Vue进阶(二)|青训营笔记

91 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第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:一个对象,包含:

    • name
    • value
    • oldValue
    • expression
    • arg
    • modifiers
  • 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,
     requiredtrue
  }
}
})

虚拟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'
    }
  })
]
)

slotschildren

你可能想知道为什么同时需要 slots()childrenslots().default 不是和 children 类似的吗?在一些场景中,是这样——但如果是如下的带有子节点的函数式组件呢?

<my-functional-component>
<p v-slot:foo>
  first
</p>
<p>second</p>
</my-functional-component>

对于这个组件,children 会给你两个段落标签,而 slots().default 只会传递第二个匿名段落标签,slots().foo 会传递第一个具名段落标签。同时拥有 childrenslots(),因此你可以选择让组件感知某个插槽机制,还是简单地通过传递 children,移交给其它组件去处理。


\