Vue基础知识—7.可复用性

7.1过滤器

过滤器常用在两个地方的后面:双括号插值和v-bind表达式(2.1.0+支持)

<!-- 在双花括号中-->
{{message|capitalize}}
<!--在v-bind中 -->
<div v-bind:id="rawId|formatId"></div>
<template>
  <div id="ReusableComponent">
    <!-- 过滤器 -->
    {{price|currency('RMB')}}
  </div>
</template>


<script>
export default {
  name:"ReusableComponent",
  data(){
    return{
      price:88
    }
  },
  filters:{
    currency(value,Symbol='¥'){
      return Symbol+value
    }
  }
}
</script>

<style scoped>

</style>

7.2自定义组件

除了核心功能默认内置的指令 ( v-model 和 v-show ),Vue 也允许注册自定义指令。注意,在 Vue2.0中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。

<template>
<!-- 可复用性 -->
  <div id="ReusableComponent">
    <!-- 输入时获取焦点 -->
    <input v-focus>
    <!-- 权限控制 -->
    <div class="toolbar" v-permission="'admin'"></div>
  </div>
</template>

<script>
import Vue from 'vue'
Vue.directive('focus',{
  inserted(el){
    el.focus()
  }
})
const role = "admin"
Vue.directive('permission',{
  inserted(el){
    if(role!=='admin'){
      el.parentElement.removeChild(el)
    }
  }
})
export default {
  name:"ReusableComponent",
  data(){
    return{
    }
  }
}
</script>

<style scoped>

</style>

7.3渲染函数

Vue推荐在绝大多数情况下使用模板来创建你的HTML,然而在一些场景中,需要Javascript的编程能力。这时,你可以使用渲染函数,它比模板更接近编译器

7.3.1 基础

render:function(createElement){
    //createElement函数返回结果是VNode
    return CreateElement(
        tag,//标签名称
        data,//传递数据
        children//子节点数组
    )
}


<template>
<!-- 可复用性 -->
  <div id="ReusableComponent">
    <!-- 利用render实现heading组件 -->
    <heading level="1" title="标题" />
  </div>
</template>

<script>
import Vue from 'vue'

Vue.component('heading',{
  props:['level','title'],
  render(h){
    console.log(this.level)
    return h(
      'h'+this.level,
       this.title
    )
  }
})

export default {
  name:"ReusableComponent",
  data(){
    return{
    }
  }
}
</script>

<style scoped>

</style>

7.3.2 虚拟DOM

Vue通过建立一个虚拟Dom来追踪自己要如何改变真实的Dom

const vnode = h(
    'h' + level,
    { attrs: { title: this.title } },
    this.$slots.default
)
console.log(vnode)

7.3.3 createElement参数

createElement可接受的参数

// @returns {VNode}
createElement(
    // {String | Object | Function}
    // 一个 HTML 标签名、组件选项对象,或者
    // resolve 了上述任何一种的一个 async 函数。必填项。
    'div',
    // {Object}
    // 一个与模板中属性对应的数据对象。可选。
    {
    // (详情见下一节)
    },
    // {String | Array}
    // 子级虚拟节点 (VNodes),由 `createElement()` 构建而成,
    // 也可以使用字符串来生成“文本虚拟节点”。可选。
    [
    '先写一些文字',
    createElement('h1', '一则头条'),
    createElement(MyComponent, {
        props: {
            someProp: 'foobar'
        }
    })
    ]
)
Vue.component('heading', {
    props: ['level', 'title', 'icon'],
    render(h) {
        let children = [];
        // 添加图标功能
        // <svg><use xlink:use="#icon-xxx"></use></svg>
        if (this.icon) {
            children.push(h(
            'svg',
            { class: 'icon' },
            [h('use', { attrs: { 'xlink:href': '#icon-' + this.icon } })]))
            children = children.concat(this.$slots.default)
        }
        vnode = h(
        'h' + level,
        { attrs: { this.title } }, // 之前省略了title的处理
        children
        )
        console.log(vnode);
        return vnode
    }
})

7.3.4 函数式组件

组件没有管理任何状态,也没有监听任何传递给它的状态,也没有生命周期方法时,可以将组件标记为functional,这意味它无状态(没有响应数据),也没实例(没有this上下文)

Vue.component('heading',{
    functional:true,//标记函数式组件
    props:['level','title','icon'],
    render(h,context){//上下文参数
        let children =[];
        //属性获取
        const {icon,title,level}=context.props
        if(icon){
            children.push(h(
                'svg',
                {class:'icon'},
                [h('use',{attrs:{
                    'xlink:href':'#icon-'+icon
                }})]
            ))
            //子元素获取
            children = children.concat(context.children)
        }
        vnode = h(
            'h'+level,
            {attrs:{title}},
            children
        )
        console.log(vnode);
        return vnode;
    }
})

7.4混入

混入(mixin)提供了一种非常灵活的方式,来分发Vue组件中的可复用功能,一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象选项将被"混合"进入该组件本身的选项
//混入对象

var MyMixin = {
  created:()=>this.hello(),
  methods:{
    hello:()=>console.log("hello from mixin!")
  }
}

//定义一个使用混入对象的组件

Vue.component('comp',{
  minxis:[MyMixin]
})

7.5插件

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

  1. 添加全局方法或者属性。如: vue-custom-element
  2. 添加全局资源:指令/过滤器/过渡等。如 vue-touch
  3. 通过全局混入来添加一些组件选项。如 vue-router
  4. 添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
  5. 一个库,提供自己的 API,同时提供上面提到的一个或多个功能。如 vue-router

7.5.1 插件声明

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

MyPlugin.install = function (Vue, options) {
    // 1. 添加全局方法或属性
    Vue.myGlobalMethod = function () {}
    // 2. 添加全局资源
    Vue.directive('my-directive', {})
    // 3. 注入组件选项
    Vue.mixin({
        created: function () {
        // 逻辑...
        }
    })
    // 4. 添加实例方法
    Vue.prototype.$myMethod = function (methodOptions) {}
}

例子

const MyPlugin = {
    install (Vue, options) {
        Vue.component('heading', {...})
    }
}
if (typeof window !== 'undefined' && window.Vue) {
    window.Vue.use(MyPlugin)
}

7.5.2 插件使用

使用Vue.use即可引入插件

Vue.use(MyPlugin)

版权声明:本文为JYB150740115原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。