使用流程

  1. 功能:用于增强Vue
  2. 本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。
  3. 定义插件:

    plugins.js(一般main同级)

  1. export default{
  2. //参数:1.Vue- vm 2.options接受其他参数用于指定filter内容等
  3. install (Vue, options) {
  4. // 1. 添加全局过滤器
  5. Vue.filter(....)
  6. // 2. 添加全局指令
  7. Vue.directive(....)
  8. // 3. 配置全局混入(合)
  9. Vue.mixin(....)
  10. // 4. 添加实例方法
  11. Vue.prototype.$myMethod = function () {...}
  12. Vue.prototype.$myProperty = xxxx
  13. }
  14. }
  1. 使用插件:Vue.use()

    main.js

  1. import plugins from './plugins'
  2. Vue.use(plugins,1,2,3)

项目实例 - Loading提示框

调用接口时loading…

手写插件 - Loading.vue

src/plugin/loading.vue

  1. <template>
  2. <div class="container" v-show="isShow">
  3. <div class="loading"></div>
  4. <p class="title">{{title}}</p>
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. name: 'Loading',
  10. data: function () {
  11. return {
  12. title: '正在加载...',
  13. isShow: false
  14. }
  15. }
  16. }
  17. </script>
  18. <style scoped lang="scss">
  19. .container{
  20. width: 200px;
  21. height: 200px;
  22. border-radius: 20px;
  23. background: rgba(0,0,0,0.5);
  24. position: absolute;
  25. left: 50%;
  26. top: 50%;
  27. transform: translate(-50%, -50%);
  28. .loading{
  29. width: 100px;
  30. height: 100px;
  31. border-radius: 50%;
  32. border: 5px solid #fff;
  33. margin: 20px auto;
  34. border-right-color: #409eff;
  35. animation: loading 2s linear infinite;
  36. }
  37. .title{
  38. text-align: center;
  39. font-size: 16px;
  40. color: #fff;
  41. }
  42. }
  43. @keyframes loading {
  44. from{
  45. transform: rotate(0deg);
  46. }
  47. to{
  48. transform: rotate(360deg);
  49. }
  50. }
  51. </style>

插件配置 - index.js

src/plugin/index.js

// import Vue from 'vue'
import Loading from './Loading'

export default {
  // 注意点: 如果要将一个组件封装成一个插件, 那么必须提供一个install方法
  //必须在install方法中注册当前的这个组件
  install: function (Vue, Options) {
    // Vue.component(Loading.name, Loading)

    // 1.根据我们的组件生成一个构造函数
    //调用Vue.extend,返回的都是一个全新的VueComponent
    let LoadingContructor = Vue.extend(Loading)
    // 2.根据构造函数创建实例对象
    let LoadingInstance = new LoadingContructor()
    // 3.随便创建一个标签(元素)
    let oDiv = document.createElement('div')
    // 4.将创建好的标签添加到界面上
    document.body.appendChild(oDiv)
    // 5.将创建好的实例对象挂载到创建好的元素上
    LoadingInstance.$mount(oDiv)

    /* 3 4 5 可以改为如下 并且可以传data 修改data
        let LoadingInstance = new LoadingContructor({
            el:document.createElement('div'),
            data(){
                return {title2: 'ing~',}
            }
        })
        document.body.appendChild(LoadingInstance.$el)
        LoadingInstance.title2 = 'ing~~~'
     */

    // console.log(Options)
    // console.log(LoadingInstance.title)
    // 添加初始化值
    if (Options && Options.title !== null && Options.title !== undefined) {
      LoadingInstance.title = Options.title
    }
    // 添加全局方法
    Vue.showLoading = function () {
      LoadingInstance.isShow = true
    }
    Vue.hiddenLoading = function () {
      LoadingInstance.isShow = false
    }
    // 添加实例方法
    Vue.prototype.$showLoading = function () {
      LoadingInstance.isShow = true
    }
    Vue.prototype.$hiddenLoading = function () {
      LoadingInstance.isShow = false
    }
  }
}

导入插件 - main.js

import Vue from 'vue'
import Loading from './plugin/loading/index'

//use方法接受一个对象或函数,对象必须有install,函数则会被调用不需要install
Vue.use(Loading,{
  title:'正在加载...'
})

使用插件 - axios调用时

import Vue from 'vue'

let count = 0 //记录请求次数
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
  // 在发送请求之前做些什么
  count++
  Vue.showLoading()
  return config
}, function (error) {
  // 对请求错误做些什么
  Vue.hiddenLoading()
  return Promise.reject(error)
})

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  count--
  if (count === 0) {
    Vue.hiddenLoading()
  }
  return response
}, function (error) {
  // 对响应错误做点什么
  Vue.hiddenLoading()
  return Promise.reject(error)
})