1. 程式人生 > >vue學習(二) vue生命週期 vue自定義指令和過濾器

vue學習(二) vue生命週期 vue自定義指令和過濾器

生命週期鉤子函式

vue的生命週期圖示

這裡寫圖片描述

vue的幾個鉤子函式

直接程式碼展示:

    <div id="box">
        {{msg}}
    </div>
    <script>
        var vm = new Vue({
            el : "#box",
            data : {
                msg : "welcome vue",
            },
            // 在例項開始初始化時同步呼叫。此時資料觀測、事件和 watcher 都尚未初始化。
init : function (){ alert("例項初始化") }, //在例項建立之後同步呼叫。 //此時例項已經結束解析選項,這意味著已建立:資料繫結,計算屬性,方法,watcher/事件回撥。 //但是還沒有開始 DOM 編譯,$el 還不存在。 created : function (){ alert("建立vue物件了") }, //在編譯開始前呼叫。
beforeCompile : function (){ alert("編譯前...."); }, //在編譯結束後呼叫。此時所有的指令已生效,因而資料的變化將觸發 DOM 更新。但是不擔保 $el 已插入文件。 compiled : function (){ alert("編譯完成..."); }, //在編譯結束和 $el 第一次插入文件之後呼叫,如在第一次 attached 鉤子之後呼叫。
//注意必須是由 Vue 插入(如 vm.$appendTo() 等方法或指令更新)才觸發 ready 鉤子。 ready : function (){ alert("插入到文件中..."); }, //在開始銷燬例項時呼叫。此時例項仍然有功能。 beforeDestroy : function (){ alert("銷燬前...."); }, //在例項被銷燬之後呼叫。此時所有的繫結和例項的指令已經解綁,所有的子例項也已經被銷燬。 //如果有離開過渡,destroyed 鉤子在過渡完成之後呼叫。 destroyed : function (){ alert("銷燬了..."); } }); document.onclick = function (){ vm.$destroy(); }
</script>

結果顯示是:

    alert("例項初始化")  —> alert("建立vue物件了") —> alert("編譯前....") —>alert("編譯完成...")  —>alert("插入到文件中...") 

    判斷使用者是否點選了文件   是:alert("銷燬前....")—>alert("銷燬了...")

計算屬性的使用(computed)

    <div id="box1">
        <p>a => {{a}}</p>
        <br>
        <p>b => {{b}}</p>
        <br>
    </div>
    <script>
        var vm = new Vue({
            el : "#box1",
            data : {
                a: 1,
            },
            computed : {
                b : function (){
                    return this.a+1;
                },
                c : function (){
                    return 20;
                }
            }
        });
        document.onclick = function (){
            vm.a=100;
        }
    </script>

效果:

這裡寫圖片描述

增加get set

    <div id="box1">
        <p>a => {{a}}</p>
        <br>
        <p>b => {{b}}</p>
        <br>
    </div>
    <script>
        var vm = new Vue({
            el : "#box1",
            data : {
                a: 1,
            },
            computed : {
                b : {
                    get : function (){
                        return this.a+1;
                    },
                    set : function (val){
                        this.a=val;
                    }
                }
            }
        });
        document.onclick = function (){
            vm.b=10;
        }
    </script>

PS:computed裡面可以放置一些業務邏輯程式碼,一定記得return

vue例項的簡單方法

  • vm.$el -> 就是元素

  • vm.$data -> 就是data

  • vm.$mount -> 手動掛在vue程式

  • vm.$options -> 獲取自定義屬性

  • vm.$destroy -> 銷燬物件

  • vm.$log(); -> 檢視現在資料的狀態

#

eldata

    <div id="box1">
        <p>a => {{a}}</p>
        <br>
    </div>
    <script>
        var vm = new Vue({
            el : "#box1",
            data : {
                a: 1,
            }
        });
        document.onclick = function (){
            // 通過$el來獲取到對應的元素
            vm.$el.style.background="red";
        }
        console.log(vm.$data.a); // 通過$data來獲取相對應的資料裡面的某個值
        console.log(vm.a);  // 可以直接通過  物件.資料  來獲取也ok
        console.log(vm.$data.a===vm.a); // true  這兩種方式獲取的資料是一樣的

    </script>

$mount

<div id="box1">
        <p>a => {{a}}</p>
        <br>
    </div>
    <script>
        // 之前是通過 el:;的形式來掛載vue程式,現在通過$mount的形式來實現掛載,
        var vm = new Vue({
            // el : "#box1", //這裡手動掛載vue程式
            data : {
                a: 1,
            }
        }).$mount("#box1");
    </script>

optionsdestroy 銷燬物件

    <div id="box1">
        <p>屬性a => {{a}}</p>
        <br>
        <p>自定義屬性aa => {{vm.$options.aa}}</p>
        <br>
        <p>自定義屬性bb => {{vm.$options.bb}}</p>
        <br>
        <p>自定義屬cc => {{vm.$options.cc}}</p>
        <br>
    </div>
    <script>
        //
        var vm = new Vue({
            el : "#box1",
            data : {
                a: 1,
            },
            show : function (){
                alert("This is options made by myself.")
            },
            aa : 123,
            bb : 'abc',
            cc : true,
        });
        //獲取自定義屬性
        console.log(vm.$options.aa)
        console.log(vm.$options.bb)
        console.log(vm.$options.cc)
        vm.$options.show();
        document.onclick = function (){
            alert(vm)
            // 銷燬物件
            vm.$destroy();
            alert(vm)
        }
        document.ondbclick = function (){
            console.log(vm);
        }
    </script>


$log 獲取當前的資料狀態

<div id="box1">
        <p>屬性a => {{a}}</p>
        <br>
        <button @click="show()">clickMe</button>
    </div>
    <script>
        //
        var vm = new Vue({
            el : "#box1",
            data : {
                a: 1,
                b:2,
                c:3
            },
            methods: {
                show : function (){
                    this.a=100
                },
            },
            aa : 123,
            bb : 'abc',
            cc : true,
        });
        document.onclick = function (){
            console.log(vm.$log());
        }
    </script>

這裡寫圖片描述

迴圈補充

    <div id="box1">
        <input type="button" value="add" @click='add()' />
        <ul>
            <li v-for="val in arr">{{val}}</li>
        </ul>
    </div>
    <script>
        // 此時點選btn 控制檯會報錯 資料重複的問題
        var vm = new Vue({
            el : "#box1",
            data : {
                arr: ['apple','orange','pear'],
            },
            methods : {
                add : function (){
                    this.arr.push('banana');
                }
            }
        });
    </script>

這裡寫圖片描述

除錯:加上 track-by

    track-by='索引'   提高迴圈效能
    track-by='$index/uid'
    <div id="box1">
        <input type="button" value="add" @click='add()' />
        <ul>
            <li v-for="val in arr" track-by='$index'>{{val}}</li>
        </ul>
    </div>
    <script>
        // 此時點選btn 控制檯會報錯 資料重複的問題
        // 加上 track-by 避免了之前的問題
        var vm = new Vue({
            el : "#box1",
            data : {
                arr: ['apple','orange','pear'],
            },
            methods : {
                add : function (){
                    this.arr.push('banana');
                }
            }
        });
    </script>

自定義過濾器

格式:

    當有多個引數的情況下,用空格隔開就好
    Vue.filter(filterName ,function(input){
        // fn
    });

    呼叫: {{msg | filterName ‘c1’ ‘c2’}}
    <div id="box1">
        {{aa}}
        <br>
        {{sum | addZero}}
        <br>
        {{date| toDate}}
        <br>
        {{msg | filterHtml}}
    </div>
    <script>
        Vue.filter('addZero',function (val){
            return val<10?'0'+val:val;
        })
        // Vue 自定義過濾器方式2 帶有多個引數的 
        // Vue.filter(filterName,fn)
        Vue.filter('addZero',function (val,c1,c2){
            if (c1 || c2) alert(c1+'----'+c2)
            return val<10?'0'+val:val;
        })

        //日期格式
        Vue.filter('toDate',function (val){
            var oDate = new Date(val);
            return oDate.getFullYear()+'/'+(oDate.getMonth()+1)+'/'+oDate.getDate()+'  '+ oDate.getHours()+':'+oDate.getMinutes()+':'+oDate.getSeconds()
        })

        //過濾html
        Vue.filter('filterHtml',function (val){
            return val.replace(/<[^<]+>/g,'');
        })
        var vm = new Vue({
            el : "#box1",
            data : {
                arr: ['apple','orange','pear','banana','age'],
                sum: 20,
                date : Date.now(),
                msg : '<strong>welcome</strong>'
            },
            methods : {
                add : function (){
                    alert(111)
                }
            }
        });
    </script>

自定義指令

自定義屬性指令

Vue.directive('name',function (){
    fn
})

在呼叫自定義屬性指令的情況下,要加上  ‘v-’
<div v-directName></div>
<div v-directName="canshu"></div>

democode

<div id="box1">
        <p v-read>{{data}}</p>
        <p v-blue="'green'">{{data}}</p>
        <p v-blue="green">{{data}}</p>
        <p v-blue="color">{{data}}</p>

        // 引數不止一個的情況下
        <p v-read="{bgColor:'blue',fontColor:'#fff'}">{{data}}</p>
    </div>
    <script>
        // 引數傳遞,引數個數是零個的時候————直接把指令寫上去
        // 引數傳遞,引數個數是一個的時候————v-blue=" '引數' "   引數可以是字串,也可以是vue裡的資料
        // 注意區分 引數是多個的情況,看下一個demo
        Vue.directive('read',function (){
            this.el.style.background="red";
        })
        Vue.directive('blue',function (c1){
            this.el.style.background=c1;
        })

        // 傳參 的問題???
        // 當引數不止一個的時候,把引數以json的形式寫進去,然後在方法中進行操作呼叫
        Vue.directive('read',function (c1){
            this.el.style.background=c1.bgColor;
            this.el.style.color=c1.fontColor;
            console.log(c1)
        })
        var vm = new Vue({
            el : "#box1",
            data : {
                data : 'new data',
                color: '#eee',
                green: 'pink'
            },
            methods : {
                //
            }
        });

自定義指令還有另外一種方式,通過在fn裡面定義 bind unbind

    <div id="box1">
        <p v-read>{{data}}</p>
    </div>
    <script>
        Vue.directive('read',{
            bind: function () {
                this.el.style.background="red";
            },
            unbind:function(){
                //
            }
        })

        var vm = new Vue({
            el : "#box1",
            data : {
                data : "new data"
            },
            methods : {
            }
        });
    </script>

自定義元素指令

(用處不是太大)
Vue.elementDirective('zns-red',{
    bind:function(){
        this.el.style.background='red';
    }
});

PS: 自定義元素指令要用bind來書寫,嘗試過用普通指令的形式書寫,不能有效

    <div id="box1">
        <ele-red>qqq</ele-red>
    </div>
    <script>
        Vue.elementDirective('ele-red',{
            bind : function (){
                this.el.style.background="red";
            }
        })
        var vm = new Vue({
            el : "#box1",
            data : {
                data : "new data"
            },
            methods : {
                //
            }
        });
    </script>

自定義指令完成拖拽實現

    <div id="box1" >
        <div class="ele1" v-drag></div>
    </div>
    <script>
        // 自定義元素指令要用bind來書寫,嘗試過用普通指令的形式書寫,不能有效
        Vue.directive('drag',{
            bind : function (){
                var oDiv = this.el;
                oDiv.onmousedown = function (ev){
                    /*var e = ev || window.event;
                    var disX = ev.clientX-obj.offsetLeft;
                    var disY = ev.clientY-obj.offsetTop;
                    document.onmousemove = function (){
                        var x = ev.clientX-disX;
                        var y = ev.clientY-disY;
                        obj.style.left=x+'px';
                        obj.style.top=y+'px';
                    }*/
                    var disX=ev.clientX-oDiv.offsetLeft;
                    var disY=ev.clientY-oDiv.offsetTop;

                    document.onmousemove=function(ev){
                        var l=ev.clientX-disX;
                        var t=ev.clientY-disY;
                        oDiv.style.left=l+'px';
                        oDiv.style.top=t+'px';
                    };
                    document.onmouseup = function (){
                        document.onmousemove = null;
                        document.onmousedown = null;
                    }
                }
            }
        })
        var vm = new Vue({
            el : "#box1",
            data : {
                data : "new data"
            },
            methods : {
                //
            }
        });
    </script>

自定義鍵盤資訊

@keydown.up
@keydown.enter
@keydown.a/b/c....

自定義鍵盤資訊:
    Vue.directive('on').keyCodes.ctrl=17;
    Vue.directive('on').keyCodes.myenter=13;

之前的做法:

    <div id="box1" >
        <input type="text" @keydown.c='show'><br>
        <input type="text" @keydown.a='show'><br>
        <input type="text" @keydown.b='show'><br>
        <input type="text" @keydown.65='show'><br>
        <input type="text" @keydown='code'>
    </div>
    <script>
        // keyCode 可以接一個字母,也可以接一個數字(對應的鍵碼來進行相關操作)
        var vm = new Vue({
            el : "#box1",
            data : {
                data : "new data"
            },
            methods : {
                show : function (){
                    alert(1111);
                },
                code: function (ev){
                    alert(ev.keyCode);// 列印鍵碼
                }
            }
        });
    </script>

使用自定義指令資訊

<div id="box1" >
        <input type="text" @keydown.a='show'><br>
        <input type="text" @keydown.ctrl='show'><br>
        <input type="text" @keydown.enter1='show'><br>
        <input type="text" @keydown='code'>
    </div>
    <script>
        // keyCode 可以接一個字母,也可以接一個數字(對應的鍵碼來進行相關操作)
        // 65 => a
        // 自定義鍵盤資訊
        //Vue.directive('on').keyCodes.a=65; // a 
        Vue.directive('on').keyCodes.ctrl=17; //點選Ctrl健, 
        Vue.directive('on').keyCodes.enter1=13; //enter 
        var vm = new Vue({
            el : "#box1",
            data : {
                data : "new data"
            },
            methods : {
                show : function (){
                    alert(1111);
                },
                code: function (ev){
                    alert(ev.keyCode);// 列印鍵碼
                }
            }
        });
    </script>

監聽資料變化

vm.$el/$mount/$options/....
vm.$watch(name,fnCb);  //淺度
vm.$watch(name,fnCb,{deep:true});  //深度監視

淺度監聽:

    <div id="box1" >
        {{data}}
    </div>
    <script>
        var vm = new Vue({
            el : "#box1",
            data : {
                data : "new data"
            },
            methods : {
                show : function (){
                    alert(1111);
                }
            }
        });
        document.onclick = function (){
            vm.data = 'add new data'
        }
        vm.$watch('data',function (){
            alert('data had changed.')
        })
    </script>

深度監聽:

    <div id="box1" >
        {{js}}
        <br>
        {{js | json}}
    </div>
    <script>
        var vm = new Vue({
            el : "#box1",
            data : {
                js : {
                    name:'Johnny',
                    age:20
                }
            },
            methods : {
                show : function (){
                    alert(1111);
                }
            }
        });
        document.onclick = function (){
            vm.js.age = 25;
        }
        /*
            vm.$watch('js',function (){
                alert('data had changed.')
            })
        */
        // 並沒有什麼效果,因為需要深度監聽 
        // 把以上程式碼替換
        vm.$watch('js',function (){
            alert('data had changed.')
        },{deep:true})
    </script>