美文网首页
Vue.js 定义组件模板的 7 种方式

Vue.js 定义组件模板的 7 种方式

作者: IT修真院 | 来源:发表于2020-05-13 19:47 被阅读0次

    作者简介:
    李中凯
    八年多工作经验 前端负责人,
    擅长JavaScript/Vue。
    掘金文章专栏:https://juejin.im/user/57c7cb8a0a2b58006b1b8666/posts
    公众号:1024译站

    定义 Vue.js 组件模板有多种方式,据我所知,至少有7种不同的方法。
    本文将逐一介绍每种方法的示例,并讨论其优缺点,以便你了解在特定情况下使用哪种方法最好。

    普通字符串
    定义 Vue 组件模板最快也是最容易的方式就是给组件定义加上一个 template 属性,它的值就是包含 HTML 标签的普通字符串。

    但是,这种方法实际上只在代码示例或快速原型中使用,因为模板过于简单,不太实用。
    app.js

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

    模板字符串
    从 ES2015 开始,可以用反引号定义一种特殊的字符串,叫做模板字面量。跟普通字符串不用,它可以内嵌表达式,并支持多行。

    支持多行的特性让它在定义组件模板时比普通字符串方便多了,因为可以让多行标签可读性更好。
    app.js

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

    较老的浏览器可能不支持 ES2015 特性,因此需要用 Babel 转换代码。

    x-template
    这种方式是将模板定义在 HTML 文件里的 script 标签里。script 标签需要指定type="text/x-template ",并通过 id 属性在组件里引用。

    好处是可以在 HTML 文件里写模板标记,非常直观。坏处就是模板和组件的其他部分分离了,查找起来不太方便。
    app.js

    Vue.component('my-checkbox', {
    template: '#checkbox-template',
    data() {
    return { checked: false, title: 'Check me' }
    },
    methods: {
    check() { this.checked = !this.checked; }
    }
    });

    index.html

    <div id="app">...</div>
    <script type="text/x-template" id="checkbox-template">
    <div class="checkbox-wrapper" @click="check">
    <div :class="{ checkbox: true, checked: checked }"></div>
    <div class="title">{{ title }}</div>
    </div>
    </script>

    inline template
    用这个方法可以在父模板中定义组件的模板。需要给标签加上inline-template 属性,以便让 Vue 知道在哪找到它。

    这个方法跟 x-template 的优缺点差不多,不过有一点区别,由于模板是定义在文档 body 里的,因此它的内容可以被爬虫识别,有利于 SEO。
    app.js

    Vue.component('my-checkbox', {
    data() {
    return { checked: false, title: 'Check me' }
    },
    methods: {
    check() { this.checked = !this.checked; }
    }
    });

    index.html

    <div id="app">
    ...
    <my-checkbox inline-template>
    <div class="checkbox-wrapper" @click="check">
    <div :class="{ checkbox: true, checked: checked }"></div>
    <div class="title">{{ title }}</div>
    </div>
    </my-checkbox>
    </div>

    inline templates 和 x-template 可以与后端框架(例如Laravel Blade)中的模板引擎结合使用。

    render 函数
    render 函数要求你用纯 JavaScript 定义模板。具体语法可以参考 Vue 文档 ,大体就是通过调用 createElement(tag, options, childElements)创建模板节点。

    这样做的好处是,它不需要编译,并且你可以完全利用 JavaScript 的能力,而不是局限于指令提供的功能。例如,模板里的循环只能通过v-for,但在 JavaScript 里你可以用任何数组方法。

    但是,与其他模板选项相比,render 函数更加冗长和抽象,我估计没人愿意用这种方法写完整个应用。
    app.js

    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]
    )
    ]
    );
    }
    });

    JSX
    JSX 是 JavaScript 的一个扩展,它可以在 JavaScript 代码里使用特殊的模板语法。

    JSX 本来是 React 的一个特性,在 Vue 的模板中使用它一直备受争议,因为一些开发人员认为它丑陋、不直观,跟 Vue 的气质不符。

    但是,用 JSX 写 Vue render 函数,可读性高得多,也没那么抽象。不过它需要编译,因为浏览器可不认识 JSX。
    app.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>
    }
    });

    单文件组件
    Vue.js 最受欢迎的特性之一就是 单文件组件(SFC)。它可以将模板和组件定义全部放在一个文件里。里面的模板会被 vue-loader 编译成 render 函数,因此也可以获得最佳的运行时性能。

    单文件组件是一个.vue文件,比如Checkbox.vue,在 template 标签中定义模板, script 标签中定义组件属性和逻辑。然后就可以在应用中导入使用了。

    只要你习惯使用 Vue CLI 或者其他构建工具,单文件组件是个不错的选择。
    Checkbox.vue

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

    谁是王者
    吧啦这么多,到底哪种方法最好?本文的答案是:单文件组件,因为它是几乎所有场景中最通用、最强大的选择。

    实际上,以上每一种方法在特定的场景中都有优势,应该根据你的实际情况进行判断。熟悉每一种用法,说不定哪天就用上了呢!

    作者简介:
    李中凯
    八年多工作经验 前端负责人,
    擅长JavaScript/Vue。
    掘金文章专栏:https://juejin.im/user/57c7cb8a0a2b58006b1b8666/posts
    公众号:1024译站

    本文已经获得李中凯老师授权转发,其他人若有兴趣转载,请直接联系作者授权。

    相关文章

      网友评论

          本文标题:Vue.js 定义组件模板的 7 种方式

          本文链接:https://www.haomeiwen.com/subject/zemonhtx.html