vue學習筆記(二)

間陽幕賓發表於2017-10-19

一、vue生命週期

vue例項從建立到銷燬的過程,稱為生命週期,共有八個階段。

這八個階段裡分別有一個叫做鉤子函式的例項選項。供使用者在相應的階段對其進行操作。

beforeCreate(){  //元件例項剛剛建立,還未進行資料觀測和事件配置
                
},
created(){  //例項已經建立完成,並且已經進行資料觀測和事件配置
                
},
beforeMount(){//模板編譯之前,還沒掛載
                
},
mounted(){ //模板編譯之後,已經掛載,此時才會渲染頁面,才能看到頁面上資料的展示
                    
},
beforeUpdate(){//元件更新之前
                
},
updated(){//元件更新之後
                
},
beforeDestroy(){//元件銷燬之前
                
},
destroyed(){  //元件銷燬之後
                    
}

這幾個鉤子中,最常用的是created()mounted()

二、計算屬性

計算屬性也是用來儲存資料,但具有以下幾個特點:

  • 資料可以進行邏輯處理操作
  • 對計算屬性中的資料進行監視

1、基本用法

<div id="app">
    {{addZero}}
</div>
    
new Vue({
    el: `#app`,
    data: {
        num: 8
    },
    computed: {
        //這是計算屬性的get方法,用於取值
        addZero() {
            return this.num > 10 ? this.num : `0` + this.num;
        }
    }
})

這裡的addZeronum一樣,都是屬性。不過addZero是依賴於num、進行計算後的值。一旦num的值發生變化,addZero的值也會隨之變化。

 <div id="app">
    {{num}}----{{addZero}}
    <br>
    <button type="button" @click="change">點選改變num</button>
 </div>
    
 new Vue({
    el: `#app`,
    data: {
        num: 8
    },
    methods: {
        change: () => {
            this.num++;
        }
    },
    computed: {
        addZero:() => {
            return this.num > 10 ? this.num : `0` + this.num;
        }
    }
 })

一旦我們點選按鈕改變num的值,那麼因為計算屬性實時監測依賴項,addZero也會跟著發生變化。

2、計算屬性 vs 方法

將計算屬性的get函式定義為一個方法也可以實現和計算屬性類似的功能。那麼二者之間有什麼區別?

  • 區別一:計算屬性是基於它的依賴進行實時更新的,方法則是呼叫才更新
  • 區別二:計算屬性是有快取的,只要相關依賴沒有改變,多次訪問計算屬性得到的值是之前快取的計算結果,不會多次執行。操作一個沒有依賴項的值也是如此。

官方文件給出了下面這個例子:

computed: {
  now: function () {
    return Date.now()
  }
}

計算屬性存在快取,這裡的now值不會發生變化。

3. get和set

計算屬性由兩部分組成:get和set,分別用來獲取計算屬性和設定計算屬性。預設只有get,如果需要set,要自己新增。

        <div id="app">
        {{num}}----{{addZero}}
        <br>
        <button type="button" @click="change(5)">點選改變num</button>
    </div>
    
   new Vue({
        el: `#app`,
        data: {
            num: 8
        },
        methods: {
            change(newNumber) {
                this.addZero = newNumber;
            }
        },
        computed: {
            addZero: {
                get() {
                    return this.num > 10 ? this.num : `0` + this.num;
                },
                set(newNum) {
                    this.num = newNum
                }
            }
        }
    })

我們再change方法中改變addZero屬性的值的時候會自動呼叫它的set方法。

三、例項屬性和方法

vue中給例項和屬性提供了若干屬性和方法。

1、屬性

獲取屬性的語法:例項名.屬性名
以下是常用的屬性:

  • vm.$el: 獲取vue例項關聯的元素DOM,進而可以對其進行操作
  • vm.$data: 獲取資料物件data
  • vm.$options:獲取選項,自定義的選項也可以在這裡獲取。
  • vm.$refs:獲取所有新增ref屬性的元素dom物件,進而可以對其進行操作

2、方法

vm.$mount()

手動掛載vue例項

var vm=new Vue({
    data:{
        msg:`Hello vue.js`
    }
 }).$mount(`#app`);

