# 封装和复用

# 插件

插件通常用来为 Vue 添加全局功能,插件的功能一般有下面几种

  1. 添加全局方法或属性
  2. 添加全局资源
  3. 通过全局混入来添加组件选项
  4. 添加实例方法
  5. 一个库,提供自己的 API

# 开发插件

Vue.js 的插件应该暴露一个install方法,这个方法的第一个参数是Vue构造器,第二个参数是一个可选的选项对象


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) {
    // 逻辑...
  }
}

# 混入

当组件使用混入对象时,所有混入对象的选项将混合进入该组件本身的选项

合并规则

数据对象会在内部进行递归合并,发生冲突时以组件数据优先 钩子函数会合并,但混入对象的钩子将在组件自身钩子之前调用

// 定义一个混入对象
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!"

# 指令

全局注册 Vue.directive()

// directive/index.js
// 注册一个全局自定义指令 `v-focus`
Vue.directive("focus", {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus();
  }
});

局部注册 directives 选项

// 某个组件内部 比如/components/demo/demo1.vue
directives: {
  focus: {
    // 指令的定义
    inserted: function (el) {
      el.focus()
    }
  }
}

# 指令生命周期

指令钩子函数
bind 绑定初始化时
inserted 被绑定元素插入父节点时
update 所在组件的 VNode 更新时,可能发生在其子 VNode 更新之前
componentUpdated 指令所在组件的 VNode 及其子 VNode 全部更新后
unbind 解除绑定时

# 钩子函数参数

  • el 所绑定元素的 DOM
  • binding 一个指令绑定的参数对象
    • name 指令的名称 例如 v-my-direct,指令名为my-direct
    • value 指令的绑定值 例如v-my-direct="1 + 1",绑定之为2
    • arg 传给指令的参数 例如 v-my-direct:foo,参数为foo
    • modifiers 一个包含修饰符的对象 例如v-my-direct:for.bar,修饰符对象对{bar:true}
  • vnode 虚拟节点
  • oldVnode 上一个虚拟节点

注意,除了el之外,其他参数都应该是只读的,切勿进行修改,如果需要共享数据,建议通过元素的dataset来进行

关于传参,如果指令需要多个值,可以传入一个 JavaScript 对象字面量。指令函数能够接受所有合法的 JavaScript 表达式。

<div v-demo="{ color: 'white', text: 'hello!' }"></div>
<button v-auth="['user_add']"></button>

# 过滤器

Vue.js 允许自定义过滤器,可用于一些常见的文本格式化,过滤器可以用在两个地方,双花括号插值和v-bind表达式,过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示;

比如下面这个首字母大写过滤器

Vue.filter("capitalize", function (value) {
  if (!value) return "";
  value = value.toString();
  return value.charAt(0).toUpperCase() + value.slice(1);
});