组件(Component)是 Vue.js 最强大的功能之一。组件能够扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。html
使用:vue
使用Vue.extend()建立一个构造器api
var userdefined = Vue.extend({ ... })
数组
建立好元素以后,开始注册元素,让你定义的元素可使用。浏览器
这里使用Vue.component去注册组件app
// 全局注册组件,tag 为 my-component
Vue.component('u', userdefined) |
官方这里有一个注意:函数
对于自定义标签名字,Vue.js 不强制要求遵循 W3C 规则(小写,而且包含一个短杠),尽管遵循这个规则比较好。ui
注册以后,就能够在HTML元素中使用了spa
<div id="app"> <u></u> </div> |
这里写了个一个小例子,实现组件内的数据绑定,方法实现,连接:.net
https://jsfiddle.net/miloer/x00grrts/
注意组件的模板替换了自定义元素,自定义元素的做用只是做为一个挂载点。这能够用实例选项 replace
改变。
局部注册:
在自定义组件里,添加另外一个自定义组件,只是在父元素组件里进行调用。连接:
https://jsfiddle.net/miloer/x00grrts/1/
一开始我觉得这么用:
html:
<div id="#app"> <other><u><u/></other> </div>
但这样只解析other的,并且这样还不符合Vue的设计风格,而后在想一想,明白了。
注册语法糖
// 在一个步骤中扩展与注册
Vue.component('my-component', { template: '<div>A custom component!</div>' }) // 局部注册也能够这么作 var Parent = Vue.extend({ components: { 'my-component': { template: '<div>A custom component!</div>' } } })
为了让事件更简单,能够直接传入选项对象而不是构造器给 Vue.component()
和component
选项。Vue.js 在背后自动调用 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><option>...</option></my-select>
不是有效的模板,即便 my-select
组件最终展开为 <select>...</select>
。
另外一个结果是,自定义标签(包括自定义元素和特殊标签,如<component>
、<template>
、 <partial>
)不能用在 ul
, select
, table
等对内部元素有限制的标签内。放在这些元素内部的自定义标签将被提到元素的外面,于是渲染不正确。
对于自定义元素,应当使用 is
特性:
<table> <tr is="my-component"></tr> </table> |
<template>
不能用在 <table>
内,这时应使用 <tbody>
,<table>
能够有多个<tbody>
:
<table> <tbody v-for="item in items"> <tr>Even row</tr> <tr>Odd row</tr> </tbody> </table> |
组件里的涉及的内容挺多的,不过越丰富功能就越完善。
使用props传递数据,组件实例的做用域是孤立的。这意味着不能而且不该该在子组件的模板内直接引用父组件的数据。可使用 props 把数据传给子组件。“prop” 是组件数据的一个字段,指望从父组件传下来。子组件须要显式地用 props
选项声明 props。
我以为这样能够在视图层显示的传递数据,假如你封装了一个form组件,加强复用性,就能够动态的更改action method方法了。固然,这个是我目前看到prosps 忽然想到的,也能解决目前的一个小问题。
写了两个demo,连接:
https://jsfiddle.net/xeu84559/1/
https://jsfiddle.net/x00grrts/2/
HTML 特性不区分大小写。名字形式为 camelCase 的 prop 用做特性时,须要转为 kebab-case(短横线隔开):
Vue.component('child', { // camelCase in JavaScript props: ['myMessage'], template: '<span>{{ myMessage }}</span>' })
<!-- kebab-case in HTML -->
<child my-message="hello!"></child>
组件能够为 props 指定验证要求。当组件给其余人使用时这颇有用,由于这些验证要求构成了组件的 API,确保其余人正确地使用组件。此时 props 的值是一个对象,包含验证要求:
Vue.component('example', { props: { // 基础类型检测 (`null` 意思是任何类型均可以) propA: Number, // 多种类型 (1.0.21+) propM: [String, Number], // 必需且是字符串 propB: { type: String, required: true }, // 数字,有默认值 propC: { type: Number, default: 100 }, // 对象/数组的默认值应当由一个函数返回 propD: { type: Object, default: function () { return { msg: 'hello' } } }, // 指定这个 prop 为双向绑定 // 若是绑定类型不对将抛出一条警告 propE: { twoWay: true }, // 自定义验证函数 propF: { validator: function (value) { return value > 10 } }, // 转换函数(1.0.12 新增) // 在设置值以前转换值 propG: { coerce: function (val) { return val + '' // 将值转换为字符串 } }, propH: { coerce: function (val) { return JSON.parse(val) // 将 JSON 字符串转换为对象 } } } })
type
能够是下面原生构造器:
type
也能够是一个自定义构造器,使用 instanceof
检测。
当 prop 验证失败了,Vue 将拒绝在子组件上设置此值,若是使用的是开发版本会抛出一条警告。
加一个 props 动态绑定: