Vue -- 可复用性

混入

  • 通过mixins属性增加混入对象,格式为[变量名]。data以及值为对象的methods、components等会自动合并属性,相同则覆盖;钩子会合并,混入对象的钩子先执行。
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 Component = Vue.extend({
  mixins: [myMixin]
})
var component = new Component() // => "hello from mixin!"
  • 也可以全局定义混入对象,但会影响所有的实例,慎用。
// 为自定义的选项 'myOption' 注入一个处理器。
Vue.mixin({
  created: function () {
    var myOption = this.$options.myOption
    if (myOption) {
      console.log(myOption)
    }
  }
})

自定义指令

  • 类似v-model和v-show,我们也可以自定义指令。(全局注册一般是Vue.命令名,局部是命令名s)。
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})
// 或者局部注册
directives: {
  focus: {
    // 指令的定义
    inserted: function (el) {
      el.focus()
    }
  }
}


  • 一个指令定义对象可以提供如下几个钩子函数 (均为可选):
    1. bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
    2. inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
    3. update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
    4. componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
    5. unbind:只调用一次,指令与元素解绑时调用。
  • 指令钩子函数会被传入以下参数(除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset来进行):
    1. el:指令所绑定的元素,可以用来直接操作 DOM 。
    2. binding:一个对象,包含以下属性:
    *   `name`:指令名,不包括 `v-` 前缀。
    *   `value`:指令的绑定值,例如:`v-my-directive="1 + 1"` 中,绑定值为 `2`。
    *   `oldValue`:指令绑定的前一个值,仅在 `update` 和 `componentUpdated` 钩子中可用。无论值是否改变都可用。
    *   `expression`:字符串形式的指令表达式。例如 `v-my-directive="1 + 1"` 中,表达式为 `"1 + 1"`。
    *   `arg`:传给指令的参数,可选。例如 `v-my-directive:foo` 中,参数为 `"foo"`。
    *   `modifiers`:一个包含修饰符的对象。例如:`v-my-directive.foo.bar` 中,修饰符对象为 `{ foo: true, bar: true }`。
    
    1. vnode:Vue 编译生成的虚拟节点。
    2. oldVnode:上一个虚拟节点,仅在 updatecomponentUpdated 钩子中可用。
  • 函数简写:如果想要在 bind 和 update 时触发相同行为,而不关心其它的钩子,可以如下写法:
Vue.directive('color-swatch', function (el, binding) {
  el.style.backgroundColor = binding.value
})
  • 指令可以传入任意合法的js表达式,如对象字面量。
Vue.directive('demo', function (el, binding) { console.log(binding.value.color) // => "white" console.log(binding.value.text) // => "hello!" })

渲染函数

  • render可以用js来写模板语法,如下面用level来拼接标签名,用template是做不到的。
Vue.component('anchored-heading', {
  render: function (createElement) {
    return createElement(
      'h' + this.level,   // tag name 标签名称
      this.$slots.default // 子组件中的阵列
    )
  },
  props: {
    level: {
      type: Number,
      required: true
    }
  }
})

等同于如下,即用render替换了template:

Vue.component('anchored-heading', {
  template: '#anchored-heading-template',
  props: {
    level: {
      type: Number,
      required: true
    }
  }
})

  • createElement(dom, descriptorObj, childNode)第一个参数是最终的节点(可以为字符串/对象/异步函数);第二个参数是对节点的描述属性对象,可描述样式或attrs/on等(只能是对象);第三个是子节点(可以为字符串/数组)。其中他们的用到的Vnode也是createElement生成的。返回的都是虚拟节点(准确来说是虚拟节点的描述对象)。
  • this.$slot可以用作createElement第三个参数表示插入插槽,.default获取匿名插槽,.name获取具名插槽;this.$scopedSlots可以指定属性描述对象。
render: function (createElement) {
  // `
` return createElement('div', this.$slots.default) } props: ['message'], render: function (createElement) { // `
` return createElement('div', [ this.$scopedSlots.default({ text: this.message }) ]) } render: function (createElement) { return createElement('div', [ createElement('child', { // pass `scopedSlots` in the data object // in the form of { name: props => VNode | Array } scopedSlots: { default: function (props) { return createElement('span', props.text) } } }) ]) }

插件

  • vue可以通过全局的四种方法来开发插件,插件应当有一个公开的install方法:
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) {
    // 逻辑...
  }
}
  • 插件通过全局方法Vue.use(MyPlugin, { someOption: true })来调用,第二个参数可选。Vue.use 会自动阻止多次注册相同插件,届时只会注册一次该插件。

过滤器

  • {{ message | filterA | filterB }}将message作为filterA的参数,然后将filterA的结果作为filterB的参数;或者{{ message | filterA('arg1', arg2) }}传入三个参数。

你可能感兴趣的:(Vue -- 可复用性)