• vue-day05----自定义指令(directive)、render和template的区别、mixin混入、Vue.use()、Vue.extend()、Vue.filter()、vue中的数据流向


    ### 自定义指令  directive

        全局自定义指令:Vue.directive()
        局部自定义指令:directives
        directive(参数一,参数二)
            参数一:指令名称
            参数二:指令的配置项,可以是函数,也可以是对象
                函数:
                    参数一:使用当前指令的元素
                    参数二:指令的详细信息
                        {
                            modifiers:修饰符(只要自定义指令后面跟了修饰符,modifiers对象中就有值,为true),
                            value:指令的值(假设指令这样写:<div v-test="'aaa'"></div>,那么value就是aaa)
                        }
                        
        
        指令的作用:操作DOM元素
        步骤:
            ①src下新建utils/utils.js:
    import Vue from "vue";
    
    /**
     *  v-test指令:
     *      <div v-test="'发发发'"></div>
     *      相当于
     *      <div>发发发</div>
     * 
     */
    Vue.directive("test",(el,{value})=>{
        el.innerText=value;
    });
    
    /**
     *  设置背景颜色的指令 
     * 
     */
    Vue.directive("backgroundColor",(el,{value,...rest})=>{
        el.style.backgroundColor=value;
    });
    
    /**
     *  阻止浏览器默认事件:v-event.prev
     * 
     */
    Vue.directive("event",(el,{modifiers})=>{
        let {prev}=modifiers;
        el.addEventListener("contextmenu",(e)=>{
            if(prev){
                e.preventDefault();
            }
        });
    });
    
    /**
     *  自动聚焦
     * 
     */
    Vue.directive("focus",{
        // 获取光标在inserted中操作,此时元素已经插入到父节点了
        inserted(el){
            el.focus();
        }
    });
    
    /**
     *  第一个参数是指令名称,第二个参数如果是一个函数,这个函数是指令要做的事情,如果是一个对象,这个对象是指令的配置项。
     * 
     * 
     */
    Vue.directive("wql",{
        bind(){ 
            // 当前元素使用当前指令的时候会被调用,只会调用一次,用来做初始化
            console.log("bind")
        },
        inserted(){
            // 当使用指令的元素被插入到父节点(#app)的时候会被触发
            console.log("inserted")
        },
        update(){
            // 只要当前元素不被移除,其他操作几乎都会触发这2个生命周期,先触发update后触发componentUpdate
            // 虚拟DOM只要涉及到元素的隐藏、显示(display)值的改变、内容的改变等都会触发虚拟DOM更新
            console.log("update")
        },
        componentUpdated(){
            console.log("componentUpdate")
        },
        unbind(){
            // 当只用指令的元素被卸载的时候会执行,简单的说就是当前元素被移除的时候
            console.log("unbind")
        }
    });
    
    
    /**
     *  v-drag
     * 
     */
    Vue.directive("drag",(el,{modifiers,value})=>{
        if(value){
            var disX,disY;
            var {l,t} = modifiers;
            el.style.position = "absolute";
            el.addEventListener("mousedown",mousedown)
            function mousedown(e){
                disX = e.offsetX;
                disY = e.offsetY;
                document.addEventListener("mousemove",move)
                document.addEventListener("mouseup",up)
            }
            function move(e){
                var x = e.clientX - disX;
                var y = e.clientY - disY;
                if((l&&t) || (!l&&!t)){
                     el.style.left = x + 'px';
                     el.style.top = y + 'px';
                     return;
                }
                if(l){
                    el.style.left = x + 'px';
                     return;
                }
                if(t){
                    el.style.top = y + 'px';
                     return;
                }
            }
            function up(){
                document.removeEventListener("mousemove",move)
                document.removeEventListener("mouseup",up)
            }
        }
    });
            ②main.js中引入:
                import "./utils/utils.js";
            ③App.vue中使用自定义指令:
                <div v-test="'发发发'" v-backgroundColor.not="'blue'"></div>
                <div v-test="'阻止浏览器默认事件'" v-backgroundColor="'yellow'" v-event.prev></div>
                <input type="text" v-focus>
        指令的生命周期:
            bind():当元素只用当前指令的时候会被调用,只会调用一次,用来做初始化
     
            inserted():当使用指令的元素被插入到父节点(#app)的时候会被触发
     
            update():只要当前元素不被移除,其他操作几乎都会触发这2个生命周期,先触发update后触发componentUpdate。虚拟DOM什么时候更新:只要涉及到元素的隐藏、显示(display)值的改变、内容的改变等都会触发虚拟DOM更新
     
            componentUpdate():组件更新
     
            unbind():当使用指令的元素被卸载的时候会执行,就是当前元素被移除的时候

    ### render和template的区别

        template----html的方式做渲染
        render----js的方式做渲染
     
        render(提供)是一种编译方式
        render里有一个函数h,这个h的作用是将单文件组件进行虚拟DOM的创建,然后再通过render进行解析。
        h就是createElement()方法:createElement(标签名称,属性配置,children)
     
        template也是一种编译方式,但是template最终还是要通过render的方式再次进行编译。
     
        区别:
            1、render渲染方式可以让我们将js发挥到极致,因为render的方式其实是通过createElement()进行虚拟DOM的创建。逻辑性比较强,适合复杂的组件封装。
            2、template是类似于html一样的模板来进行组件的封装。
            3、render的性能比template的性能好很多
            4、render函数优先级大于template

    ### mixin   混入

        通过mixins引入组件后,会给当前组件额外扩展一些属性和方法,简单的说就是给组件额外添加了一个BUFF
     
        封装插件的时候用mixin
     
        mixin----全局使用
        mixins----局部使用
     
        步骤:
            ①utils下新建mixin.js:
                export default {
                    // new Vue()中的配置项都可以在这里加
                    data(){
                        return{
                            title:"我是额外提供的一个属性"
                        }
                    },
                    created() {
                        console.log("我是一个buff")
                    }
                }
            ②App.vue中引入:
                import Mixin from "./utils/mixin.js";
            ③添加mixins属性:
                mixins:[Mixin],
            此时在created中就多一个console.log打印,在App.vue页面可以直接使用title属性,就和写在自己的data中一样。

    ### Vue.use()

        Vue.use()是用来使用插件的,当前插件如果导出的是一个函数,那么这个函数就会被当做install方法。如果当前插件导出的是一个对象,那么这个对象必须提供一个install方法,因为Vue.use()在使用这个插件的时候会给install方法提供一个Vue构造函数。
     
        注:所有的插件都创建了一个install方法,再将install方法导出。
     
        使用场景:如果在编写插件的时候通过外部的方式来引入Vue的时候会使这个插件变得特别大,此时需要用到Vue.use(),它的作用就是给插件传递一个vue。
     
        步骤:
            ①src下新建plugins/wql.js:
                // 如果导出一个函数,这个函数会被当做是install方法,同时Vue.use()会给这个函数传递Vue的构造函数,不用引入直接就有
                // export default (Vue)=>{
                //     console.log(Vue)
                // }
    
                // 如果导出一个对象,这个对象必须要提供install方法,同时Vue.use()会给这个方法传递Vue的构造函数
                export default {
                    install(Vue){
                        console.log(Vue)
                    }
                }
            ②main.js中引入并使用wql.js:
                import wql from "./plugins/wql.js";
                Vue.use(wql); // 打印vue的构造函数

    ### Vue.extend()

        作用:让编写好的组件可以当成方法使用,就是将ui组件转换为js组件。
        步骤:
            ①src下新建publics/index.vue和publics/index.js文件:
                在index.vue中写好组件,在index.js中引入再通过Vue.extend()继承,转换成js组件
                import messageBox from "./index.vue";
                import Vue from 'vue';
                // options对象是Message()中的参数对象
                export default (options)=>{
                    // 继承Vue,将js对象来继承Vue,来转换成js组件,这个js组件可以被放在页面的任何地方
                    let MessageBox=Vue.extend(messageBox);
                    let vmMessage=new MessageBox({
                        el:document.createElement("div"),
                        // 这里是继承的Vue,所以有和vue一样的配置项,可以写data、methods、生命周期...
                    }
                    // $mount()返回一个对象,其中有$el,$el就是赋给el的div
                    document.body.appendChild(vmMessage.$mount().$el);
                }
            ②main.js中引入并使用:
                import Message from "./plugins/message/index.js";
                Vue.use(Message);
                此时页面上就已经显示了组件,因为install方法是自动执行的。
     
            ③不在main.js中引入,直接在需要使用的组件(App.vue)中引入:
                import Message from "./plugins/message/index.js";
                然后在created()中执行 Message(); 就会在页面上显示出来,Message()中可以写一个{},将属性和方法传递给options。
     

    ### Vue.filter()

        作用:过滤数据
     
        语法:
            全局:
                Vue.filter("过滤器名",(参数一,参数二)=>{});
                    参数一:需要过滤的数据
                    参数二:传递的数据
     
            局部:
                filters:{
                    过滤器名(){
     
                    }
                }
        
        使用:{{username|过滤器名()}}
     
        步骤:
        (1)时间过滤器
            ①声明一个全局过滤器
                Vue.filter("date",(data,icon)=>{
                    let year=(new Date(data)).getFullYear();
                    let month=(new Date(data)).getMonth()+1;
                    let day=(new Date(data)).getDate();
                    var icon=icon||"/";
                    return `${year}${icon}${month}${icon}${day}`; 
                });
            ②实例中设置一个time:
                let vm=new Vue({
                    el:"#app",
                    data:{
                        time:(new Date()).getTime()
                    }
                });
            ③管道符进行使用:
                {{time|date("-")}}
        (2)图片尺寸过滤器
            ①data中将imgUrl引入:
                data(){
                    return{
                        imgUrl:"http://p0.meituan.net/w.h/movie/2c24eb6a84a92b9ba837967851bec9462844109.jpg"
                    }
                }
            ②声明局部filters:
                filters:{
                    imgReplace(data,wh){
                        // 将字符串 "w.h" 替换为 "170.280"
                        return data.replace(/w.h/,wh);
                    }
                }
            ③页面中使用:
                <img :src="imgUrl|imgReplace('170.280')">

     

    ### Question:

    vue中组件通讯的数据流向?

        在组件通讯的时候数据的流向是单向数据流。
     
        在组件通信的时候父组件传递给子组件的状态,子组件只允许做访问,不能做修改。如果需要做修改则需要在自己内部保存一份再进行修改。因为如果子组件改变了父组件的状态,会导致数据流难以理解。































  • 相关阅读:
    51nod乘积之和
    Dell服务器安装OpenManage(OMSA)
    Nginx反向代理PHP
    搭建haproxy
    108. Convert Sorted Array to Binary Search Tree
    60. Permutation Sequence
    142. Linked List Cycle II
    129. Sum Root to Leaf Numbers
    118. Pascal's Triangle
    26. Remove Duplicates from Sorted Array
  • 原文地址:https://www.cnblogs.com/wuqilang/p/12359571.html
Copyright © 2020-2023  润新知