Vue 组件开发的几种方式

序言

Vue 日常开发中模块化,组件化开发思想必不可少。 对于一些通用,常用及多次使用与某一处等场景,怎样的组件API设计及使用方式能更好的方便使用者快速使用。这里也许能给你一些参考。
拿Element UI 中的组件举例,主要结合了三中方式: 常规组件, Vue原型链组件, 指令/混淆组件。

常规组件

大多数开发场景下使用的方式: 通用性不是很高,与业务挂钩及个性化的关联较性强。 拆成组件方式主要是方便插拔,开发协作,模块化组织思想,提高可维护性等。

该方式较为常规,这里不在举例…

结合 Vue.prototype 组件

这种模式主要方便在Vue 项目中以类Vue API 的方式使用。 在组件数据交互及控制上显得更直观和简易。其结合了常规组件的基础上设计开发。
简例:

//  component name: Msg
  
  
// extend comp 
const installMsg = Vue.extend(Msg)// Msg = import Msg from '.../../Msg.vue'
$Msg = new installMsg({data:{isShow: false, }, el: xxxxx})
document.body.appendChild($Msg.$mount().$el)

let msgOpt = {
    show(){ $Msg.isShow = ture },
    hide(){$Msg.isShow = false}
}

if(!Vue.$msg) {
    Vue.$msg = msgOpt
}

Vue.prototype.$msg = Vue.$msg

// client use Msg by Vue Component
handleShowMsg (){
   this.$msg.show()/hiden()
}

结合 指令,mixin 组件

  • 通过指令directive允许我们在需要的组件便签上使用 ‘v-指令名’来控制及交互我们的组件
Loding....
  • 通过==mixin == 允许我们指定具体混淆到全局组件的某个具体位置(比如: created , beforeCreated等钩子函数初始化时)
    mixin 特点:
    *1. 优先级: 全局mixin, 局部mixin, 组件构造函数; *
    2. 相同钩子函数执行两边 ,mixin内的优先限执行;
    3. data 同名属性,同名时组件中的值优先级高;
    4. methods 内方法: 同名时则组件覆盖mixin 的方法;
 Vue.mixin({
    created() {
      this.$loading = Vue.$loading;
    }
  })

注: mixin 在vue中使用的是被混淆的对应钩子,被混入的组件如果存在相同属性等,则会被覆盖

实例:
组件部分代码



插件部分代码 directive.js:

import Vue from 'vue'
import Loading from './Loading'
const Mask = Vue.extend(Loading);

const loadingDirective = {};
loadingDirective.install = (Vue, options) => {
  let mask = new Mask({
    el: document.createElement('div'),
    data: {
      text: "你好...",
    }
  });

  // 指令在使用的时候对应要加  “v-指令名”
  Vue.directive('loading', {
    /* 
    el: 设置指令的对应标签dom
    binding: {
       name: "loading"
       rawName: "v-loading"
       value: true  // 使用指令是赋的值
       expression: "true"
       modifiers: {}
      def: {bind: ƒ, update: ƒ, unbind: ƒ}
    }
*/
    bind: (el, binding, vnode) => { // 指令与被绑定元素第一次绑定时触发,通常做一些事件监听的初始化
      console.log("bind():", el, binding, vnode, oldVnode);
      const vm = vnode.context;
      mask.visible = binding.value;
      el.instance = mask;
      el.mask = mask.$el;
      el.maskStyle = {};
      Vue.nextTick(() => {
        document.body.appendChild(mask.$mount().$el)
      })
    },
    update: (el, binding) => { // 被绑定元素内容发生变化时触发,可接受参数,在这里也可以进行事件监听的初始化
      console.log("update():", el, binding)
    },
    unbind: (el) => {  // 指令与元素解绑时触发,比如通过路由转跳页面时需要解绑指令
      console.log("unbind():", el, binding)
    },
  inserted: function () {},// 绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中)。
  componentUpdated: function () {},// 被绑定元素所在模板完成一次更新周期时调用。
  });

  let loading = {
    show() { mask.visible = true },
    hide() { mask.visible = false },
    setText(text){ mask.text = text}
  };

  if (!Vue.$loading) {
    Vue.$loading = loading;
  }

  Vue.mixin({
    created() {
      this.$loading = Vue.$loading;
    }
  })
};
export default loadingDirective; 

测试插件的使用

首先,在主入口文件间处 引入"directive.js" 并通过 Vue.use(Loading) 注册插件, 然后就可以在各个组件中使用了。




你可能感兴趣的:(VUE)