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

學(xué)習(xí)JSX,先了解一下createElement

提到JSX,不可避免的就要提到createElement,當(dāng)你看完本節(jié),你會發(fā)現(xiàn),奇怪的知識又增多了。ok,我們接著上一部分繼續(xù)講。這一次的準(zhǔn)備工作是了解createElement。

Vue編譯后的代碼看createElement

你是否看過寫的Vue代碼經(jīng)過編譯之后的樣子,比如下面這段代碼

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

小編對這段代碼進(jìn)行編譯之后,得到下面這段代碼

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

通過對上面的代碼進(jìn)行分析,不難發(fā)現(xiàn),Vue模板中的每一個元素編譯之后都會對應(yīng)一個createElement,那么這個createElement到底是什么,嗯,這個你面試的時候也許已經(jīng)提到過了。

那么什么是createElement

無論是Vue還是React,都存在createElement,而且作用基本一致。可能你對createElement不是很了解,函數(shù)名翻譯過來就是增加一個元素,但他的返回值你一定知道。createElement函數(shù)返回的值稱之為虛擬節(jié)點,即VNode,而由VNode扎堆組成的樹便是大名鼎鼎,面試必問的虛擬DOM。

createElement函數(shù)的參數(shù),在這里小編偷個懶抄一下Vue官方文檔

// @returns {VNode}
createElement(
  // {String | Object | Function}
  // 一個 HTML 標(biāo)簽名、組件選項對象,或者
  // resolve 了上述任何一種的一個 async 函數(shù)。必填項。
  'div',

  // {Object}
  // 一個與模板中 attribute 對應(yīng)的數(shù)據(jù)對象??蛇x。
  {
    // (詳情見下一節(jié))
  },

  // {String | Array}
  // 子級虛擬節(jié)點 (VNodes),由 `createElement()` 構(gòu)建而成,
  // 也可以使用字符串來生成“文本虛擬節(jié)點”??蛇x。
  [
    '先寫一些文字',
    createElement('h1', '一則頭條'),
    createElement(MyComponent, {
      props: {
        someProp: 'foobar'
      }
    })
  ]
)

從上面可以看出createElement一共有三個參數(shù),三個參數(shù)分別是

  • 第一個參數(shù)是需要渲染的組件,可以是組件的標(biāo)簽,比如div;或者是一個組件對象,也就是你天天寫的export default {};亦或者可以是一個異步函數(shù)。
  • 第二個參數(shù)是這個組件的屬性,是一個對象,如果組件沒有參數(shù),可以傳null(關(guān)于組件的屬性,下文將依次介紹)
  • 第三個參數(shù)是這個組件的子組件,可以是一個字符串(textContent)或者一個由VNodes組成的數(shù)組

createElement寫一個組件吧

表單示例

假設(shè)我們需要開發(fā)一個下面這樣的表格(element-ui的)

img

用模板代碼去開發(fā)

如果我們用模板代碼去開發(fā)這個表單,那么代碼大概就長這樣

<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="活動區(qū)域">
    <el-select v-model="formInline.region" placeholder="活動區(qū)域">
      <el-option label="區(qū)域一" value="shanghai"></el-option>
      <el-option label="區(qū)域二" 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去實現(xiàn)

如果我們直接將上面的代碼轉(zhuǎn)換為用createElement去實現(xiàn),那么代碼將會是這樣的

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: '活動區(qū)域'
            }
          },
          [
            createElement(
              'ElSelect',
              {
                props: {
                  value: this.formInline.region,
                  placeholder: '活動區(qū)域'
                }
              },
              [
                createElement('ElOption', {
                  props: {
                    label: '區(qū)域一',
                    value: 'shanghai'
                  }
                }),
                createElement('ElOption', {
                  props: {
                    label: '區(qū)域二',
                    value: 'beijing'
                  }
                })
              ]
            )
          ]
        ),
        createElement('ElFormItem', null, [
          createElement(
            'ElButton',
            {
              props: {
                type: 'primary'
              },
              on: {
                click: this.$_handleSubmit
              }
            },
            '查詢'
          )
        ])
      ]
    )
  }
}

看到上面的代碼,你可能會驚呼,代碼好多啊,好痛苦,想當(dāng)年發(fā)明JSX的人剛開始天天也是寫createElement,寫的直掉頭發(fā),太痛苦了,然后就使勁撓頭,當(dāng)額頭锃光發(fā)亮的時候,終于想到了一種新的語法,就是JSX。從此之后,頭發(fā)呼呼的又長回來了。

看到上面代碼,你會發(fā)現(xiàn)有一個render函數(shù),這個函數(shù)叫做渲染函數(shù),相當(dāng)于通過createElementJSX去實現(xiàn)功能的主入口方法。而且你熟悉的v-model也沒見了,而是用value + input代替了。

ok,這一部分先寫到這里,下一篇文章寫下一部分:是時候使用JSX代替createElement了。喜歡的朋友可以繼續(xù)看哦,我更新非??炫?。也會一直出優(yōu)秀的文章給大家分享。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容