基础

除了内置指令,Vue.js 也允许注册自定义指令。自定义指令提供一种机制将数据的变化映射为 DOM 行为。

可以用 Vue.directive(id, definition) 方法注册一个全局自定义指令,它接收两个参数指令 ID 与定义对象。也可以用组件的 directives 选项注册一个局部自定义指令。

钩子函数

定义对象可以提供几个钩子函数(都是可选的):

bind:只调用一次,在指令第一次绑定到元素上时调用。

update: 在 bind 之后立即以初始值为参数第一次调用,之后每当绑定值变化时调用,参数为新值与旧值。

unbind:只调用一次,在指令从元素上解绑时调用。

示例

Vue.directive(‘my-directive’, {
bind: function () {
// 准备工作
// 例如,添加事件处理器或只需要运行一次的高耗任务
},
update: function (newValue, oldValue) {
// 值更新时的工作
// 也会以初始值为参数调用一次
},
unbind: function () {
// 清理工作
// 例如,删除 bind() 添加的事件监听器
}
})
在注册之后,便可以在 Vue.js 模板中这样用(记着添加前缀 v-):

<div v-my-directive=”someValue”></div>
当只需要 update 函数时,可以传入一个函数替代定义对象:

Vue.directive(‘my-directive’, function (value) {
// 这个函数用作 update()
})

Read More →

大部分的基础内容我们已经讲到了,现在讲点底层内容。Vue.js 最显著的一个功能是响应系统 —— 模型只是普通对象,修改它则更新视图。这让状态管理非常简单且直观,不过理解它的原理也很重要,可以避免一些常见问题。下面我们开始深挖 Vue.js 响应系统的底层细节。

如何追踪变化

把一个普通对象传给 Vue 实例作为它的 data 选项,Vue.js 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。这是 ES5 特性,不能打补丁实现,这便是为什么 Vue.js 不支持 IE8 及更低版本。

用户看不到 getter/setters,但是在内部它们让 Vue.js 追踪依赖,在属性被访问和修改时通知变化。一个问题是在浏览器控制台打印数据对象时 getter/setter 的格式化不同,使用 vm.$log() 实例方法可以得到更友好的输出。

模板中每个指令/数据绑定都有一个对应的 watcher 对象,在计算过程中它把属性记录为依赖。之后当依赖的 setter 被调用时,会触发 watcher 重新计算 ,也就会导致它的关联指令更新 DOM。

Read More →

什么是组件?

