在 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 定义组件模板的七种方式(一般用单文件组件更好)的更多相关文章

  1. Vue--项目开发之实现tabbar功能来学习单文件组件1

    创建好一个Vue项目后,我们进入项目里,点开src文件下的components文件里的helloworld.vue 文件.清空初始数据.然后开始编写. 一个.vue文件初始格式为以下三部分(组件三部曲 ...

  2. 黑马vue---56-58、vue组件创建的三种方式

    黑马vue---56-58.vue组件创建的三种方式 一.总结 一句话总结: 不论是哪种方式创建出来的组件,组件的 template 属性指向的模板内容,必须有且只能有唯一的一个根元素 1.使用 Vu ...

  3. Vue自定义组件以及组件通信的几种方式

    本帖子来源:小贤笔记 功能 组件 (Component) 是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素,Vue.js 的编译器为它 ...

  4. vue组件通信的几种方式

    最近用vue开发项目,记录一下vue组件间通信几种方式 第一种,父子组件通信 一.父组件向子组件传值 1.创建子组件,在src/components/文件夹下新建一个Child.vue 2.Child ...

  5. Vue单文件组件基础模板

    背景 相信大家在使用Vue开发项目时,基本都是以单文件组件的形式开发组件的,这种方式好处多多: 1.代码集中,便于开发.管理和维护 2.可复用性高,直接将vue文件拷贝到新项目中 我暂时就想到这两点, ...

  6. Vue路由传参的几种方式

    原 Vue路由传参的几种方式 2018年07月28日 23:52:40 广积粮缓称王 阅读数 12613   前言:顾名思义,vue路由传参是指嵌套路由时父路由向子路由传递参数,否则操作无效.传参方式 ...

  7. 基于VSCode的vue单文件组件模板设置---一次设置,可爽终生

    第一步: 第二步: 第三步: 打开vue.json文件后,如果是初次设置,应该如下图所示,绿色注释部分不用管,注意那两个白色大括号 第四步:在大括号内全部粘贴如下代码,保存即可完成vue模板的设置 & ...

  8. React组件导入的两种方式(动态导入组件的实现)

    一. react组件两种导入方式 React组件可以通过两种方式导入另一个组件 import(常用) import component from './component' require const ...

  9. JavaScript 创建对象的七种方式

    转自:xxxgitone.github.io/2017/06/10/JavaScript创建对象的七种方式/ JavaScript创建对象的方式有很多,通过Object构造函数或对象字面量的方式也可以 ...

随机推荐

  1. 通过access_token openid获取微信用户昵称等信息

    <?php header('Access-Control-Allow-Origin:*'); $access_token = !empty($_GET['access_token'])?$_GE ...

  2. Delphi DBGridEH中,选中行、列、单元格

    // 新增行后,默认首列 procedure TForm1.ADOQuery1AfterInsert(DataSet: TDataSet);begin  with DBGridEh1 do  begi ...

  3. window.navigator.standalone 检测iOS WebApp是否运行在全屏模式

    iOS上的Safari浏览器可以让Web应用程序全屏显示,以取得类似本地应用的显示效果.但是这需要用户把Web应用程序的图标添加到主屏幕才可以.作为开发者,为了更好的显示效果,我们可能希望自己开发的W ...

  4. BZOJ 1079 着色方案(DP)

    如果把当前格子涂什么颜色当做转移的话,状态则是每个格子的颜色数还剩多少,以及上一步用了什么颜色,这样的状态量显然是5^15.不可取. 如果把当前格子涂颜色数还剩几个的颜色作为转移的话,状态则是每个格子 ...

  5. Python虚拟环境virtualenv的使用

    virtualenv 是一个创建孤立的Python环境的工具.可以让你创建各自独立的.互不影响的Python开发环境. 使用pip安装即可 pip install virtualenv 查看是否安装成 ...

  6. Dom选择器以及内容文本操作

    1. DOM:文档对象模型.把整个HTML当做大的对象.每一个标签认为是一个对象.(每一个个体就是一个对象) 2. 查找: 直接查找 var obj=document.getElementById(& ...

  7. [HNOI2009]有趣的数列 卡特兰数

    题面:[HNOI2009]有趣的数列 题解: 观察到题目其实就是要求从长为2n的序列中选n个放在集合a,剩下的放在集合b,使得集合a和集合b中可以一一对应的使a中的元素小于b. 2种想法(实质上是一样 ...

  8. [CQOI2017]老C的方块 网络流

    ---题面--- 题解: 做这题做了好久,,,换了4种建图QAQ 首先我们观察弃疗的形状,可以发现有一个特点,那就是都以一个固定不变的特殊边为中心的,如果我们将特殊边两边的方块分别称为s块和t块, 那 ...

  9. UVA.10192 Vacation (DP LCS)

    UVA.10192 Vacation (DP LCS) 题意分析 某人要指定旅游路线,父母分别给出了一系列城市的旅游顺序,求满足父母建议的最大的城市数量是多少. 对于父母的建议分别作为2个子串,对其做 ...

  10. 阿里云遇到的坑:CentOS7防火墙(Firewalld),你关了吗?

    阿里云官方教程: https://help.aliyun.com/knowledge_detail/41317.html 百度参考的牛人教程(推荐): http://www.111cn.net/sys ...