资讯专栏INFORMATION COLUMN

JS每日一题: Vue中mixin怎么理解?

jubincn / 3007人阅读

摘要:两个对象键名冲突时,取组件对象的键值对也使用同样的策略进行合并。代码理解全局混合也可以全局注册混合对象。注意使用一旦使用全局混合对象,将会影响到所有之后创建的实例为自定义的选项注入一个处理器。

20190122

Vue中mixin怎么理解?

mixin是为了让可复用的功能灵活的混入到当前组件中,混合的对象可以包含任意组件选项(生命周期,指令之类等等), mixin翻译过来叫混合,高级的词汇可以叫插件入侵
简单使用
// 定义一个混合对象
const myMixin = {
  created: function () {
    this.hello()
  },
  methods: {
    hello: function () {
      console.log("JS 每日一题")
    }
  }
}
// 定义一个使用混合对象的组件
const Component = Vue.extend({
  mixins: [myMixin]
})
var component = new Component() // JS 每日一题
选项合并(优先级)

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

代码理解

const mixin = {
  created: function () {
    console.log("混合对象的钩子被调用")
  }
}
new Vue({
  mixins: [mixin],
  created: function () {
    console.log("组件钩子被调用")
  }
})

// => "混合对象的钩子被调用"
// => "组件钩子被调用"
// 从上面的代码我们可以看出来混合对象的生命周期会被先调用

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

代码理解

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"
全局混合

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

// 为自定义的选项 "myOption" 注入一个处理器。
Vue.mixin({
  created: function () {
    var myOption = this.$options.myOption
    if (myOption) {
      console.log(myOption)
    }
  }
})
new Vue({
  myOption: "hello!"
})
// => "hello!"

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

// 源码地址 https://github.com/vuejs/vue/blob/52719ccab8fccffbdf497b96d3731dc86f04c1ce/src/core/util/options.js#L365

export 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
  }
}
总结

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

关于JS每日一题

JS每日一题可以看成是一个语音答题社区
每天利用碎片时间采用60秒内的语音形式来完成当天的考题
群主在次日0点推送当天的参考答案

注 绝不仅限于完成当天任务,更多是查漏补缺,学习群内其它同学优秀的答题思路

搜索微信公众号:JS每日一题

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102112.html

相关文章

  • JS每日一题: 请简述一下vuex实现原理

    摘要:给的实例注入一个的属性,这也就是为什么我们在的组件中可以通过访问到的各种数据和状态源码位置,是怎么实现的源码位置是对的的初始化,它接受个参数,为当前实例,为的,为执行的回调函数,为当前模块的路径。 20190221 请简述一下vuex实现原理 对vuex基础概念有不懂的可以点这里 vuex实现原理我们简单过一遍源码 地址 https://github.com/vuejs/vuex 首...

    JohnLui 评论0 收藏0
  • 前端知识点(二)

    摘要:在给一个目标对象为构造函数的代理对象构造实例时触发该操作,比如在执行时。 1、元素上下垂直居中的方式有哪些? 元素水平垂直居中的方式有哪些? absolute加margin方案 fixed 加 margin 方案 display:table 方案 行内元素line-height方案 flex 弹性布局方案 transform 未知元素宽高解决方案 absolute加mar...

    zacklee 评论0 收藏0
  • 前端知识点(二)

    摘要:在给一个目标对象为构造函数的代理对象构造实例时触发该操作,比如在执行时。 1、元素上下垂直居中的方式有哪些? 元素水平垂直居中的方式有哪些? absolute加margin方案 fixed 加 margin 方案 display:table 方案 行内元素line-height方案 flex 弹性布局方案 transform 未知元素宽高解决方案 absolute加mar...

    lbool 评论0 收藏0
  • 前端知识点(二)

    摘要:在给一个目标对象为构造函数的代理对象构造实例时触发该操作,比如在执行时。 1、元素上下垂直居中的方式有哪些? 元素水平垂直居中的方式有哪些? absolute加margin方案 fixed 加 margin 方案 display:table 方案 行内元素line-height方案 flex 弹性布局方案 transform 未知元素宽高解决方案 absolute加mar...

    Alex 评论0 收藏0
  • JS每日一题:vuekeepalive怎么理解

    摘要:问中怎么理解说在前面是源码中实现的一个组件感兴趣的可以研究源码什么是我们平时开发中总有部分组件没有必要多次我们需要将组件进行持久化,使组件状态维持不变,在下一次展示时,也不会进行重新音译过来就是保持活着所以在中我们可以使用来进行组件缓存基 20190212问 vue中keepalive怎么理解? 说在前面: keep-alive是vue源码中实现的一个组件, 感兴趣的可以研究源码 ht...

    fsmStudy 评论0 收藏0

发表评论

0条评论

jubincn

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<