1. 程式人生 > >Vue 定義組件模板的七種方式(一般用單文件組件更好)

Vue 定義組件模板的七種方式(一般用單文件組件更好)

value 最有 names 標簽 checked render jsf href this

在 Vue 中定義一個組件模板,至少有七種不同的方式(或許還有其它我不知道的方式):

  • 字符串
  • 模板字面量
  • x-template
  • 內聯模板
  • render 函數
  • JSF
  • 單文件組件

在這篇文章中,我將通過示例介紹每個選項,並探討利弊。以便你知道在任何特定情況下最適合的是哪一種。

1. 字符串

默認情況下,模板會被定義為一個字符串。我想我們的觀點會達成一致:字符串中的模板是非常難以理解的。除了廣泛的瀏覽器支持之外,這種方法沒有太多用處。

Vue.component(‘my-checkbox‘, {
    template: `<div class="checkbox-wrapper" @click="check"><div :class="{ checkbox: true, checked: checked }"></div><div class="title"></div></div>`,
    data() {
        return { checked: false, title: ‘Check me‘ }
    },
    methods: {
        check() { this.checked = !this.checked; }
    }
});

2. 模板字面量

ES6 模板字面量允許你使用多行定義模板,這在常規 JavaScript 字符串中是不被允許的。此方式閱讀體驗更佳,並在許多現代瀏覽器中得到支持,不過安全起見你還是需要把代碼轉換成 ES5 。
這種方法並不完美,我發現大多數 IDE 仍然會通過語法高亮、tab 格式化、換行符等地方的問題折磨著你。

Vue.component(‘my-checkbox‘, {
    template: `<div class="checkbox-wrapper" @click="check">
                            <div :class="{ checkbox: true, checked: checked }"></div>
                            <div class="title"></div>
                        </div>`,
    data() {
        return { checked: false, title: ‘Check me‘ }
    },
    methods: {
        check() { this.checked = !this.checked; }
    }
});

3. x-template

使用此方法,你的模板被定義在例如 index.html 文件中的 script 標簽裏。此 script 標簽使用 text/x-template 標記,並由組件定義的 id 引用。
我喜歡這種方法,它允許你使用適當的 HTML 標記編寫你的 HTML,不過不好的一面是,它把模板和組件定義的其它部分分離開來。

Vue.component(‘my-checkbox‘, {
    template: ‘#checkbox-template‘,
    data() {
        return { checked: false, title: ‘Check me‘ }
    },
    methods: {
        check() { this.checked = !this.checked; }
    }
});
<script type="text/x-template" id="checkbox-template">
    <div class="checkbox-wrapper" @click="check">
        <div :class="{ checkbox: true, checked: checked }"></div>
        <div class="title"></div>
    </div>
</script>

4. 內聯模板

通過在組件中添加 inline-template 屬性,你可以向 Vue 指示內部內容是其模板,而不是將其視為分布式內容(參考 slot 。
它與 x-templates 具有相同的缺點,不過一個優點是,內容在 HTML 模板的正確位置,因此可以在頁面加載時呈現,而不是等到 JavaScript 運行。

Vue.component(‘my-checkbox‘, {
    data() {
        return { checked: false, title: ‘Check me‘ }
    },
    methods: {
        check() { this.checked = !this.checked; }
    }
});
<my-checkbox inline-template>
    <div class="checkbox-wrapper" @click="check">
        <div :class="{ checkbox: true, checked: checked }"></div>
        <div class="title"></div>
    </div>
</my-checkbox>

5. render 函數

render 函數需要你將模板定義為 JavaScript 對象,這顯然是最詳細和抽象的模板選項。
不過,優點是你的模板更接近編譯器,並允許你使用完整的 JavaScript 功能,而不是指令提供的子集。

Vue.component(‘my-checkbox‘, {
    data() {
        return { checked: false, title: ‘Check me‘ }
    },
    methods: {
        check() { this.checked = !this.checked; }
    },
    render(createElement) {
        return createElement(
            ‘div‘,
            {
                    attrs: {
                        ‘class‘: ‘checkbox-wrapper‘
                    },
                    on: {
                        click: this.check
                    }
            },
            [
                createElement(
                ‘div‘,
                {
                    ‘class‘: {
                        checkbox: true,
                        checked: this.checked
                    }
                }
                ),
                createElement(
                ‘div‘,
                {
                    attrs: {
                    ‘class‘: ‘title‘
                    }
                },
                [ this.title ]
                )
            ]
        );
    }
});

6. JSX

Vue 中最有爭議的模板選項是 JSX,一些開發者認為它醜陋、不直觀,是對 Vue 精神的背叛。JSX 需要你先編譯,因為它不能被瀏覽器運行。
不過,如果你需要完整的 JavaScript 語言功能,又不太適應 render 函數過於抽象的寫法,那麽 JSX 是一種折衷的方式。

Vue.component(‘my-checkbox‘, {
    data() {
        return { checked: false, title: ‘Check me‘ }
    },
    methods: {
        check() { this.checked = !this.checked; }
    },
    render() {
        return <div class="checkbox-wrapper" onClick={ this.check }>
                 <div class={{ checkbox: true, checked: this.checked }}></div>
                 <div class="title">{ this.title }</div>
               </div>
    }
});

單文件組件

只要你把構建工具設置的很舒服,單文件組件就是模板選項中的王者。它允許你寫 HTML 標簽定義組件,並且將所有組件定義保留在一個文件中。
盡管它也有一些劣勢:需要預編譯,某些 IDE 不支持 .vue 文件的語法高亮,不過其地位依然難以被撼動。

<template>
  <div class="checkbox-wrapper" @click="check">
    <div :class="{ checkbox: true, checked: checked }"></div>
    <div class="title"></div>
  </div>
</template>
<script>
  export default {
    data() {
      return { checked: false, title: ‘Check me‘ }
    },
    methods: {
      check() { this.checked = !this.checked; }
    }
  }
</script>

你還可以通過引入 pug 之類的預處理器,來獲得模板定義的更多可能性。

Vue 定義組件模板的七種方式(一般用單文件組件更好)