9159金沙游艺场

图片 5
windows中VirtualBox调整扩大VMDK格式的磁盘空间

js玩转数字—-取整,四舍五入,数字字符串转换

Vue中mixin怎么理解?

Vue中mixin怎么理解?

new Vue()、component

一.自定义指令directive

mixin是为了让可复用的功能灵活的混入到当前组件中,混合的对象可以包含任意组件选项,
mixin翻译过来叫混合,高级的词汇可以叫插件入侵

首先我们来约定一个选项对象 baseOptions,后面的代码会用到.

除了核心功能默认内置的指令 (v-model和v-show),Vue
也允许注册自定义指令。注意,在Vue2.0中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通
DOM 元素进行底层操作,这时候就会用到自定义指令。

简单使用

let options = { template: '{{firstName}} {{lastName}} aka {{alias}}', data: function () { return { firstName: 'Walter', lastName: 'White', alias: 'Heisenberg' } }, created(){ console.log; }};

来个实例,当页面加载时,该input元素将获得焦点:

// 定义一个混合对象const myMixin = { created: function () { this.hello() }, methods: { hello: function () { console.log('JS 每日一题') } }}// 定义一个使用混合对象的组件const Component = Vue.extend({ mixins: [myMixin]})var component = new Component() // JS 每日一题

new Vue() source:vue/src/core/instance/index.js

// 注册一个全局自定义指令 `v-focus`Vue.directive('focus', { // 当被绑定的元素插入到 DOM 中时…… inserted: function (el) { // 聚焦元素 el.focus() }})

选项合并(优先级)

new Vue;// -> onCreated-1component source:vue/src/core/global-api/assets.js

如果想注册局部指令,组件中也接受一个directives的选项:

当组件和混合对象含有同名选项时,选项会按照规则进行合并

Vue.component 是用来注册或获取全局组件的方法,其作用是将通过 Vue.extend
生成的扩展实例构造器注册为一个组件.全局注册的组件可以在所有晚于该组件注册语句构造的Vue实例中使用.