组件(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 规则(小写,并且包含一个短杠),尽管遵循这个规则比较好。

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

<div id=”example”>
<my-component></my-component>
</div>
// 定义
var MyComponent = Vue.extend({
template: ‘<div>A custom component!</div>’
})

// 注册
Vue.component(‘my-component’, MyComponent)

// 创建根实例
new Vue({
el: ‘#example’
})
渲染为:

<div id=”example”>
<div>A custom component!</div>
</div>
A custom component!
注意组件的模板替换了自定义元素,自定义元素的作用只是作为一个挂载点。可以用实例选项 replace 决定是否替换。

Read More →

通过 Vue.js 的过渡系统,可以在元素从 DOM 中插入或移除时自动应用过渡效果。Vue.js 会在适当的时机为你触发 CSS 过渡或动画,你也可以提供相应的 JavaScript 钩子函数在过渡过程中执行自定义的 DOM 操作。

为了应用过渡效果,需要在目标元素上使用 transition 特性:

<div v-if=”show” transition=”my-transition”></div>
transition 特性可以与下面资源一起用:

v-if
v-show
v-for (只在插入和删除时触发,使用 vue-animated-list 插件)
动态组件 (介绍见组件)
在组件的根节点上,并且被 Vue 实例 DOM 方法(如 vm.$appendTo(el))触发。
当插入或删除带有过渡的元素时,Vue 将:

尝试以 ID “my-transition” 查找 JavaScript 过渡钩子对象——通过 Vue.transition(id, hooks) 或 transitions 选项注册。如果找到了,将在过渡的不同阶段调用相应的钩子。

自动嗅探目标元素是否有 CSS 过渡或动画,并在合适时添加/删除 CSS 类名。

如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作(插入/删除)在下一帧中立即执行。

Read More →

基础用法

可以用 v-model 指令在表单控件元素上创建双向数据绑定。根据控件类型它自动选取正确的方法更新元素。尽管有点神奇,v-model 不过是语法糖,在用户输入事件中更新数据,以及特别处理一些极端例子。

Text

<span>Message is: {{ message }}</span>
<br>
<input type=”text” v-model=”message” placeholder=”edit me”>
Message is:

Checkbox

单个勾选框,逻辑值:

<input type=”checkbox” id=”checkbox” v-model=”checked”>
<label for=”checkbox”>{{ checked }}</label>
false
多个勾选框,绑定到同一个数组:

<input type=”checkbox” id=”jack” value=”Jack” v-model=”checkedNames”>
<label for=”jack”>Jack</label>
<input type=”checkbox” id=”john” value=”John” v-model=”checkedNames”>
<label for=”john”>John</label>
<input type=”checkbox” id=”mike” value=”Mike” v-model=”checkedNames”>
<label for=”mike”>Mike</label>
<br>
<span>Checked names: {{ checkedNames | json }}</span>
new Vue({
el: ‘…’,
data: {
checkedNames: []
}
})
Jack John Mike
Checked names: []
Radio

<input type=”radio” id=”one” value=”One” v-model=”picked”>
<label for=”one”>One</label>
<br>
<input type=”radio” id=”two” value=”Two” v-model=”picked”>
<label for=”two”>Two</label>
<br>
<span>Picked: {{ picked }}</span>
One
Two
Picked:
Select

单选:

<select v-model=”selected”>
<option selected>A</option>
<option>B</option>
<option>C</option>
</select>
<span>Selected: {{ selected }}</span>
Selected: A
多选(绑定到一个数组):

<select v-model=”selected” multiple>
<option selected>A</option>
<option>B</option>
<option>C</option>
</select>
<br>
<span>Selected: {{ selected | json }}</span>

Selected: [ “A” ]
动态选项,用 v-for 渲染:

<select v-model=”selected”>
<option v-for=”option in options” v-bind:value=”option.value”>
{{ option.text }}
</option>
</select>
<span>Selected: {{ selected }}</span>
new Vue({
el: ‘…’,
data: {
selected: ‘A’,
options: [
{ text: ‘One’, value: ‘A’ },
{ text: ‘Two’, value: ‘B’ },
{ text: ‘Three’, value: ‘C’ }
]
}
})
Selected: A
绑定 value

对于单选按钮,勾选框及选择框选项,v-model 绑定的 value 通常是静态字符串(对于勾选框是逻辑值):

<!– 当选中时,`picked` 为字符串 “a” –>
<input type=”radio” v-model=”picked” value=”a”>

<!– `toggle` 为 true 或 false –>
<input type=”checkbox” v-model=”toggle”>

<!– 当选中时,`selected` 为字符串 “abc” –>
<select v-model=”selected”>
<option value=”abc”>ABC</option>
</select>
但是有时我们想绑定 value 到 Vue 实例的一个动态属性上,这时可以用 v-bind 实现,并且这个属性的值可以不是字符串。

Checkbox

<input
type=”checkbox”
v-model=”toggle”
v-bind:true-value=”a”
v-bind:false-value=”b”>
// 当选中时
vm.toggle === vm.a
// 当没有选中时
vm.toggle === vm.b
Radio

<input type=”radio” v-model=”pick” v-bind:value=”a”>
// 当选中时
vm.pick === vm.a
Select Options

<select v-model=”selected”>
<!– 对象字面量 –>
<option v-bind:value=”{ number: 123 }”>123</option>
</select>
// 当选中时
typeof vm.selected // -> ‘object’
vm.selected.number // -> 123
参数特性

lazy

在默认情况下,v-model 在input 事件中同步输入框值与数据,可以添加一个特性lazy,从而改到在 change 事件中同步:

<!– 在 “change” 而不是 “input” 事件中更新 –>
<input v-model=”msg” lazy>
number

如果想自动将用户的输入转为 Number 类型(如果原值的转换结果为 NaN 则返回原值),可以添加一个特性 number:

<input v-model=”age” number>
debounce

debounce 设置一个最小的延时,在每次敲击之后延时同步输入框的值与数据。如果每次更新都要进行高耗操作(例如在输入提示中 Ajax 请求),它较为有用。

<input v-model=”msg” debounce=”500″>
edit me

注意 debounce 参数不会延迟 input 事件:它延迟“写入”底层数据。因此在使用 debounce时应当用 vm.$watch() 响应数据的变化。若想延迟 DOM 事件,应当使用 debounce 过滤器。