vue的jsx寫法記錄

[toc]
由於vue的createElement跟react的createElement有區別,導致jsx的寫法也有區別.本文將記錄一些vue中比較特殊的jsx的寫法.可以參考官方說明

v-model的寫法

官網中v-model寫法不可行,需要爲:

 <el-input v-model="inputValue"/> 
 //   
 <el-input vModel_trim={inputValue}/>
   //或者使用
   <el-input 
    value={this.inputValue} 
    on-input={val => this.inputValue = val}/>

v-for

    <el-tag
        v-for="(item, index) in content"
        :key="index"
        type="success"
    >
    {{item.name}}
    </el-tag>
    
    // 
    
    {
        this.content.map((item, index) => {
            return (
                <el-tag
                    key={index}
                    type="success"
                >
                {item.name}
                </el-tag>
            )
        })
    }

事件 & 按鍵修飾符

官方的寫法

<input vOn:click_stop_prevent="newTodoText" />

一些編輯會提示語法錯誤,
推薦可以使用下面的寫法

    <el-input
            @keyup.native.enter="fetch()"
            @click="click()"
            class="width-20"
            prefix-icon="el-icon-search"
            placeholder="關鍵字搜索"
          />

    // 或者爲:  
    <el-input
            class="width-20"
            nativeOn-keyup={arg => arg.keyCode === 13 && this.fetch()}
            on-click={_ => {this.click()} }
            prefix-icon="el-icon-search"
            placeholder="關鍵字搜索"
          />

需要注意的是,不要使用on-click={this.click() }這樣寫,會報錯.解決方案是:
on-click={this.click.bind(this, args) },不過建議的寫法是on-click={() => {this.click(args)} },就不需要寫bind(this)了.

data寫法

jsx其實是createElement的語法糖.jsx語法最終會轉爲createElement函數.當在jsx的標籤中使用{ ...obj }時,obj將會編譯爲createElement的中間參數.

需要注意的是,vue的createElement跟react的createElement函數中間的參數是的意義是一樣的.在vue中,中間的參數是data對象
,而react中,中間參數是props.

所以如果vue中需要向react中一樣設置動態屬性時,需要:

const props={
    name: 'joyer',
},
// react中
<my-button {...props}></my-button>
// vue中
<my-button {...{
    props: props,
}}></my-button>

當你不知道一個在template中的屬性怎麼在jsx中使用時,可以先轉換爲createElementdata對象寫法,然後使用{...data}寫在jsx標籤上.

如高級組件中使用了v-on="$listeners"或者v-bind="$attrs"代理時,在官網並沒有說明.官網有對v-on="$listeners"v-bind="$attrs"的說明,當使用createElement函數創建時,在第二個參數中可以這樣寫:

return createElement('div', {
    props: {
        ...$attrs,
        otherProp: value,
    },
    on: {
        ...$listeners,
        click() {
        },
    }
},this.$slots.default])

在jsx中,也可以使用data,語法爲{...data}:

// 官網推薦寫法
<button domPropsType="submit"><button>
// data方式寫法
<button { ...{
  domProps: {
    type: 'submit',
  }, 
}}><button>

所以當你不知道jsx中元素上面的屬性怎麼寫時,可以全部寫入一個data對象中,然後用...data放在元素上.

const data = {
  domProps: {
    type: 'submit',
  }, 
  scopedSlots: {
    default: props => createElement('span', props.text)
  },
    props: {
        ...$attrs,
        otherProp: value,
    },
    on: {
        ...$listeners,
        click() {
        },
    }
}
<button { ...data }><button>

這樣就解決了v-on="$listeners"或者v-bind="$attrs".

需要注意的是,如果使用{...data}的高級組件的中,在{...data}所在標籤的組件也是一個使用v-bind="$attrs"或者{...data}的組件,還需要在當前組件中設置attrs:
cd-table-column-id的源碼:

<cd-table-column { ...{
        props: this.$attrs,
        attrs: this.$attrs,
        on: this.$listeners,
        scopedSlots,
      } } bold>
</cd-table-column>

cd-table-column的源碼:

<el-table-column { ...{
    props: columnAttrs,
    on: columnListeners,
    scopedSlots,
    } }>
</el-table-column>

這是因爲cd-table-column裏面也是使用了{...data}寫法,其組件的props爲空,所以設置props是無效的,需要添加一個attrs,通過attrs繼承機制將cd-table-column-idthis.$attrs傳遞給cd-table-columnthis.$attrs.

slot寫法

默認

    <button>
        <slot></slot>
      </button>
     //
      <button>
        {this.$scopedSlots.default()}
      </button>

具名slot:

    <button>
        <slot name="before"></slot>
        <slot ></slot>
      </button>
// 
let before = '';
    if (this.$scopedSlots.before) {
      before = this.$scopedSlots.before(props => props.text);
    }
    return (
      <button>
        { before }
        {this.$scopedSlots.default()}
      </button>

作用域slot:

    <slot :isAdvancedPanelShow="isAdvancedPanelShow"></slot>
    
    // 
    
    {this.$scopedSlots.default({
       isAdvancedPanelShow: this.isAdvancedPanelShow
    })}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章