Vue中jsx的使用

标签(空格分隔): Vue jsx


背景

目前的项目主要都是依赖在Vue框架下进行开发的,一般情况下,在Vue文件中都是使用template来进行编写代码,但是有一些需要定制配置的页面,这样写起来就特别蛋疼,比如下面的代码:

    import preview from './preview'
    const config = {
        preview: {
            name: '名称',
            preIcon: 'el-icon-view',
            dialog: {
                slot: [
                    { key: 'body', child: preview, data: {name: '预览'}},
                ]
            },
            click: () => {
                console.log('触发点击')
            }
        },
    }

上面是一个渲染 按钮 – 弹窗 的组件,点击按钮可以触发一个弹窗,dialog里面是弹窗的具体内容,其中slot是自定义渲染的内容,渲染一个自定义的插槽来满足定制化的业务场景。这种写法可以满足业务封装的需求,使得项目在一定程度上可以配置化编写,有利于后期项目的拓展和维护。但是其实我的preview功能可能仅仅是这样:

    // preview.js
    <template>
        <div>data.name</div>
    </template>
    <script>
        export default {
            props: {
                data: Object
            }
        }
    </script>

其实我仅仅需要的就是一个div标签而已,但是使用vue的template却只能新创建一个vue文件来进行引入。如果换成jsx那么我们直接就可以这样写:


const config = { preview: { name: '名称', preIcon: 'el-icon-view', dialog: { slot: [ { key: 'body', child: <div>预览</div>}, ] }, click: () => { console.log('触发点击') } }, }

这样就简单很多了,而且也不需要单独创建一个.vue文件。

引申

从上述可以看出,有些情况下vue jsx确实会带来一定的优越性(特别对于写惯了react的切图仔)。下面介绍一下写vue jsx的时候需要注意的点,以及与react的不同。

与react jsx的不同

  1. React中父子之间传递的所有数据都是属性,即所有数据均挂载在props下(style, className, children, value, onChange等等。
  2. Vue则不然,仅仅属性就有三种:组件属性props,普通html属性attrs,Dom属性domProps。

如下示例所示:

const ButtonCounter = {
  name: "button-counter",
  props: ["count"],
  methods: {
    onClick() {
      this.$emit("change", this.count + 1);
    }
  },
  render() {
    return (
      <button>You clicked me {this.count} times.</button>
    );
  }
};

export default {
  name: "button-counter-container",
  data() {
    return {
      count: 0
    };
  },
  methods: {
    onChange(val) {
      this.count = val;
    }
  },
  render() {
    const { count, onChange } = this;
    return (
      <div>


      </div>
    );
  }
};

通过上述我们可以区分出这几种属性的区别:

  1. 组件属性props:指组件声明的属性,即上述示例中声明的props: [‘count’]。

  2. 普通html属性attrs: 指组件未声明的属性,即上述示例中的type=”button”,该属性默认会直接挂载到组件根节点的上,如果不需要挂载到根节点,可声明 inheritAttrs: false。

  3. Dom属性domProps:指的Dom属性,如上述示例中的innerHTML,它会覆盖组件内部的children, 这类属性我们一般很少使用到。

抽象程度较高的动态属性

一般情况下,在已知属性和方法的时候,我们可以直接将属性值传入已经定义好的组件即可,但是如果想高度抽象来复用一些组件,那静态属性传入就不太合适了,这个时候一般使用如下方法将属性传入子组件:

    const dynamicProps = {
        props: {},
        on: {},
    }
    if(hasValue) dynamicProps.props.value = value
    if(hasChange) dynamicProps.on.change = onChange

本文关于vue jsx的介绍就到这里,如果想了解更多,建议查看官方文档。