vue學習(二) vue生命週期 vue自定義指令和過濾器
阿新 • • 發佈:2019-02-19
生命週期鉤子函式
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(); -> 檢視現在資料的狀態
#
<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>
<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>