Vue

vue优雅使用技巧(一)

2020-12-10  本文已影响0人  Raral

vue优雅使用

1. 高频组件全局引入

// 使用Vue.use()注入全局组件(高频出现)
import Vue from "vue";
import Child2 from "../components/child2"
import Child3 from "../components/child3"

let installComponents = [
    Child2,
    Child3
]

//将install函数挂在到对应得组件上
installComponents.map(component => {
   component.install = Vue => {
       Vue.component(component.name, component);
   }
})
//遍历使用Vue.use()
installComponents.map(component => {
    Vue.use(component);
})

//动态引入
//webpack  require.context
//1. 目标文件
//2. 是否匹配子目录
//3. 匹配什么类型文件
import Vue from "vue"

function changeStr(str) {
    return str.charAt(0).toUpperCase() + str.slice(1);
}
//是一个map对象 { "./child": 模块,"./child2": 模块 }
const requireCompoent = require.context(".",false,/\.vue$/);


requireCompoent.keys().forEach(fileName => {
    ////从 map对象 通过 filename找出对应的模块
    const config = requireCompoent(fileName);
    const componentName = changeStr(
        //将相对得目的文件 换成一个ps
        fileName.replace(/^\.\//,"").replace(/\.\w+$/, "")
    )
    Vue.component(componentName, config.default || config)
})

2. 通过指令权限控制到具体元素

//commom/array.js
//权限控制
export function checkArray(key) {
    //权限数组 
    let arr = [1,3,5,7,9];
    
    let index = arr.indexOf(key);
    if(index > -1) {
        return true
    }else {
        return false
    }
}
//main.js
import "./components/golbal.js"
Vue.config.productionTip = false
import { checkArray} from "./common/array.js"

//vue自定义指令
Vue.directive("permisson", {
    inserted(el,binding) {
        let displayKey = binding.value;
        if(displayKey) {
            let hasPermisson = checkArray(displayKey);
            if(!hasPermisson) {
                el.parentNode && el.parentNode.removeChild(el);
            }
        }else {
            throw new Error("need key!")
        }
    }
})

import { checkArray } from '@/common/array';

const permisson = {
    //被绑定的dom插入父节点时调用,必须保证父节点存在
    inserted:(el,binding,vnode, oldNode) => {
        let bindValue = binding.value;
        if(bindValue) {
            let hasPermisson = checkArray(bindValue);
            if(!hasPermisson) {
                el.parentNode && el.parentNode.removeChild(el);
            }

        }else {
            throw new Error("need directive params!!!")
        }
    }
}

export default permisson

src/directives/index.js

// 引入目录下指令文件
import Vue from "vue";
//方式1
import permisson from "./modules/permisson";
// import xxx from "./modules/v-xxx";

let directives = {
    permisson
}
//遍历使用Vue.use() 注册全局指令
Object.keys(directives).forEach(key => {
    Vue.directive(key,directives[key]);
})
 

可以通过require.context方法 优化

let requireDirective = require.context("./modules", true, /\.js$/);
requireDirective.keys().forEach(fileName => {
    //通过map对象的key 获取对应的模块
    let configModule = requireDirective(fileName);
    let directiveName = fileName.replace(/\.\//,"").replace(/\.js/, "");
    console.log(directiveName, configModule.default|| configModule);
    Vue.directive(directiveName, configModule.default|| configModule);
})

3. render函数应用 当组件的处理的判断逻辑繁多使用 render 方便维护


<script>
export default {
    props: {
        type: {
            type:String,
            default: "normal"
        },
        text: {
            type:String,
            default: "默认的"
        }
    },
    render: h => h( 
        "button",{
            class: {
                btn: true,
                "btn-sucess":this.type == "sucess",
                "btn-danger":this.type == "danger",
                "btn-warning":this.type == "warning", 
            },
            domProps: {
                innerHTML: this.text
            }
        }
    )
}
</script>
<style  scoped>
    .btn {
        width: 100px;
        height: 80px;
        background-color: #ffffff;
    }
    .btn-sucess {
        background-color: blue;
    }
    .btn-danger {
        background-color: red;
    }
    .btn-waring {
        background-color: yellow;
    }

</style>
 <ChildRender type="sucess" text="成功的"></ChildRender>
 <ChildRender type="danger" text="危险的"></ChildRender>

4. Vue.mixin和 Vue.extend()

Vue.mixin: 全局注册一个混入,会影响之后的创建的每一个Vue实例对象,谨慎使用全局混入!!!一般推荐使用局部混入。
场景:我们有一对组件, 例如 提示框和模态框,他们的样式不一样,用法不一样,但是他们的行为一样(都是需要显示和隐藏操作)

//mixins/toggle.js
import Modal from "@/views/Modal";
import Tip from "@/views/Tip";
import Vue from "vue";

export default {
    data() {
        return{
            isShowing: false
        }
    },
    methods: {
        show: function(msg,el) {
            // 通过Vue.extend() 返回一个vue的构造器
            const constructor = Vue.extend(Modal);
            //同构造器new 一个 Vue实例对象
            const vm = new constructor();
            
            //注入数据
            vm.$data.msg = msg;
            vm.$mount(el);
        }
    }
}

//指定的组件使用 App.vue
<button @click="show('提示信息2', $refs.cover)">mixin使用</button>
<br>
<div ref="cover">

</div>

深入理解混入和应用

Vue的混入 mixins

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

  1. 尽量使用局部混入
  2. 选项合并时,以当前组件为主合并

mixins理解

  1. 使用mixins 尽量 抽离vue组件中公共方法和公共数据;这也是 区别与 公共组件的特点,因为公共组件不仅可以抽离方法和数据还可以抽离公共的 模板结构
  2. mixins的数据和方法,在每一个组件中都是独立的,互不干扰的,都属于vue组件的自身; 这也是区别与vuex,因为所有的组件公用一个vuex状态管理器数据和方法

使用mixins优化

如果在某个场景下真的需要通过 mixin来抽离 一个组件的视图,数据,方法呢?
我们要用到一个vue.extend()方法来构建一个 模板;
场景:

  1. 使用mixins 实现 popup功能
  2. 判断当前页面或者按钮,是否登录过,如果没登陆,出现弹框;
  3. 比如在当前页面,突然加一个非业务功能需求(抢红包,抽奖,广告...等),我们都可以在当前页面所改的需求,封装成一个混入。这样可以灵活切换是否使用,代码容易维护。

万水千山总是情,点波关注行不行(●'◡'●)!!!

上一篇下一篇

猜你喜欢

热点阅读