Vue学习之Vue插件编写

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Kiloveyousmile/article/details/79222148

  虽然,相比于React、angular、Knockout等框架,Vue.js起步较晚,但是,它集成了大量其他框架的优点,目前已经成为目前广泛应用的一个前端框架。在他的社区,也活跃着大量的第三方插件。
  不过,偶尔我们也会用到原生的javascript库或者插件。如何在Vue.js框架中引入这些非Vue库或插件呢?笔者认为主要有以下两种方式:
  第一种,利用Vue提供的生命周期钩子函数,在不同时期引入原生js代码。Vue实例生命周期如图:

Vue实例生命周期图
这里写图片描述
  第二种,将第三方库或插件封装为Vue插件。具体如何实现呢?当你了解了Vue插件的编写方式之后,自然会明白。

Vue.js插件介绍

  这里,官网给出了很全面的介绍以及代码框架。

插件通常会为 Vue 添加全局功能。插件的范围没有限制——一般有下面几种:
1. 添加全局方法或者属性,如: vue-custom-element
2. 添加全局资源:指令/过滤器/过渡等,如 vue-touch
3. 通过全局 mixin 方法添加一些组件选项,如: vue-router
4. 添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
5. 一个库,提供自己的 API,同时提供上面提到的一个或多个功能,如 vue-router

  官网给的代码框架如下:

MyPlugin.install = function (Vue, options) {
  // 1. 添加全局方法或属性
  Vue.myGlobalMethod = function () {
    // 逻辑...
  }

// 2. 添加全局资源
Vue.directive('my-directive', {
  bind (el, binding, vnode, oldVnode) {
    // 逻辑...
  }
  ...
})

// 3. 注入组件
Vue.mixin({
  created: function () {
    // 逻辑...
  }
  ...
})

// 4. 添加实例方法
Vue.prototype.$myMethod = function (methodOptions) {
  // 逻辑...
  }
}

  官网给出了4种编写插件的方式。接下来,我们来尝试编写插件。

编写插件

  在我看来,Vue插件只是对原生javascript代码或Vue组件的简单封装,从而用以替换利用Vue实例生命周期钩子函数调用原生javascript代码的方式。以下是几种编写Vue插件的方式的实例。

1. 添加全局方法或属性

  编写一个Vue单页组件。

<!-- sayhello.vue组件 -->
<template>
    <div class="Hello-box" v-show="show">
      <p>Hello<p>
      <h1>{{text}}</h1>
    </div>
</template>

<script>
export default {
  props: {
    show: Boolean,
    text: {
      type: String,
      default: 'Wait a time...'
    }
  }
}
</script>

<style>
p{
  font-size: 28px;
  text-align: center;
}
h1 {
  text-align: center;
}
</style>

  对组件进行封装,并添加全局属性:

// sayhello.js
import SayHello from './sayhello.vue'
let $vm

export default {
  install (Vue, options) {
    if (!$vm) {
      const SayHelloPlugin = Vue.extend(SayHello)

      $vm = new SayHelloPlugin({
        el: document.createElement('div')
      })
      document.body.appendChild($vm.$el)
    }

    $vm.show = false

    let sayhello = {
      show (text) {
        $vm.show = true

        $vm.text = text
      },
      hide () {
        $vm.show = false
      }
    }

    if (!Vue.$sayhello) {
      Vue.$sayhello = sayhello
    }
  }
}

  在这个这个插件种,我们为组件增加了设置和隐藏text的功能。通过showhide函数完成,他们被封装在sayhello中。通过下面这句语句设置全局属性

Vue.$sayhello = sayhello

  我们来测试这个以下这个插件。由于.vue文件需要编译,我们使用vue-cli脚手架工具来测试:

扫描二维码关注公众号,回复: 3793937 查看本文章
//App.vue
<template>
  <div id="app">
   - A Smiple Demo -
  </div>
</template>