vm.$destroy()

銷燬例項

vm.$destroy();  //銷燬例項所佔的記憶體空間

vm.$nextTick(callback)

在DOM更新完成後再執行回撥函式,一般在修改資料之後使用該方法,以便獲取更新後的DOM

var vm=new Vue({
    data:{
        msg:`Hello vue.js`
    }
 }).$mount(`#app`);
 
 //修改資料
 vm.msg=`foo`;
 
 console.log(vm.$refs.title.textContent);  //Hello vue.js
 vm.$nextTick(function(){
    console.log(vm.$refs.title.textContent); //foo
 });

DOM還沒更新完,Vue實現響應式並不是資料發生改變之後DOM立即變化,需要按一定的策略進行DOM更新,需要時間!使用$nextTick方法等DOM更新完再獲取資料。

vm.$set(target,key,value)

通過vue例項的$set方法為物件新增屬性,可以實時監視。

<div id="app">
    {{user.name}}<br> {{user.age}}
    <br>
    <button type="button" @click="addAge">新增屬性</button>
</div>
    
var vm = new Vue({
    data: {
        msg: `Hello vue.js`,
        user: {
            name: `hedawei`,
            gender: `man`
        }
    },
    methods: {
        addAge() {
            /* this.user.age = 22; */
            this.$set(this.user, `age`, 22);
        }
    }
}).$mount(`#app`);

方法中使用原始的新增屬性方法的話不會在模板中顯示。使用$set方法會實時監控資料,然後新增。

vm.$watch(監聽的屬性,callback)

監控vue例項的變化

 vm.$watch(`msg`, (newValue, oldValue) => {
    console.log(`msg被修改啦,原值:` + oldValue + `,新值:` + newValue);
 });

如果需要監控深度資料變化(例如監控一個物件中的某個屬性),則需要在選項中新增{deep:true}

四、自定義指令

自定義指令分為自定義全域性指令和自定義區域性指令。

1、自定義全域性指令

使用全域性方法Vue.directive(指令ID,定義物件)。注:使用指令時必須在指名名稱前加字首v-,即v-指令名稱

簡單示例:

Vue.directive(`hello`,{
    bind(){ //常用!!
        alert(`指令第一次繫結到元素上時呼叫,只呼叫一次,可執行初始化操作`);
    },
    inserted(){
        alert(`被繫結元素插入到DOM中時呼叫`);
    },
    update(){
        alert(`被繫結元素所在模板更新時呼叫`);
    },
    componentUpdated(){
        alert(`被繫結元素所在模板完成一次更新週期時呼叫`);
    },
    unbind(){
        alert(`指令與元素解綁時呼叫,只呼叫一次`);
    }
 });

這裡定義了一個名為hello的指令,指令定義函式提供了幾個鉤子函式,分別在不同的時期生效。我們像下面這樣使用這個指令:

<p v-hello>hello vue.js</p>

大多數情況下,我們只需要使用bindupdate鉤子函式。vue裡提供了函式的簡寫形式:

Vue.directive(`hello`, function () {
    alert("hello vue.js");
})  

鉤子函式有兩個常用的引數elbindingel是繫結的DOM物件,binding是一個物件,包含若干屬性。

拿到DOM物件,我們就可以對DOM進行一些操作。

<p v-hello="msg">hello vue.js</p>

Vue.directive(`hello`, function (el,binding) {
    el.style.color = "red";
    
    //屬性name是指令的名字(不帶v-)
    console.log(binding.name);     //hello
    //屬性value是傳遞給指令的值
    console.log(binding.value);   //alice
    //屬性expression是指令值的字串形式(個人感覺就是類似變數名)
    console.log(binding.expression);  //msg
    //屬性arg是傳遞給指令的引數(和傳值寫在一起容易令初學者困惑,下面分開寫  
    //合在一起寫的寫法是<p v-hello:123="msg">hello vue.js</p>)
    //<p v-hello:123>hello vue.js</p>
    console.log(binding.arg);       //123
    //屬性modifiers是一個包含修飾符的物件。
    //與傳參傳值合在一起的寫法是 <p v-hello:123.bar="msg">hedawei</p>
    //<p v-hello.bar>hello vue.js</p>
    console.log(binding.modifiers);    //{bar:true}
})  

 var vm = new Vue({
    el: `#app`,
    data: {
        msg: `alice`
    }
 })

