vue高级用法

作者: 小王子__ | 来源:发表于2021-12-24 18:03 被阅读0次

    Vue 插件 plugin

    1, Vue 插件 plugin

    安装 Vue.js 插件。如果插件是一个对象,必须提供 install 方法。如果插件是一个函数,它会被作为 install 方法。install 方法调用时,会将 Vue 作为参数传入。

    该方法需要在调用 new Vue() 之前被调用。

    当 install 方法被同一个插件多次调用,插件将只会被安装一次。

    使用插件

    通过全局方法 Vue.use() 使用插件。它需要在你调用 new Vue() 启动应用之前完成:

    // 调用 `MyPlugin.install(Vue)`
    Vue.use(MyPlugin)
    new Vue({
     // ...组件选项
    })
    
    等同于 `Myplugin.install(Vue)`
    

    也可以传入一个可选的选项对象:

    Vue.use(MyPlugin, { someOption: true })
    

    Vue.use 会自动阻止多次注册相同插件,届时即使多次调用也只会注册一次该插件。

    Vue.js 官方提供的一些插件 (例如 vue-router) 在检测到 Vue 是可访问的全局变量时会自动调用 Vue.use()。然而在像 CommonJS 这样的模块环境中,你应该始终显式地调用 Vue.use():

    // 用 Browserify 或 webpack 提供的 CommonJS 模块环境时
    var Vue = require('vue')
    var VueRouter = require('vue-router')
    
    // 不要忘了调用此方法
    Vue.use(VueRouter)
    

    开发插件

    我们开发插件对象, 需要给这个对象下暴露⼀个 install ⽅法。也就是说只要⼀个对象有 install ⽅法,同时它的第⼀个参数为 Vue 构造函数,第⼆个参数为⼀个 options,那么他就是⼀个合法的 Vue 插件。

    // myPlugin 只需要是⼀个对象即可
    let MyPlugin = {}
    let myPlugin = function() {}
    MyPlugin.install = function (Vue, options) {
      // 1. 添加全局方法或 property
      Vue.myGlobalMethod = function () {
        // 逻辑...
      }
    
      // 2. 添加全局资源
      Vue.directive('my-directive', {
        bind (el, binding, vnode, oldVnode) {
          // 逻辑...
        }
        ...
      })
    
      // 3. 注入组件选项
      Vue.mixin({
        created: function () {
          // 逻辑...
        }
        ...
      })
    
      // 4. 添加实例方法
      Vue.prototype.$myMethod = function (methodOptions) {
        // 逻辑...
      }
    }
    

    可以使⽤插件做很多⾃动化的事情,某些情况下我们可以⽐ 组件化 能够做更多细粒度的封装。

    创建 plugins.js 文件:

    export const useHeaderComponent = {
        install: function (Vue) {
            Vue.component('Header', {
                mounted() {
                    console.log('mounted=====')
                },
                render(createElement) {
                    return createElement(
                        'div', {
                        attrs: {
                            id: 'Head'
                        }
                    }
                    )
                }
            })
        }
    }
    

    main.js中引入:

    import { useHeaderComponent } from './plugins'
    Vue.use(useHeaderComponent)
    

    其他组件中直接使用:

    <Header />
    

    2,Vue 混合 mixin

    混⼊ (mixin) 提供了⼀种⾮常灵活的⽅式,来分发 Vue 组件中的可复⽤功能。

    ⼀个混⼊对象可以包含任意组件选项。当组件使⽤混⼊对象时,所有混⼊对象的选项将被“混合”进⼊该组件本身的选项。
    我们的 mixin 可以在组件级别和全局两种⽅式进⾏混⼊

    // 定义⼀个混⼊对象
    var myMixin = {
     created: function () {
       this.hello()
     },
     methods: {
       hello: function () {
         console.log('hello from mixin!')
       }
     }
    }
    // 定义⼀个使⽤混⼊对象的组件
    var Component = Vue.extend({
       mixins: [myMixin]
    })
    var component = new Component() // => "hello from mixin!"
    

    选项合并

    当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行“合并”。

    比如,数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先。

    var mixin = {
      data: function () {
        return {
          message: 'hello',
          foo: 'abc'
        }
      }
    }
    
    new Vue({
      mixins: [mixin],
      data: function () {
        return {
          message: 'goodbye',
          bar: 'def'
        }
      },
      created: function () {
        console.log(this.$data)
        // => { message: "goodbye", foo: "abc", bar: "def" }
      }
    })
    

    同名钩子函数将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。

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

    值为对象的选项,例如 methods、components 和 directives,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。

    var mixin = {
      methods: {
        foo: function () {
          console.log('foo')
        },
        conflicting: function () {
          console.log('from mixin')
        }
      }
    }
    
    var 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.extend() 也使用同样的策略进行合并。

    全局混入

    混入也可以进行全局注册。使用时格外小心!一旦使用全局混入,它将影响每一个之后创建的 Vue 实例。使用恰当时,这可以用来为自定义选项注入处理逻辑。

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

    请谨慎使用全局混入,因为它会影响每个单独创建的 Vue 实例 (包括第三方组件)。大多数情况下,只应当应用于自定义选项,就像上面示例一样。推荐将其作为插件发布,以避免重复应用混入。

    自定义选项合并策略

    自定义选项将使用默认策略,即简单地覆盖已有值。如果想让自定义选项以自定义逻辑合并,可以向 Vue.config.optionMergeStrategies 添加一个函数:

    Vue.config.optionMergeStrategies.myOption = function (toVal, fromVal) {
      // 返回合并后的值
    }
    

    对于多数值为对象的选项,可以使用与 methods 相同的合并策略:

    var strategies = Vue.config.optionMergeStrategies
    strategies.myOption = strategies.methods
    

    可以在 Vuex 1.x 的混入策略里找到一个更高级的例子:

    const merge = Vue.config.optionMergeStrategies.computed
    Vue.config.optionMergeStrategies.vuex = function (toVal, fromVal) {
      if (!toVal) return fromVal
      if (!fromVal) return toVal
      return {
        getters: merge(toVal.getters, fromVal.getters),
        state: merge(toVal.state, fromVal.state),
        actions: merge(toVal.actions, fromVal.actions)
      }
    }
    

    相关文章

      网友评论

        本文标题:vue高级用法

        本文链接:https://www.haomeiwen.com/subject/hixrqrtx.html