首页 > web前端 > js教程 > 正文

Vue.js每天必学之组件与组件间的通信

高洛峰
发布: 2017-01-03 17:26:19
原创
1138 人浏览过

什么是组件?

组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。

使用组件

注册

之前说过,我们可以用 Vue.extend() 创建一个组件构造器:

var MyComponent = Vue.extend({
 // 选项...
})
登录后复制

要把这个构造器用作组件,需要用 `Vue.component(tag, constructor)` **注册** :

// 全局注册组件,tag 为 my-component
Vue.component('my-component', MyComponent)
登录后复制

对于自定义标签名字,Vue.js 不强制要求遵循 W3C 规则(小写,并且包含一个短杠),尽管遵循这个规则比较好。

组件在注册之后,便可以在父实例的模块中以自定义元素 的形式使用。要确保在初始化根实例之前注册了组件:

<div id="example">
 <my-component></my-component>
</div>
 
// 定义
var MyComponent = Vue.extend({
 template: &#39;<div>A custom component!</div>&#39;
})
 
// 注册
Vue.component(&#39;my-component&#39;, MyComponent)
 
// 创建根实例
new Vue({
 el: &#39;#example&#39;
})
登录后复制

渲染为:

<div id="example">
 <div>A custom component!</div>
</div>
登录后复制

注意组件的模板替换了自定义元素,自定义元素的作用只是作为一个挂载点。可以用实例选项 replace 决定是否替换。

局部注册

不需要全局注册每个组件。可以让组件只能用在其它组件内,用实例选项 components 注册:

var Child = Vue.extend({ /* ... */ })
 
var Parent = Vue.extend({
 template: &#39;...&#39;,
 components: {
 // <my-component> 只能用在父组件模板内
 &#39;my-component&#39;: Child
 }
})
登录后复制

这种封装也适用于其它资源,如指令、过滤器和过渡。

注册语法糖

为了让事件更简单,可以直接传入选项对象而不是构造器给 Vue.component() 和 component 选项。Vue.js 在背后自动调用 Vue.extend():

// 在一个步骤中扩展与注册
Vue.component(&#39;my-component&#39;, {
 template: &#39;<div>A custom component!</div>&#39;
})
 
// 局部注册也可以这么做
var Parent = Vue.extend({
 components: {
 &#39;my-component&#39;: {
  template: &#39;<div>A custom component!</div>&#39;
 }
 }
})
登录后复制

组件选项问题

传入 Vue 构造器的多数选项也可以用在 Vue.extend() 中,不过有两个特例: data 和 el。试想如果我们简单地把一个对象作为 data 选项传给 Vue.extend():

var data = { a: 1 }
var MyComponent = Vue.extend({
 data: data
})
登录后复制

这么做的问题是 `MyComponent` 所有的实例将共享同一个 `data` 对象!这基本不是我们想要的,因此我们应当使用一个函数作为 `data` 选项,让这个函数返回一个新对象:

var MyComponent = Vue.extend({
 data: function () {
 return { a: 1 }
 }
})
登录后复制

同理,`el` 选项用在 `Vue.extend()` 中时也须是一个函数。

模板解析

Vue 的模板是 DOM 模板,使用浏览器原生的解析器而不是自己实现一个。相比字符串模板,DOM 模板有一些好处,但是也有问题,它必须是有效的 HTML 片段。一些 HTML 元素对什么元素可以放在它里面有限制。常见的限制:
•a 不能包含其它的交互元素(如按钮,链接)
•ul 和 ol 只能直接包含 li
•select 只能包含 option 和 optgroup
•table 只能直接包含 thead, tbody, tfoot, tr, caption, col, colgroup
•tr 只能直接包含 th 和 td

在实际中,这些限制会导致意外的结果。尽管在简单的情况下它可能可以工作,但是你不能依赖自定义组件在浏览器验证之前的展开结果。例如 不是有效的模板,即使 my-select 组件最终展开为

另一个结果是,自定义标签(包括自定义元素和特殊标签,如