directives: { focus: { // 指令的定义 inserted: function (el) { el.focus() } }}

代码理解

Vue.component('global-component', Vue.extend;//传入一个选项对象,等价于上行代码.Vue.component('global-component', baseOptions);// 获取注册的组件var MyComponent = Vue.component

然后你可以在模板中任何元素上使用新的 v-focus 属性,如下:

const mixin = { created: function () { console.log('混合对象的钩子被调用') }}new Vue({ mixins: [mixin], created: function () { console.log('组件钩子被调用') }})// = "混合对象的钩子被调用"// = "组件钩子被调用"// 从上面的代码我们可以看出来混合对象的生命周期会被先调用

当我们需要在其他页面‘扩展’或者叫‘混合’baseOptions时,Vue中提供了多种的实现方式:extend,mixins,extends.

input v-focus

值为对象的选项,例如 methods, components 和
directives,将被混合为同一个对象。两个对象键名冲突时,取组件对象的键值对,Vue.extend()
也使用同样的策略进行合并。

extend source:vue/src/core/global-api/extend.js

钩子函数

代码理解

可以扩展 Vue 构造器,从而用预定义选项创建可复用的组件构造器。

一个指令定义对象可以提供如下几个钩子函数 (均为可选):

const mixin = { methods: { foo: function () { console.log('foo') }, conflicting: function () { console.log('from mixin') } }}const vm = new Vue({ mixins: [mixin], methods: { bar: function () { console.log('bar') }, conflicting: function () { console.log('from self') } }})vm.foo() // = "foo"vm.bar() // = "bar"vm.conflicting() // = "from self"
let BaseComponent = Vue.extend;//基于基础组件BaseComponent,再扩展新逻辑.new BaseComponent{ //do something console.log; } //其他自定义逻辑});// -> onCreated-1// -> onCreated-2

bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。inserted:被绑定元素插入父节点时调用
(仅保证父节点存在,但不一定已被插入文档中)。update:所在组件的 VNode
更新时调用,但是可能发生在其子 VNode
更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新
(详细的钩子函数参数见下)。componentUpdated:指令所在组件的 VNode 及其子
VNode 全部更新后调用。unbind:只调用一次,指令与元素解绑时调用。

全局混合

mixins

接下来我们来看一下钩子函数的参数 (即el、binding、vnode和oldVnode)。

也可以全局注册混合对象。注意使用! 一旦使用全局混合对象,将会影响到 所有
之后创建的 Vue 实例

mixins
选项接受一个混合对象的数组。这些混合实例对象可以像正常的实例对象一样包含选项,他们将在
Vue.extend() 里最终选择使用相同的选项合并逻辑合并。

钩子函数参数

// 为自定义的选项 'myOption' 注入一个处理器。Vue.mixin({ created: function () { var myOption = this.$options.myOption if (myOption) { console.log(myOption) } }})new Vue({ myOption: 'hello!'})// = "hello!"
new Vue({ mixins: [baseOptions], created(){ //do something console.log; } //其他自定义逻辑});// -> onCreated-1// -> onCreated-2

指令钩子函数会被传入以下参数:

再了解了基本用法后再简单过一遍源码加深印象

extends

el:指令所绑定的元素,可以用来直接操作 DOM 。

// 源码地址 #L365export function mergeOptions ( parent: Object, child: Object, vm?: Component): Object { // flow语法,表明返回的是一个对象 if (process.env.NODE_ENV !== 'production') { checkComponents(child) } if (typeof child === 'function') { child = child.options } normalizeProps(child, vm) normalizeInject(child, vm) normalizeDirectives(child) const extendsFrom = child.extends //若存在extends,则将其内容合并到父对象parent中保存,最后再和自身child合并 if (extendsFrom) { parent = mergeOptions(parent, extendsFrom, vm) } // 若存在mixins,则将其内容合并到父对象parent中保存,最后再和自身child合并 if (child.mixins) { for (let i = 0, l = child.mixins.length; i  l; i++) { parent = mergeOptions(parent, child.mixins[i], vm) } } //初始化一个对象,用于存储parent和child合并后的内容,并作为mergeOptions函数的结果返回 const options = {} let key for (key in parent) { mergeField(key) } for (key in child) { if (!hasOwn(parent, key)) { mergeField(key) } } //使用策略对象对parent和child进行合并 function mergeField (key) { const strat = strats[key] || defaultStrat options[key] = strat(parent[key], child[key], vm, key) } return options}export function initMixin (Vue: GlobalAPI) { Vue.mixin = function (mixin: Object) { this.options = mergeOptions(this.options, mixin) return this }}

这和 mixins
类似,区别在于,组件自身的选项会比要扩展的源组件具有更高的优先级.

binding:一个对象,包含以下属性:

总结

官方文档是这么写的,除了优先级,可能就剩下接受参数的类型吧,mixins接受的是数组.

name:指令名,不包括 v-
前缀。value:指令的绑定值,例如:v-my-directive=”1 +
1″中,绑定值为2。oldValue:指令绑定的前一个值,仅在update和componentUpdated钩子中可用。无论值是否改变都可用。expression:字符串形式的指令表达式。例如v-my-directive=”1

mixin就是采取一定规则将一个功能(组件)的属性混合到另一个组件或者全局当中,优点就是灵活度高,耦合度低,便于维护

new Vue({ extends: baseOptions, created(){ //do something console.log; } //其他自定义逻辑});// -> onCreated-1// -> onCreated-2
  • 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来进行。

Vue.extend Vue.extend只是创建一个构造器,他是为了创建可复用的组件.
mixins,extends 而mixins和extends是为了拓展组件.

这是一个使用了这些属性的自定义钩子样例:

从源码来看通过extend,extends和mixins三种方式接收的options,最终都是通过mergeOptions进行合并的.差异只是官方文档中提到的优先级不同extend
> extends > mixins.
所以,如果是简单的扩展组件功能,三个方式都可以达到目的.

div v-demo:foo.a.b="message"/div

Vue.directive('demo', { bind: function (el, binding, vnode) { var s = JSON.stringify el.innerHTML = 'name: ' + s(binding.name) + 'br' + 'value: ' + s(binding.value) + 'br' + 'expression: ' + s(binding.expression) + 'br' + 'argument: ' + s(binding.arg) + 'br' + 'modifiers: ' + s(binding.modifiers) + 'br' + 'vnode keys: ' + Object.keys(vnode).join(', ') }})new Vue({ el: '#hook-arguments-example', data: { message: 'hello!' }})

而这三种方式使用场景上细化的区分,目前我也蒙圈中…

结果:

//几种方式的不同示例:

name: "demo"value: "hello!"expression: "message"argument: "foo"modifiers: {"a":true,"b":true}vnode keys: tag, data, children, text, elm, ns, context, fnContext, fnOptions, fnScopeId, key, componentOptions, componentInstance, parent, raw, isStatic, isRootInsert, isComment, isCloned, isOnce, asyncFactory, asyncMeta, isAsyncPlaceholder

相关文章

No Comments, Be The First!
近期评论
    功能
    网站地图xml地图