天天看點

【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>;
  }
};      

繼續閱讀