摘要:僅對于組件,用于監聽原生事件,而不是組件內部使用觸發的事件。注意,你無法對中的賦值,因為已經自動為你進行了同步。
簡介
在使用Vue進行開發的時候,大多數情況下都是使用template進行開發,使用template簡單、方便、快捷,可是有時候需要特殊的場景使用template就不是很適合。因此為了很好使用render函數,我決定深入窺探一下。各位看官如果覺得下面寫的有不正確之處還望看官指出,你們與我的互動就是寫作的最大動力。
場景官網描述的場景當我們開始寫一個通過 level prop 動態生成 heading 標簽的組件,你可能很快想到這樣實現:
Vue.component("anchored-heading", { template: "#anchored-heading-template", props: { level: { type: Number, required: true } } })
在這種場景中使用 template 并不是最好的選擇:首先代碼冗長,為了在不同級別的標題中插入錨點元素,我們需要重復地使用
雖然模板在大多數組件中都非常好用,但是在這里它就不是很簡潔的了。那么,我們來嘗試使用 render 函數重寫上面的例子:
Vue.component("anchored-heading", { render: function (createElement) { return createElement( "h" + this.level, // tag name 標簽名稱 this.$slots.default // 子組件中的陣列 ) }, props: { level: { type: Number, required: true } } })
簡單清晰很多!簡單來說,這樣代碼精簡很多,但是需要非常熟悉 Vue 的實例屬性。在這個例子中,你需要知道當你不使用 slot 屬性向組件中傳遞內容時,比如 anchored-heading 中的 Hello world!,這些子元素被存儲在組件實例中的 $slots.default中。
createElement參數介紹接下來你需要熟悉的是如何在 createElement 函數中生成模板。這里是 createElement 接受的參數:
createElement( // {String | Object | Function} // 一個 HTML 標簽字符串,組件選項對象,或者 // 解析上述任何一種的一個 async 異步函數,必要參數。 "div", // {Object} // 一個包含模板相關屬性的數據對象 // 這樣,您可以在 template 中使用這些屬性??蛇x參數。 { // (詳情見下一節) }, // {String | Array} // 子節點 (VNodes),由 `createElement()` 構建而成, // 或使用字符串來生成“文本節點”??蛇x參數。 [ "先寫一些文字", createElement("h1", "一則頭條"), createElement(MyComponent, { props: { someProp: "foobar" } }) ] )深入 data 對象
有一件事要注意:正如在模板語法中,v-bind:class 和 v-bind:style ,會被特別對待一樣,在 VNode 數據對象中,下列屬性名是級別最高的字段。該對象也允許你綁定普通的 HTML 特性,就像 DOM 屬性一樣,比如 innerHTML (這會取代 v-html 指令)。
{ // 和`v-bind:class`一樣的 API "class": { foo: true, bar: false }, // 和`v-bind:style`一樣的 API style: { color: "red", fontSize: "14px" }, // 正常的 HTML 特性 attrs: { id: "foo" }, // 組件 props props: { myProp: "bar" }, // DOM 屬性 domProps: { innerHTML: "baz" }, // 事件監聽器基于 `on` // 所以不再支持如 `v-on:keyup.enter` 修飾器 // 需要手動匹配 keyCode。 on: { click: this.clickHandler }, // 僅對于組件,用于監聽原生事件,而不是組件內部使用 // `vm.$emit` 觸發的事件。 nativeOn: { click: this.nativeClickHandler }, // 自定義指令。注意,你無法對 `binding` 中的 `oldValue` // 賦值,因為 Vue 已經自動為你進行了同步。 directives: [ { name: "my-custom-directive", value: "2", expression: "1 + 1", arg: "foo", modifiers: { bar: true } } ], // Scoped slots in the form of // { name: props => VNode | Array條件渲染} scopedSlots: { default: props => createElement("span", props.text) }, // 如果組件是其他組件的子組件,需為插槽指定名稱 slot: "name-of-slot", // 其他特殊頂層屬性 key: "myKey", ref: "myRef" }
既然熟讀以上api接下來咱們就來點實戰。
之前這樣寫
//HTML我被你發現啦!!!//js //組件形式 Vue.component("vv-isshow", { props:["show"], template:" 我被你發現啦2!?。?/div>", }); var vm = new Vue({ el: "#app", data: { isShow:true } });render這樣寫
//HTML列表渲染//js //組件形式 Vue.component("vv-isshow", { props:{ show:{ type: Boolean, default: true } }, render:function(h){ if(this.show ) return h("div",this.$slots.default); }, }); var vm = new Vue({ el: "#app", data: { isShow:true } });我被你發現啦3!?。?/slot> 之前是這樣寫的,而且v-for 時template內必須被一個標簽包裹
//HTML//js //組件形式 Vue.component("vv-aside", { props:["list"], methods:{ handelClick(item){ console.log(item); } }, template:" ", //template:"{{item.txt}}{{item.txt}}",錯誤 }); var vm = new Vue({ el: "#app", data: { list: [{ id: 1, txt: "javaScript", odd: true }, { id: 2, txt: "Vue", odd: false }, { id: 3, txt: "React", odd: true }] } });render這樣寫
//HTMLv-model//js //側邊欄 Vue.component("vv-aside", { render: function(h) { var _this = this, ayy = this.list.map((v) => { return h("div", { "class": { odd: v.odd }, attrs: { title: v.txt }, on: { click: function() { return _this.handelClick(v); } } }, v.txt); }); return h("div", ayy); }, props: { list: { type: Array, default: () => { return this.list || []; } } }, methods: { handelClick: function(item) { console.log(item, "item"); } } }); var vm = new Vue({ el: "#app", data: { list: [{ id: 1, txt: "javaScript", odd: true }, { id: 2, txt: "Vue", odd: false }, { id: 3, txt: "React", odd: true }] } });之前的寫法
//HTML//js //input Vue.component("vv-models", { props: ["txt"], template: " ", computed: { txtcout:{ get(){ return this.txt; }, set(val){ this.$emit("input", val); } } } }); var vm = new Vue({ el: "#app", data: { txt: "", } });看官你輸入的是:{{txtcout}}
render這樣寫
//HTML總結//js //input Vue.component("vv-models", { props: { txt: { type: String, default: "" } }, render: function(h) { var self=this; return h("div",[h("p","你猜我輸入的是啥:"+this.txt),h("input",{ on:{ input(event){ self.$emit("input", event.target.value); } } })] ); }, }); var vm = new Vue({ el: "#app", data: { txt: "", } });render函數使用的是JavaScript 的完全編程的能力,在性能上是占用絕對的優勢,小編只是對它進行剖析。至于實際項目你選擇那種方式進行渲染依舊需要根據你的項目以及實際情況而定。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/94195.html
摘要:前端日報精選浮點數精度之謎前端面試必備基本排序算法從賀老微博引出的遍歷器加速那些奧秘進階之深入理解數據雙向綁定全棧天中文深入理解筆記用模塊封裝代碼前端架構經驗分享周二放送自制知乎專欄譯在大型應用中使用的五個技巧掘金開發指南眾成 2017-08-02 前端日報 精選 JavaScript 浮點數精度之謎前端面試必備——基本排序算法從賀老微博引出的遍歷器(Iterators)加速那些奧秘J...
摘要:所謂知其然還要知其所以然本文將分析的部分源碼包括組件初始渲染的過程和組件更新的過程在這之前假設讀者已經對有一定了解知道區別了解生命周期事務批量更新大致概念等如何分析源碼代碼架構預覽首先我們找到在上的地址把版本的源碼下來觀察它的整體架構這 所謂知其然還要知其所以然. 本文將分析 React 15-stable的部分源碼, 包括組件初始渲染的過程和組件更新的過程.在這之前, 假設讀者已經:...
摘要:數據驅動一個核心思想是數據驅動。發生了什么從入口代碼開始分析,我們先來分析背后發生了哪些事情。函數最后判斷為根節點的時候設置為,表示這個實例已經掛載了,同時執行鉤子函數。這里注意表示實例的父虛擬,所以它為則表示當前是根的實例。 數據驅動 Vue.js 一個核心思想是數據驅動。所謂數據驅動,是指視圖是由數據驅動生成的,我們對視圖的修改,不會直接操作 DOM,而是通過修改數據。它相比我們傳...
閱讀 925·2021-11-24 09:38
閱讀 939·2021-11-23 09:51
閱讀 2947·2021-11-16 11:44
閱讀 1775·2021-09-22 15:52
閱讀 1683·2021-09-10 11:20
閱讀 1410·2019-08-30 13:47
閱讀 1304·2019-08-29 12:36
閱讀 3338·2019-08-26 10:43