美文网首页Vue
vue优雅使用技巧(一)

vue优雅使用技巧(一)

作者: Raral | 来源:发表于2020-12-10 15:25 被阅读0次

    vue优雅使用

    1. 高频组件全局引入

    • 使用Vue.use()方法
      弊端: 需要多次import 引入组件
    // 使用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);
    })
    
    
    • 使用require.context方法
    //动态引入
    //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. 通过指令权限控制到具体元素

      1. 全局指令在入口文件定义
    //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!")
            }
        }
    })
    
    
      1. 通过Vue.use() 注入 多个全局的指令
        src/directives/modules/permission.js
    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 方便维护

    • 使用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. 比如在当前页面,突然加一个非业务功能需求(抢红包,抽奖,广告...等),我们都可以在当前页面所改的需求,封装成一个混入。这样可以灵活切换是否使用,代码容易维护。

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

    相关文章

      网友评论

        本文标题:vue优雅使用技巧(一)

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