vue可复用性
title: vue可复用性&组合
date: 2019-10-14 15:08:18
tags: # 这里写的分类会自动汇集到 categories 页面上,分类可以多级
- Vue.js # 一级分类
- Vue.js进阶 # 二级分类
混入 mixin
一个混入对象可以包含任意组件选项.当组件使用混入对象时,所有混入对象的选项将被”混合”进组件本身的选项.
例子:
1 | //定义一个混入对象 |
选项合并
当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行”合并”.
比如,数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先.
1 | var mixin = { |
同名钩子函数将合并成一个数组,因此都将被调用.另外,混入对象的钩子将在组件自身钩子之前调用.
1 | var mixin = { |
值为对象的选项,例如 methods、components 和 directives,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。
1 | var mixin = { |
注意:
Vue.extend()
也使用同样的策略进行合并。
全局混入
混入也可以进行全局注册,使用时需要小心.一但使用全局混入,他将影响每一个之后创建的 Vue 实例.
使用恰当时还可以用来为自定义选项注入处理逻辑.
1 | // 为自定义的选项 'myOption' 注入一个处理器。 |
请谨慎使用全局混入,因为它会影响每个单独创建的 Vue 实例 (包括第三方组件)。大多数情况下,只应当应用于自定义选项,就像上面示例一样。推荐将其作为插件发布,以避免重复应用混入。
自定义选项合并策略
自定义选项将使用默认策略,即简单地覆盖已有值。如果想让自定义选项以自定义逻辑合并,可以向 Vue.config.optionMergeStrategies 添加一个函数:
1 | Vue.config.optionMergeStrategies.myOption = function (toVal, fromVal) { |
对于多数值为对象的选项,可以使用与 methods 相同的合并策略:
1 | var strategies = Vue.config.optionMergeStrategies; |
可以在 Vuex 1.x 的混入策略里找到一个更高级的例子:
1 | const merge = Vue.config.optionMergeStrategies.computed; |
自定义指令
输入框聚焦
当页面加载时,该元素将获得焦点 (注意:autofocus 在移动版 Safari 上不工作)。事实上,只要你在打开这个页面后还没点击过任何内容,这个输入框就应当还是处于聚焦状态。现在让我们用指令来实现这个功能:
1 | //注册一个全局自定义指令v-focus |
局部指令注册,组件中接受directive
:
1 | directives: { |
然后在模板中任何元素上使用v-focus
属性,例如:
1 | <input v-focus> |
钩子函数
一个指令对象可以提供以下几个钩子函数:
bind
: 只调用一次,指令第一次绑定到元素时调用.在这里进行一次性的初始化设置.inserted
: 被绑定元素插入到父节点时调用.update
: 所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前.指令的值可能发生改变,也可能没有.componentUpdated
: 指令所在组件的 VNode 及其子 VNode 全部更新后调用.unbind
: 只调用一次,指令与元素解绑时调用.
钩子函数的参数
指令钩子会被传入以下参数:
el
: 指令所绑定的元素,可以直接操作 DOM.binding
: 一个对象,包含以下属性: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 编译生成的虚拟节点.oldVNode
: 上一个虚拟节点.
除了
el
之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的dataset
来进行。
范例:
1 | //html |
动态指令参数
在 v-mydirective:[argument]="value"
中,argument 参数可以根据组件实例数据进行更新!
例如创建一个自定义指令,通过固定布局将元素固定在页面上.
1 | <div id="baseexample"> |
自定义事件
1 | Vue.directive('pin', { |
这会把元素固定在距离页面顶部 200px 的位置.
如果需要将元素固定在左侧呢?
1 | <div id="dynamicexample"> |
1 | Vue.directive("pin", { |
函数简写
在很多时候,你可能想在 bind 和 update 时触发相同行为,而不关心其它的钩子。比如这样写:
1 | Vue.directive("color-swatch", function (el, binding) { |
对象字面量
如果指令需要多个值,可以传入一个 JavaScript 对象字面量。记住,指令函数能够接受所有合法的 JavaScript 表达式。
1 | //html |
渲染函数&JSX
渲染函数在 Vue.js 进阶里有讲到,JSX 先不看了.
插件
插件用来为 Vue 添加全局功能.
插件常用功能:
- 添加全局方法或属性.
- 添加全局资源: 指令,过滤器,过渡
- 通过全局混入来添加一些组件选项.
- 添加 Vue 实例方法,通过把他们添加到 Vue.prototype 上实现.
- 一个库,提供自己的 API,同时提供上面提到的一个或多个功能.如 Vue-router
使用插件
通过全局方法Vue.use()
使用插件.需要在new Vue()
之前调用.
也可以传入一个可选的对象.
1 | Vue.use(MyPlugin, { someOption: true }); |
Vue.use 会自动阻止多次注册相同插件,届时即使多次调用也只会注册一次该插件。
Vue.js 官方提供的一些插件 (例如 vue-router) 在检测到 Vue 是可访问的全局变量时会自动调用 Vue.use()
。然而在像 CommonJS 这样的模块环境中,你应该始终显式地调用 Vue.use()
开发插件
Vue.js 的插件暴露一个 install 的方法.这个方法的第一个参数是 Vue 构造器,第二个参数是可选的选项对象:
1 | MyPlugin.install = function (Vue, options) { |
过滤器
过滤器可以用在:双花括号插值和 v-bind 表达式
1 | <!-- 在双花括号中 --> |
在组件的选项中定义本地的过滤器
1 | filters: { |
或者在创建 Vue 实例之前全局定义过滤器:
1 | Vue.filter("capitalize", function (value) { |
当全局过滤器和局部过滤器重名时,会采用局部过滤器。
过滤器可以串联
1 | { |
在这个例子中,filterA 被定义为接收单个参数的过滤器函数,表达式 message 的值将作为参数传入到函数中。然后继续调用同样被定义为接收单个参数的过滤器函数 filterB,将 filterA 的结果传递到 filterB 中。
过滤器可以接收参数:
1 | { |
这里,filterA 被定义为接收三个参数的过滤器函数。其中 message 的值作为第一个参数,普通字符串 ‘arg1’ 作为第二个参数,表达式 arg2 的值作为第三个参数。