美文网首页
Vue -- 可复用性

Vue -- 可复用性

作者: Da_xiong | 来源:发表于2018-10-21 22:53 被阅读0次

    混入

    • 通过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()
        }
      }
    }
    
    <input v-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表达式,如对象字面量。
    <div v-demo="{ color: 'white', text: 'hello!' }"></div>
    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
        }
      }
    })
    <script type="text/x-template" id="anchored-heading-template">
      <h1 v-if="level === 1">
        <slot></slot>
      </h1>
      <h2 v-else-if="level === 2">
        <slot></slot>
      </h2>
      <h3 v-else-if="level === 3">
        <slot></slot>
      </h3>
      <h4 v-else-if="level === 4">
        <slot></slot>
      </h4>
      <h5 v-else-if="level === 5">
        <slot></slot>
      </h5>
      <h6 v-else-if="level === 6">
        <slot></slot>
      </h6>
    </script>
    
    • createElement(dom, descriptorObj, childNode)第一个参数是最终的节点(可以为字符串/对象/异步函数);第二个参数是对节点的描述属性对象,可描述样式或attrs/on等(只能是对象);第三个是子节点(可以为字符串/数组)。其中他们的用到的Vnode也是createElement生成的。返回的都是虚拟节点(准确来说是虚拟节点的描述对象)。
    • this.$slot可以用作createElement第三个参数表示插入插槽,.default获取匿名插槽,.name获取具名插槽;this.$scopedSlots可以指定属性描述对象。
    render: function (createElement) {
      // `<div><slot></slot></div>`
      return createElement('div', this.$slots.default)
    }
    
    props: ['message'],
    render: function (createElement) {
      // `<div><slot :text="message"></slot></div>`
      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<VNode> }
          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 -- 可复用性

          本文链接:https://www.haomeiwen.com/subject/uzosvftx.html