2、區域性自定義指令

區域性自定義指令寫在例項的directives選項中。

  var vm = new Vue({
    el: `#app`,
    data: {
        msg: `alice`
    },
    methods: {
    },
    directives: {
        word: function(el, binding) {
            console.log(binding.name);
        }
    }
 })

其他用法與全域性自定義指令一致。

五、過度(動畫)

Vue 在插入、更新或者移除 DOM 時,提供多種不同方式的應用過渡效果。本質上還是使用CSS3動畫:transition、animation屬性。

1、基本用法

使用transition元件,將要執行動畫的元素包含在該元件內:

    <transition name="fade">
        運動的元素
</transition>   

我們需要為其定義一個name屬性,以便後面為其新增css樣式。

動畫有6個CSS類名,下面結合例子說明:

<style>
        button {
            display: block;
            margin: 20px auto;
        }
        
        p {
            width: 100px;
            height: 100px;
            background-color: red;
            margin: 0 auto;
        }
        
        .fade-enter-active,
        .fade-leave-active {   //定義整個過渡期間的效果
            transition: all 2s ease;
        }
        
        .fade-enter-to {    //定義過渡進入的最終效果
            opacity: 1;
            width: 100px;
            height: 100px;
        }
        
        .fade-leave-to {    //定義過渡離開的最終效果
            opacity: 0;
            width: 50px;
            height: 50px;
        }
        
        .fade-enter {      //定義過渡進入的開始效果
            opacity: 0;
            width: 50px;
            height: 50px;
        }
    </style>
    
    <div id="app">
        <button type="button" @click="flag = !flag">點 擊</button>
        <transition name="fade">
            <p v-show="flag">
            </p>
        </transition>
    </div>
    
    <script>
        new Vue({
            el: `#app`,
            data: {
                flag: false
            }
        });
    </script>

2、鉤子函式

vue中給過渡的不同時期提供了不同的鉤子函式。

<transition name="fade" @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter" @before-leave="beforeLeave" @leave="leave" @after-leave="afterLeave">
        <p v-show="flag">
        </p>
</transition>
        
 new Vue({
        ...
    methods: {
        beforeEnter(el) {
            alert(`動畫進入之前`);
        },
        enter(el) {
            alert(`動畫進入`);
        },
        afterEnter(el) {
            alert(`動畫進入之後`);
        },
        beforeLeave(el) {
            alert(`動畫離開之前`);
        },
        leave(el) {
            alert(`動畫離開`);
        },
        afterLeave(el) {
            alert(`動畫離開之後`);
        }
    }
 });

在這不同的時期,我們可以取到過渡元素的DOM物件,從而對其進行操作。

3、多元素過渡

上面的<transition></transition>標籤只適用於單元素過渡。若要對多元素進行過渡,則需要使用<transition-group></transition-group>標籤,並且繫結key屬性,設定不同的值。

    <button type="button" @click="flag = !flag">點 擊</button>
    <transition-group name="fade">
        <p v-show="flag" :key="1">
        </p>
        <p v-show="flag" :key="2">
        </p>
    </transition-group>

4、結合第三方庫一起使用(animate.css)

我們可以使用vue的自定義過渡類名結合第三方動畫庫實現自定義動畫效果。這六個自定義類名和vue內建的類名類似:

  • enter-class
  • enter-active-class
  • enter-to-class
  • leave-class
  • leave-active-class
  • leave-to-class
    示例:
 p {
    width: 300px;
    height: 300px;
    background-color: red;
    margin: 0 auto;
 }

 <div id="app">
    <button type="button" @click="flag = !flag">點 擊</button>
    <transition enter-active-class="animated tada" leave-active-class="animated bounceOutRight">
        <p v-show="flag">
        </p>
    </transition>
</div>

 <script>
    new Vue({
        el: `#app`,
        data: {
            flag: false
        }
    });
 </script>

未完待續。。。

相關文章