vue jsx写法记录

由于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
    })}

猜你喜欢

转载自www.cnblogs.com/joyer-li/p/11510791.html