學Vue,就要學會vue JSX(二)

學習JSX,先了解一下createElement

提到JSX,不可避免的就要提到createElement,當你看完本節,你會發現,奇怪的知識又增多了。ok,咱們接着上一部分繼續講。這一次的準備工做是瞭解createElement。前端

Vue編譯後的代碼看createElement

你是否看過寫的Vue代碼通過編譯以後的樣子,好比下面這段代碼面試

 <template>
   <div>我喜歡<span class="emphasize">前端</span></div>
 </template>

小編對這段代碼進行編譯以後,獲得下面這段代碼element-ui

 function () {
   var e = this,
   // e._self._c 對應源碼裏面的createElement
   t = e._self._c;
   // 返回了一個 createElement('div',[])
   return t("div", [
     // e._v 對應源碼裏面的createTextVNode
     e._v("my"),
     t("span", { staticClass: "emphasize" }, [e._v("前端")]),
   ]);
 }

 

經過對上面的代碼進行分析,不難發現,Vue模板中的每個元素編譯以後都會對應一個createElement,那麼這個createElement究竟是什麼,嗯,這個你面試的時候也許已經提到過了。數組

那麼什麼是createElement

不管是Vue仍是React,都存在createElement,並且做用基本一致。可能你對createElement不是很瞭解,函數名翻譯過來就是增長一個元素,但他的返回值你必定知道。createElement函數返回的值稱之爲虛擬節點,即VNode,而由VNode扎堆組成的樹即是大名鼎鼎,面試必問的虛擬DOM異步

createElement函數的參數,在這裏小編偷個懶抄一下Vue官方文檔async

 // @returns {VNode}
 createElement(
   // {String | Object | Function}
   // 一個 HTML 標籤名、組件選項對象,或者
   // resolve 了上述任何一種的一個 async 函數。必填項。
   'div',
 ​
   // {Object}
   // 一個與模板中 attribute 對應的數據對象。可選。
   {
     // (詳情見下一節)
   },
 ​
   // {String | Array}
   // 子級虛擬節點 (VNodes),由 `createElement()` 構建而成,
   // 也可使用字符串來生成「文本虛擬節點」。可選。
   [
     '先寫一些文字',
     createElement('h1', '一則頭條'),
     createElement(MyComponent, {
       props: {
         someProp: 'foobar'
       }
     })
   ]
 )

 

從上面能夠看出createElement一共有三個參數,三個參數分別是函數

  • 第一個參數是須要渲染的組件,能夠是組件的標籤,好比div;或者是一個組件對象,也就是你每天寫的export default {};亦或者能夠是一個異步函數。學習

  • 第二個參數是這個組件的屬性,是一個對象,若是組件沒有參數,能夠傳null(關於組件的屬性,下文將依次介紹)ui

  • 第三個參數是這個組件的子組件,能夠是一個字符串(textContent)或者一個由VNodes組成的數組this

createElement寫一個組件吧

表單示例

假設咱們須要開發一個下面這樣的表格(element-ui的)

img

用模板代碼去開發

若是咱們用模板代碼去開發這個表單,那麼代碼大概就長這樣

 <el-form :inline="true" :model="formInline" class="demo-form-inline">
   <el-form-item label="審批人">
     <el-input v-model="formInline.user" placeholder="審批人"></el-input>
   </el-form-item>
   <el-form-item label="活動區域">
     <el-select v-model="formInline.region" placeholder="活動區域">
       <el-option label="區域一" value="shanghai"></el-option>
       <el-option label="區域二" value="beijing"></el-option>
     </el-select>
   </el-form-item>
   <el-form-item>
     <el-button type="primary" @click="onSubmit">查詢</el-button>
   </el-form-item>
 </el-form>

 

createElement去實現

若是咱們直接將上面的代碼轉換爲用createElement去實現,那麼代碼將會是這樣的

 export default {
  methods: {
     $_handleChangeUser(value) {
       this.formInline.user = value
     }
   },
   render(createElement) {
     return createElement(
       'ElForm',
       {
         props: {
           inline: true,
           model: this.formInline
         },
         staticClass: 'demo-form-inline'
       },
       [
         createElement(
           'ElFormItem',
           {
             props: {
               label: '審批人'
             }
           },
           [
             createElement('ElInput', {
               props: {
                 value: this.formInline.user
               },
               attrs: {
                 placeholder: '審批人'
               },
               on: {
                 input: this.$_handleChangeUser
               }
             })
           ]
         ),
         createElement(
           'ElFormItem',
           {
             props: {
               label: '活動區域'
             }
           },
           [
             createElement(
               'ElSelect',
               {
                 props: {
                   value: this.formInline.region,
                   placeholder: '活動區域'
                 }
               },
               [
                 createElement('ElOption', {
                   props: {
                     label: '區域一',
                     value: 'shanghai'
                   }
                 }),
                 createElement('ElOption', {
                   props: {
                     label: '區域二',
                     value: 'beijing'
                   }
                 })
               ]
             )
           ]
         ),
         createElement('ElFormItem', null, [
           createElement(
             'ElButton',
             {
               props: {
                 type: 'primary'
               },
               on: {
                 click: this.$_handleSubmit
               }
             },
             '查詢'
           )
         ])
       ]
     )
   }
 }

 

看到上面的代碼,你可能會驚呼,代碼好多啊,好痛苦,想當年發明JSX的人剛開始每天也是寫createElement,寫的直掉頭髮,太痛苦了,而後就使勁撓頭,當額頭鋥光發亮的時候,終於想到了一種新的語法,就是JSX。今後以後,頭髮呼呼的又長回來了。

看到上面代碼,你會發現有一個render函數,這個函數叫作渲染函數,至關於經過createElementJSX去實現功能的主入口方法。並且你熟悉的v-model也沒見了,而是用value + input代替了。

ok,這一部分先寫到這裏,下一篇文章寫下一部分:是時候使用JSX代替createElement了。喜歡的朋友能夠繼續看哦,我更新很是快哦。也會一直出優秀的文章給你們分享。

相關文章
相關標籤/搜索