<script>
import SayHello from './components/plugin/sayhello.js'
import Vue from 'vue'
Vue.use(SayHello)
export default {
  name: 'App',
  mounted () {
    Vue.$sayhello.show('Friend')
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
//main.js
import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  components: { App },
  template: '<App/>'
})

  结果如图:
运行结果图

2. 添加全局资源

  添加全局资源包含了添加全局的指令/过滤器/过渡等,这种方式通过Vue.directive实现。假如我们有一个focus插件,它获取某个元素的焦点,则可以通过以下方式实现:

//focus.js
export default {
  install(Vue, options) {
      Vue.directive('focus', {
        bind: function() {},

        // 当绑定元素插入到 DOM 中。
       inserted: function(el, binding, vnode, oldVnode) {
         // 聚焦元素
         el.focus();
       },

      update: function() {},
      componentUpdated: function() {},
      unbind: function() {}
    });
  },
}

  调用方式:

<template>
  <input v-focus>
</template>
<script>
import Focus from './components/plugin/focus.js'
Vue.use(Focus)
<script>

  这样,在input挂载在DOM中时,便会自动获取焦点。
  Vue.directive包括5个函数,分别在不同的生命周期阶段调用。具体可以查看:自定义指令

附:说说VNode节点(Vue.js实现)

3. 注入组件

  这一种方式的实现可以通过调用Vue.mixin。混合 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混合对象可以包含任意组件选项。当组件使用混合对象时,所有混合对象的选项将被混入该组件本身的选项。
  也就是说,假设定义一个混合对象example,当一个组件test使用混合对象example时,test将拥有example的所有选项。
  修改1. 添加全局方法或属性sayhello.js中的代码,修改结果如下:

// sayhello.js
import SayHello from './sayhello.vue'
let $vm

export default {
  install (Vue, options) {
    if (!$vm) {
      const SayHelloPlugin = Vue.extend(SayHello)

      $vm = new SayHelloPlugin({
        el: document.createElement('div')
      })
      document.body.appendChild($vm.$el)
    }

    $vm.show = false

    let sayhello = {
      show (text) {
        $vm.show = true

        $vm.text = text
      },
      hide () {
        $vm.show = false
      }
    }

    // 以下为修改部分
    // if (!Vue.$sayhello) {
    //   Vue.$sayhello = sayhello
    // }

    Vue.mixin({
      created () {
        this.$sayhello = sayhello
      }
    })
  }
}

  调用方式同样改变:

//App.vue
//将
Vue.$sayhello.show()
//修改为
this.$sayhello.show()

  在混合(mixin)中,你可使用的选项基本上包括Vue创建实例时的所有选项。

4. 添加实例方法

  这种方式,只需要把你要暴露的方法、变量等添加到Vue.prototype上即可。
  具体可以修改demo如下:

// sayhello.js
import SayHello from './sayhello.vue'
let $vm

export default {
  install (Vue, options) {
    if (!$vm) {
      const SayHelloPlugin = Vue.extend(SayHello)

      $vm = new SayHelloPlugin({
        el: document.createElement('div')
      })
      document.body.appendChild($vm.$el)
    }

    $vm.show = false

    let sayhello = {
      show (text) {
        $vm.show = true

        $vm.text = text
      },
      hide () {
        $vm.show = false
      }
    }

    // 以下为修改部分
    // if (!Vue.$sayhello) {
    //   Vue.$sayhello = sayhello
    // }

    // Vue.mixin({
    //   created () {
    //     this.$sayhello = sayhello
    //   }
    // })

    Vue.prototype.$sayhello = sayhello
  }
}

  至此,4种编写插件的方式都已经介绍完毕。当然,正如官网所述的那样,每种方式并非独立的,需要根据自己的需求,选择一种或多种方式编写插件。
  demo网址:https://github.com/kangbb/plugin-demo

猜你喜欢

转载自blog.csdn.net/Kiloveyousmile/article/details/79222148