混入
基础
混入提供了一种非常灵活的方式分发Vue组件中可复用功能。一个混入对象可以包含任意组件选项。
1 | // 定义一个混入对象 |
选项合并
数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先。
同名钩子函数将合并为一个数组,混入对象的钩子将在组件自身钩子之前调用。
值为对象的选项,例如 methods
、components
和 directives
,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。
全局混入
混入实例进行全局注册时,将影响每一个之后创建的 Vue 实例。
自定义选项合并
自定义选项将使用默认策略,即简单地覆盖已有值。如果想让自定义选项以自定义逻辑合并,可以向 Vue.config.optionMergeStrategies
添加一个函数:
1 | Vue.config.optionMergeStrategies.myOption = function (toVal, fromVal) { |
自定义指令
简介
除了核心功能默认内置的指令 (v-model
和 v-show
),Vue 也允许注册自定义指令。
例如,实现一个自动聚焦指令
1 | // 注册一个全局自定义指令 `v-focus` |
如果想注册局部指令,组件中也接受一个 directives
的选项:
1 | directives: { |
然后可以在模板中任何元素上使用新的 v-focus
property,如下:
1 | <input v-focus> |
钩子函数
一个指令定义对象可以提供如下几个钩子函数 (均为可选):
bind
:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。inserted
:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。update
:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。componentUpdated
:指令所在组件的 VNode 及其子 VNode 全部更新后调用。unbind
:只调用一次,指令与元素解绑时调用。
钩子函数参数
指令钩子函数会被传入以下参数:
el
:指令所绑定的元素,可以用来直接操作 DOM。binding
:一个对象,包含以下 property:-
name
:指令名,不包括v-
前缀。value
:指令的绑定值,例如:v-my-directive="1 + 1"
中,绑定值为2
。oldValue
:指令绑定的前一个值,仅在update
和componentUpdated
钩子中可用。无论值是否改变都可用。expression
:字符串形式的指令表达式。例如v-my-directive="1 + 1"
中,表达式为"1 + 1"
。arg
:传给指令的参数,可选。例如v-my-directive:foo
中,参数为"foo"
。modifiers
:一个包含修饰符的对象。例如:v-my-directive.foo.bar
中,修饰符对象为{ foo: true, bar: true }
。
vnode
:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。oldVnode
:上一个虚拟节点,仅在update
和componentUpdated
钩子中可用。
除了
el
之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的dataset
来进行。
使用了这些 property 的自定义钩子样例:
1 | <div id="hook-arguments-example" v-demo:foo.a.b="message"></div> |
1 | Vue.directive('demo', { |
动态指令参数
指令的参数可以是动态的。例如,在 v-mydirective:[argument]="value"
中,argument
参数可以根据组件实例数据进行更新!
使用时,通过钩子函数的binding.arg
获取该指令的参数,根据指令参数的不同可以处理不同的操作。
函数简写
在很多时候,你可能想在 bind
和 update
时触发相同行为,而不关心其它的钩子。比如这样写:
1 | Vue.directive('color-swatch', function (el, binding) { |
对象字面量
如果指令需要多个值,可以传入一个 JavaScript 对象字面量。指令函数能够接受所有合法的 JavaScript 表达式。
1 | <div v-demo="{ color: 'white', text: 'hello!' }"></div> |
1 | Vue.directive('demo', function (el, binding) { |
渲染函数 & JSX
Vue 推荐在绝大多数情况下使用模板来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器。
插件
插件通常用来为 Vue 添加全局功能。插件的功能范围没有严格的限制——一般有下面几种:
- 添加全局方法或者 property。如:vue-custom-element
- 添加全局资源:指令/过滤器/过渡等。如 vue-touch
- 通过全局混入来添加一些组件选项。如 vue-router
- 添加 Vue 实例方法,通过把它们添加到
Vue.prototype
上实现。 - 一个库,提供自己的 API,同时提供上面提到的一个或多个功能。如 vue-router
使用插件
通过全局方法 Vue.use()
使用插件。它需要在你调用 new Vue()
启动应用之前完成:
1 | // 调用 `MyPlugin.install(Vue)` |
也可以传入一个可选的选项对象:
1 | Vue.use(MyPlugin, { someOption: true }) |
Vue.use
会自动阻止多次注册相同插件,届时即使多次调用也只会注册一次该插件。
Vue.js 官方提供的一些插件 (例如 vue-router
) 在检测到 Vue
是可访问的全局变量时会自动调用 Vue.use()
。然而在像 CommonJS 这样的模块环境中,你应该始终显式地调用 Vue.use()
:
1 | // 用 Browserify 或 webpack 提供的 CommonJS 模块环境时 |
过滤器
Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器可以用在两个地方:双花括号插值和 v-bind
表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示:
1 | <!-- 在双花括号中 --> |
可以在一个组件的选项中定义本地的过滤器:
1 | filters: { |
或者在创建 Vue 实例之前全局定义过滤器:
1 | Vue.filter('capitalize', function (value) { |
当全局过滤器和局部过滤器重名时,会采用局部过滤器。
过滤器可以串联:
1 | {{ message | filterA | filterB }} |
过滤器是 JavaScript 函数,因此可以接收参数:
1 | {{ message | filterA('arg1', arg2) }} |
这里,filterA
被定义为接收三个参数的过滤器函数。其中 message
的值作为第一个参数,普通字符串 'arg1'
作为第二个参数,表达式 arg2
的值作为第三个参数。