vue入门(六)可复用性&组合

一、混入

    一个混入对象可以包含任意组件选项,当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。

var myMixin = { ... }    //定义一个混入对象

var Component = Vue.extend({
    mixins:[myMixin]           //定义一个使用混入对象的组件
})

1、选项合并

    当组件和混入对象有同名选项时,选项将会合并,Vue.extend() 也使用同样的策略进行合并:

①数据会递归合并,发生冲突时以组件数据优先。

②同名钩子函数会合并成一个数组,所以都会被调用,且混入对象钩子先调用 

③值为对象的选项,如methodscomponents 和 directives,会被合并成一个对象,键名冲突时取组件的值。

2、全局混入

    混入也可全局注册,一旦使用全局混入,就会影响每一个之后创建的Vue实例。

3、自定义选项合并策略

    可以向Vue.config.optionMergeStrategies 添加一个函数:

Vue.config.optionMergeStrategies.myOption = function (toVal, fromVal) {
  // 返回合并后的值
}

二、自定义指令

1、注册全局指令

Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})

2、注册局部指令:组件中接收一个directives的选项

directives: {
  focus: {
    // 指令的定义
    inserted: function (el) {
      el.focus()
    }
  }
}             

可以在模板中的任何元素上使用指令自定义指令   <input v-focus>

3、钩子函数

一个指令定义对象可以提供以下几个钩子函数:

bind:只调用一次,第一次绑定到元素时调用

inserted:被绑定元素插入父节点时调用

updata:VNode更新时调用

componentUpdata:指令所在组件的VNode及其子VNode全部更新后调用

unbind:指令与元素解绑时调用

钩子函数参数(el,binding,vnode,oldVnode),除了el,其他都是只读

Vue.directive('demo', {            //demo指令名
  bind: function (el, binding, vnode) {           //bind函数
    var s = JSON.stringify
    el.innerHTML =
      'name: '       + s(binding.name) + '<br>' +       //bingding的属性name,指令名
      'value: '      + s(binding.value) + '<br>' +      //指令的绑定值
      'expression: ' + s(binding.expression) + '<br>' +  //字符串形式的指令表达式
      'argument: '   + s(binding.arg) + '<br>' +          //传给指令的参数
      'modifiers: '  + s(binding.modifiers) + '<br>' +    //包含修饰符的对象
      'vnode keys: ' + Object.keys(vnode).join(', ')
  }
})

4、动态指令参数

指令的参数可以是动态的。例如,在 v-mydirective:[argument]="value"中,argument 参数可以根据组件实例数据进行更新!

5、对象字面量

如果指令需要多个值,可以传入一个 JavaScript 对象字面量。

<div v-demo="{ color: 'white', text: 'hello!' }"></div>

三、渲染函数render&JSX

    在vue开发需要动态的生成页面,就是render函数,有时使用render比使用slot效率更高

Vue.component('anchored-heading', {
  render: function (createElement) {
    return createElement(
      'h' + this.level,   // 标签名称
      this.$slots.default // 子节点数组
    )
  },
  props: {
    level: {
      type: Number,
      required: true
    }
  }
})

1、渲染函数render

return createElement('h1',this,blogTitle)

createElement会返回一个createNodeDescription,包含需要渲染的节点和子节点描述,称为虚拟节点VNode

(1)createElement参数

({标签、组件选项对象、函数},{数据对象可选},{子级VNode可选})

数据对象,{'class’:{  },style:{   },attrs:{普通的HTML特性},props:{组件prop},domProps:{DOM属性},

on:{事件监听},directives:[{自定义指令}],...}

(2)约束

组件树中的所有 VNode 必须是唯一的。可以使用工厂函数来重复很多次元素/组件

render: function (createElement) {
  return createElement('div',
    Array.apply(null, { length: 20 }).map(function () {
      return createElement('p', 'hi')
    })
  )
}

(3)事件&按键修饰符

对于修饰符, 有前缀    可用于on

.passiv              &

.capture             !

.once                 ~

.caputure.once    ~!

(4)插槽

    可以通过this.$slots访问静态插槽的内容,每个插槽都是一个VNode数组

render: function (createElement) {
  // `<div><slot></slot></div>`
  return createElement('div', this.$slots.default)
}

也可以通过this.$scopeSlots访问作用域插槽,每个作用域插槽都是一个返回若干VNode的函数

props: ['message'],
render: function (createElement) {
  // `<div><slot :text="message"></slot></div>`
  return createElement('div', [
    this.$scopedSlots.default({
      text: this.message
    })
  ])
}

可以用VNode数据对象中的scopedSlots字段,用渲染函数向子组件传递作用域插槽

2、JSX

    Babel插件用于在Vue中使用JSX语法,

import AnchoredHeading from './AnchoredHeading.vue'

new Vue({
  el: '#demo',
  render: function (h) {        //h为createElement的别名
    return (
      <AnchoredHeading level={1}>
        <span>Hello</span> world!
      </AnchoredHeading>
    )
  }
})

3、函数式组件

    一个组件没有管理、监听状态,没有生命周期方法,只接受一些prop的函数,可标记为functional,函数式组件

Vue.component('my-component', {
  functional: true,    // Props 是可选的
  props: {    // ...  },
  render: function (createElement, context) {     }})

        在添加functional: true 之后,需要更新渲染函数,为其增加 context 参数,并将 this.$slots.default 更新为 context.children,然后将 this.level 更新为 context.props.level

四、插件

1、插件的功能:

①添加全局方法或者属性  ②添加全局资源   ③全局混入来添加一些组件选项  ④添加Vue实例方法

2、使用插件

    通过Vue.use( )使用插件,Vue.use(插件名,{可选的选项对象}),在调用new Vue()启动应用前完成。

Vue.use 会自动阻止多次注册相同插件。在webpack 提供的 CommonJS 模块环境中,应始终显式地调用 Vue.use()

3、开发插件

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

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

五、过滤器

过滤器可以用在两个地方:双花括号插值和 v-bind 表达式

可以在一个组件的选项中定义本地过滤器filters:{ },或者在创建Vue实例前全局定义过滤器Vue.filter( )

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

全局和局部过滤器重名时,采用局部过滤器。

过滤器函数总接收表达式的值 (之前的操作链的结果) 作为第一个参数。

过滤器可以串联{{ message | filterA | filterB }}     message传入过滤器A,再传入B

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值