这是我参与「第四届青训营 」笔记创作活动的第8天
Mixin
混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。
合并
若组件内部与混入对象有重名的选项时,会以适当的方式进行
数组
不重名的自动合并,重名的以组件原先有的数据为准。
钩子函数
混入对象的钩子函数先执行,组件中的后执行
选项
如methods , components , directives ,以组件中的数据优先进行合并。
自定义选项合并策略
自定义选项将使用默认策略,即简单地覆盖已有值。如果想让自定义选项以自定义逻辑合并,可以向 Vue.config.optionMergeStrategies 添加一个函数:
Vue.config.optionMergeStrategies.myOption = function (toVal, fromVal) {
// 返回合并后的值
}
对于多数值为对象的选项,可以使用与 methods 相同的合并策略:
var strategies = Vue.config.optionMergeStrategies
strategies.myOption = strategies.methods
自定义指令
语法
注册全局指令
Vue.directive('focus',{
inserted:function(el){
el.focus();
}
})
注册局部指令
directives:{
focus:{
inserted:function(el){
el.focus();
}
}
}
注册之后便可以使用 v-focus 指令。
钩子函数
自定义指令定义对象中提供以下几种钩子函数
bind:只调用一次,第一次绑定到指令时调用。inserted:被绑定元素插入父节点时调用update:所在组件的VNode更新时调用(有可能是更新前,也有可能是更新后)componentUpdated:指令所在组件的VNode及其子VNode全部更新后调用unbind:只调用一次,指令与元素解绑时调用
参数
-
el:指令所绑定的元素,用于直接操作DOM
-
binding:一个对象,包含:
namevalueoldValueexpressionargmodifiers
-
VNode -
oldVnode
动态参数
例如v-mydirective:[argument]="value"的augument 参数时动态的。
渲染函数与JSX
Vue官方推荐的创建HTML的方式是使用模版(template),但也同时支持渲染函数(render )与JSX语法。
Vue.component('anchored-heading', {
render: function (createElement) {
return createElement(
'h' + this.level, // 标签名称
this.$slots.default // 子节点数组
//当向组件中传递不带v-slot的子节点时,这些子节点被存储在实例中的 $slots.default中
)
},
props: {
level: {
type: Number,
required: true
}
}
})
虚拟DOM
Vue会建立一个虚拟DOM来对真实DOM进行更新。
return createElement('h1',this.blogTitle)
createElement 实际上是创建了一个关于节点的信息,把这些信息告诉Vue,这些节点称为虚拟节点,也就是VNode 。
⚠️VNode必须是唯一的,下面这种情况是错误的
render: function (createElement) {
var myParagraphVNode = createElement('p', 'hi')
return createElement('div', [
// 错误 - 重复的 VNode
myParagraphVNode, myParagraphVNode
])
}
createElement
对createElement 作如下解释。
createElement(
// {String | Object | Function}
// 一个 HTML 标签名、组件选项对象,或者
// resolve 了上述任何一种的一个 async 函数。必填项。
'div',
// {Object}
// 一个与模板中 attribute 对应的数据对象。可选。
{
// (详情见下一节)
},
// {String | Array}
// 子级虚拟节点 (VNodes),由 `createElement()` 构建而成,
// 也可以使用字符串来生成“文本虚拟节点”。可选。
[
'先写一些文字',
createElement('h1', '一则头条'),
createElement(MyComponent, {
props: {
someProp: 'foobar'
}
})
]
)
slots 与children
你可能想知道为什么同时需要 slots() 和 children。slots().default 不是和 children 类似的吗?在一些场景中,是这样——但如果是如下的带有子节点的函数式组件呢?
<my-functional-component>
<p v-slot:foo>
first
</p>
<p>second</p>
</my-functional-component>
对于这个组件,children 会给你两个段落标签,而 slots().default 只会传递第二个匿名段落标签,slots().foo 会传递第一个具名段落标签。同时拥有 children 和 slots(),因此你可以选择让组件感知某个插槽机制,还是简单地通过传递 children,移交给其它组件去处理。
\