天天看点

【Vue 开发实战】基础篇 # 14:template和JSX的对比以及它们的本质

说明

【Vue 开发实战】学习笔记。

template

  • 模板语法(HTML的扩展)
  • 数据绑定使用Mustache语法(双大括号)
【Vue 开发实战】基础篇 # 14:template和JSX的对比以及它们的本质

JSX

  • JavaScript的语法扩展
  • 数据绑定使用单引号
【Vue 开发实战】基础篇 # 14:template和JSX的对比以及它们的本质

template vs JSX

【Vue 开发实战】基础篇 # 14:template和JSX的对比以及它们的本质

更抽象一点来看 ,我们可以把组件区分为两类:一类是偏视图表现的(presentational) , 一类则是偏逻辑的(logical)。 我们推荐在前者中使用模

板,在后者中使用JSX或渲染函数。这两类组件的比例会根据应用类型的不同有所变化,但整体来说我们发现表现类的组件远远多于逻辑类组件。

语法糖

template、JSX都是语法糖而已,最终编译的都是一样

【Vue 开发实战】基础篇 # 14:template和JSX的对比以及它们的本质

例子:template、JSX、js、函数式组件的写法

​index.vue​

​ 组件

<template>
  <div>
    <span>Message: {{ msg }}</span>
    <br />
    <VNodes :vnodes="getJSXSpan()" />
    <anchored-heading1 :level="1">Hello world!</anchored-heading1>
    <anchored-heading2 :level="2">Hello world!</anchored-heading2>
    <anchored-heading3 :level="3">Hello world!</anchored-heading3>
    <VNodes :vnodes="getAnchoredHeading(4)" />
  </div>
</template>
<script>import AnchoredHeading1 from "./AnchoredHeading.vue";
import AnchoredHeading2 from "./AnchoredHeading.js";
import AnchoredHeading3 from "./AnchoredHeading.jsx";

export default {
  components: {
    AnchoredHeading1,
    AnchoredHeading2,
    AnchoredHeading3,
    VNodes: {
      functional: true,
      render: (h,) => ctx.props.vnodes
    }
  },
  data() {
    return {
      msg: "hello vue"
    };
  },
  methods: {
    getJSXSpan() {
      return <span>Message: {this.msg}</span>;
    },
    getAnchoredHeading(level) {
      const Tag = `h${level}`;
      return <Tag>Hello world!</Tag>;
    }
  }
};</script>      

​AnchoredHeading.vue​

<template>
  <h1 v-if="level === 1">
    <slot></slot>
  </h1>
  <h2 v-else-if="level === 2">
    <slot></slot>
  </h2>
  <h3 v-else-if="level === 3">
    <slot></slot>
  </h3>
  <h4 v-else-if="level === 4">
    <slot></slot>
  </h4>
  <h5 v-else-if="level === 5">
    <slot></slot>
  </h5>
  <h6 v-else-if="level === 6">
    <slot></slot>
  </h6>
</template>
<script>export default {
  props: {
    level: {
      type: Number,
      default: 1
    }
  }
};</script>      

​AnchoredHeading.js​

export default {
  props: {
    level: {
      type: Number,
      default: 1
    }
  },
  render: function(createElement) {
    return createElement(
      "h" + this.level, // 标签名称
      this.$slots.default // 子元素数组
    );
  }
};      

​AnchoredHeading.jsx​

export default {
  props: {
    level: {
      type: Number,
      default: 1
    }
  },
  render: function(h) {
    const Tag = `h${this.level}`;
    return <Tag>{this.$slots.default}</Tag>;
  }
};      

继续阅读