之前學(xué)過vue,上一個(gè)項(xiàng)目做小程序,發(fā)現(xiàn)跟vue差不多耻台,于是給一個(gè)星期的時(shí)間自己重拾vue摄杂,但是發(fā)現(xiàn)高估了自己映挂,并發(fā)現(xiàn)自己已變成一個(gè)小白...看了幾天vue文檔之后,再也不想說小程序與vue相似,小程序簡單太多了,看完文檔就可以做出來了,但是vue不一樣。揍异。雨涛。個(gè)人覺得vue的文檔很散,講的都是小零件僚纷,所以很難想著拼起來。在學(xué)習(xí)過程中做一下筆記吧...忘了可以看...
創(chuàng)建實(shí)例
new Vue({
el: "#app",
data:{},
methods: {},
filters: {},
directives: {},
computed:{},
router: vueRouter
})
過濾器
過濾器可以用在兩個(gè)地方:mustache 插值和 v-bind 表達(dá)式潮剪。
- 全局過濾器(自定義)
Vue.filter("dateFmt",function (param,fmtStr) {
let year = param.getFullYear();
let month = param.getMonth() + 1;
let day = param.getDate();
let hour = param.getHours();
let minute = param.getMinutes();
let second = param.getSeconds();
if(fmtStr == "yyyy-mm-dd"){
return year + "-" + month + "-" + day;
}else if(fmtStr == "yyyy-mm-dd hh:mm:ss"){
return year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
}
});
- 局部過濾器(自定義)
filters:{
dateFmt(param,fmtStr){
let year = param.getFullYear();
let month = param.getMonth() + 1;
let day = param.getDate();
let hour = param.getHours();
let minute = param.getMinutes();
let second = param.getSeconds();
if(fmtStr == "yyyy-mm-dd"){
return year + "-" + month + "-" + day;
}else if(fmtStr == "yyyy-mm-dd hh:mm:ss"){
return year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
}
},
}
- 使用過濾器(管道符后跟著過濾器名(參數(shù)))
<td>{{item.time | dateFmt("yyyy-mm-dd hh:mm:ss")}}</td>
自定義指令(這指令的鉤子函數(shù)涣楷,看不太懂...)
鉤子函數(shù)
- bind: 只調(diào)用一次狮斗,指令第一次綁定到元素時(shí)調(diào)用,用這個(gè)鉤子函數(shù)可以定義一個(gè)在綁定時(shí)執(zhí)行一次的初始化動(dòng)作
- inserted: 被綁定元素插入父節(jié)點(diǎn)時(shí)調(diào)用(父節(jié)點(diǎn)存在即可調(diào)用翼闹,不必存在于 document 中)斑鼻。
鉤子函數(shù)參數(shù)
- binding: 一個(gè)對(duì)象,包含以下屬性:
value: 指令的綁定值关摇, 例如:v-my-directive="1 + 1"
, value 的值是 2荒叶,又如:v-color="{colorname:'red',colorname2:'green'}"
,value.colorname的值是red,value.colorname2的值是green
我想输虱,暫時(shí)這兩個(gè)夠用了...畢竟其他還不會(huì)...
- 全局指令
// 定義一個(gè)全局自定義屬性指令
Vue.directive('focus', {
// 當(dāng)綁定元素插入到 DOM 中時(shí)調(diào)用(父節(jié)點(diǎn)存在即可調(diào)用些楣,不必存在于 document 中)
inserted: function (el) {
// 聚焦元素
el.focus();
console.log(el);
}
});
- 局部指令
directives: {
focus:{
inserted(el){
el.focus();
}
},
"color":{
bind: function (el,binding) {
console.log(binding.value.colorname);
el.style.color = binding.value.colorname;
},
inserted: function (el,binding) {
console.log(binding.value.colorname);
}
}
}
- 使用指令
<label>學(xué)號(hào):<input class="add" type="text" v-model="newNo" v-focus v-color="{colorname:'red'}"></label>
計(jì)算屬性(局部)
vue.js v1的系統(tǒng)過濾器filterBy換成計(jì)算屬性了
computed: {
searchQuery: function () {
var self = this;
return self.studentsList.filter(function (user) {
return (user["name"].indexOf(self.searchValue) !== -1 || user["no"].indexOf(self.searchValue) !== -1 || user["gender"].indexOf(self.searchValue) !== -1);
})
}
}
vue-resource
響應(yīng).then()內(nèi)的成功回調(diào)中的參數(shù)是響應(yīng)報(bào)文體
這相當(dāng)于jq的ajax
- get
this.$http.get('/someUrl').then(successCallback, errorCallback);
- post
需要加上emulateJSON:true,其本質(zhì)是在請(qǐng)求報(bào)文頭上增加了Content-Type:application/x-www-form-urlencode宪睹,由此愁茁,服務(wù)器中才可以獲取{no:1,sex:1}屬性值
this.$http.post('/someUrl',{no:1,sex:1(請(qǐng)求報(bào)文體)},{emulateJSON:true}).then(successCallback, errorCallback);
- jsonp
原理:jsonp不是一個(gè)ajax請(qǐng)求,采取的是瀏覽器的同源策略來實(shí)現(xiàn)跨域亭病,在請(qǐng)求的時(shí)候會(huì)在url后帶上callback=生成的函數(shù)名稱 一起提交給服務(wù)器鹅很,在服務(wù)器中利用callback傳入的值當(dāng)做一個(gè)方法來將要響應(yīng)回去的數(shù)據(jù)當(dāng)做參數(shù)傳入。
// jsonp是設(shè)置回調(diào)的屬性名罪帖,有些是cb=jqxxxx促煮,有些是callback=jqxxxx邮屁,默認(rèn)是callback
this.$http.post('/someUrl',{jsonp: "cb"}).then(successCallback, errorCallback);
生命周期
<div id="app">
<span ref="span">hello vue</span>
</div>
new Vue({
el: "#app",
data: {
msg:"hello"
},
// 在實(shí)例初始化之后,data和event/watcher 事件配置之前
// 還不能取到this.data污茵、事件
beforeCreate(){
console.log("1---beforeCreate",this.msg,this.$refs.span);
},
// 實(shí)例已完成以下的配置:data樱报,屬性和方法的運(yùn)算, watch/event 事件回調(diào)泞当。然而迹蛤,掛載階段還沒開始,$el 屬性目前不可見襟士。
// >>>>想要顯示頁面的時(shí)候就有數(shù)據(jù)的話盗飒,就在這個(gè)函數(shù)里請(qǐng)求數(shù)據(jù)
created(){
console.log("2---created",this.msg,this.$refs.span);
},
// 在掛載開始之前被調(diào)用:相關(guān)的 render 函數(shù)首次被調(diào)用。(可以理解為渲染前)
beforeMount(){
console.log("3---beforeMount",this.msg,this.$refs.span);
},
// el 被新創(chuàng)建的 vm.$el 替換(如{{}}差值表達(dá)式陋桂、v-show="isShow"等替換值)逆趣,并掛載到實(shí)例上去之后調(diào)用該鉤子。(可以理解為渲染后不知道這個(gè)vm.$el怎么用...)
mounted(){
console.log("4---mounted",this.msg,this.$refs.span);
}
})
過渡
感覺這個(gè)過渡真的好鬼復(fù)雜嗜历!官網(wǎng)最簡答的例子是點(diǎn)擊按鈕觸發(fā)宣渗,但是我不想要這種,我要一打開網(wǎng)頁就有動(dòng)畫梨州,怎么實(shí)現(xiàn)痕囱?于是我就開始嘗試用過渡的CSS類名和過渡鉤子。
- 過渡CSS類名實(shí)現(xiàn)
↓ 這個(gè)CSS其實(shí)我也不懂為什么要這樣寫暴匠,真的不懂鞍恢,但是按照這個(gè)格式.XXXX-enter-active, .XXXX-leave-active { } .XXXX-enter, .XXXX-leave-active { }
就可以有過渡的效果。
// CSS
<style>
.box { position: absolute; left: 0; top: 100px; width: 50px; height: 50px; background: skyblue;}
.box1-enter-active, .box1-leave-active {
transition: all .5s;
transform: translateX(0px);
}
.box1-enter, .box1-leave-active {
transform: translateX(200px)
}
</style>
↓ 一開始是用按鈕觸發(fā)isMove
每窖,后來被我注釋了帮掉。
// html
<div id="app">
<!--<button @click="isMove=!isMove">移動(dòng)</button>-->
<transition name="box1">
<div v-if="isMove" class="box"></div>
</transition>
</div>
看代碼就知道一開始我在created
鉤子控制isMove
,后來發(fā)現(xiàn)不行就換成mounted
鉤子窒典,為什么mounted
鉤子就行蟆炊,我是在過渡鉤子發(fā)現(xiàn)的。
// JS
new Vue({
el: "#app",
data: {
isMove: false
},
// created(){
// this.isMove = true;
// },
mounted(){
this.isMove = true;
}
})
- 過渡鉤子實(shí)現(xiàn)
↓ 一定要給過渡元素加上類名崇败,而且要有過渡(transition)屬性盅称。
// CSS
<style>
.box { width: 50px; height: 50px; background: skyblue; transition: all 3s linear;}
</style>
↓ @before-enter @enter @after-enter
都是固定的,函數(shù)名隨你后室,v-show
很重要哦缩膝,就是要靠他觸發(fā)
// html
<div id="app">
<transition name="moveBox"
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter">
<div v-show="isShow" class="box"></div>
</transition>
</div>
↓ 一開始我在created
控制isShow
,失敗之后我想應(yīng)該在哪個(gè)鉤子控制變量呢岸霹,(錯(cuò)誤思想:我看著過渡鉤子疾层,看到了el
,哦贡避!恍然大悟痛黎!mounted
鉤子不是跟el
有關(guān)系的嗎予弧?寫!搞定~)問了朋友關(guān)于生命周期mounted
的問題后湖饱,得出答案:過渡元素還沒有渲染完掖蛤,元素渲染完在改變isShow
,所以放在mounted
執(zhí)行
// JS
new Vue({
el: "#app",
data: {
isShow: false
},
methods: {
beforeEnter: function (el) {
// 控制動(dòng)畫的準(zhǔn)備進(jìn)入
el.style.transform = 'translateX(0px)';
},
enter: function (el, done) {
// 控制動(dòng)畫的最終狀態(tài)
let a = el.offsetLeft;
this.$nextTick(()=>{
el.style.transform = 'translateX(300px)';
});
done();
},
afterEnter: function (el) {
// 動(dòng)畫完以后的一些邏輯處理
}
},
// created(){
// this.isShow = true;
// console.log(this.isShow);
// },
mounted(){
this.isShow = true;
}
})
組件
不說廢話直接上碼
- 基礎(chǔ)組件
- html 分成3塊看
↓ 這#app
就是根組件井厌,www
是父組件
↓ 這就是父組件<div id="app"> <www></www> </div>
www
的模板蚓庭,這個(gè)模板里面有兩個(gè)<a>
,點(diǎn)擊登錄
變量which = login
仅仆,點(diǎn)擊注冊(cè)
變量which = register
器赞,還有子組件,這個(gè)是動(dòng)態(tài)組件墓拜,<component>
的元素屬性is = which
決定渲染哪個(gè)子組件港柜,而which
由點(diǎn)擊哪個(gè)a
標(biāo)簽決定。(keep-alive此時(shí)我還不知道有什么用咳榜,隨意加上去的)
↓ 父組件模板的子組件模板<template id="account"> <div> <h3>{{msg}}</h3> <a href="#" @click="which='login'">登錄</a> <a href="#" @click="which='register'">注冊(cè)</a> <!--動(dòng)態(tài)組件--> <keep-alive> <component :is="which"></component> </keep-alive> </div> </template>
<template id="login"> <div> <h4>登錄組件內(nèi)容</h4> </div> </template> <template id="register"> <div> <h4>注冊(cè)組件內(nèi)容</h4> </div> </template>
- JS
↓ 全局注冊(cè)父組件夏醉,父組件中注冊(cè)子組件
↓ 還可以局部注冊(cè)父組件Vue.component('www',{ // www 為組件元素名 template:'#account', // template元素的id data: function () { return{ msg: "賬戶組件內(nèi)容:", which: "login" } }, // 父組件中注冊(cè)子組件 components:{ "login":{ // 組件元素名 template: "#login" }, "register":{ // 組件元素名 template: "#register" } } }); new Vue({ el:'#app' });
new Vue({ el:'#app', components: { "www":{ template:'#account', // template元素的id data: function () { return{ msg: "賬戶組件內(nèi)容:", which: "login" } }, // 父組件中注冊(cè)子組件 components:{ "login":{ // 組件元素名 template: "#login" }, "register":{ // 組件元素名 template: "#register" } } } } });
- html 分成3塊看
- 父組件傳值子組件
在上面的例子基礎(chǔ)上動(dòng)工!- html
↓ 在父組件模板中加了一個(gè)<input>
涌韩,輸入登錄人名稱授舟,在動(dòng)態(tài)子組件中賦值給user
屬性,實(shí)現(xiàn)傳值贸辈,要注意的是給組件屬性賦值必須是父組件的已知值,不能是子組件的值肠槽。
↓ 在登錄子組件模板中加了<span>{{user}}擎淤,歡迎登陸!</span>
秸仙,子組件通過屬性user
取得登錄人名稱存放到props
中嘴拢,再用{{ }}
取出。<template id="account"> <div> <h3>{{info}}</h3> <a href="#" @click="which='login'">登錄</a> <a href="#" @click="which='register'">注冊(cè)</a> <br> <label>登錄的人是 <input type="text" v-model="msg"></label> <!--動(dòng)態(tài)組件--> <keep-alive> <component :user="msg" :is="which"></component> </keep-alive> </div> </template> <template id="login"> <div> <h4>登錄組件內(nèi)容</h4> <span>{{user}}寂纪,歡迎登陸席吴!</span> </div> </template> <template id="register"> <div> <h4>注冊(cè)組件內(nèi)容</h4> </div> </template> <div id="app"> <www></www> </div>
- JS
↑ 解釋的很清楚了,這里不說了捞蛋。Vue.component('www',{ template:'#account', data: function () { return{ info: "賬戶組件內(nèi)容:", which: "login", msg: "" } }, components:{ "login":{ template: "#login", props:["user"] }, "register":{ template: "#register" } } }); new Vue({ el:'#app' });
- html
- 子組件傳值父組件
這個(gè)栗子是點(diǎn)擊登錄以后孝冒,出現(xiàn)登錄組件,在該組件中輸入一句話拟杉,這句話在父組件中出現(xiàn)庄涡。- html
↓ 在父組件模板中加了<span>登陸之后,{{msg}}說:</span><span>{{userSay}}</span>
用來顯示子組件輸入的話搬设。在動(dòng)態(tài)子組件中綁定自定義事件get-child-say
(這個(gè)必須是羊肉串命名穴店,不可以駝峰)撕捍,事件處理程序就是sayWhat
。
↓ 在登錄子組件模板中增加<label>我說: <input type="text" v-model="childSay" @keyup.enter="sendToFoo"></label>
泣洞,當(dāng)輸入一句話后按回車鍵就會(huì)觸發(fā)事件sendToFoo
<template id="account"> <div> <h3>{{info}}</h3> <a href="#" @click="which='login'">登錄</a> <a href="#" @click="which='register'">注冊(cè)</a> <br> <label>登錄的人是 <input type="text" v-model="msg"></label> <div> <span>登陸之后忧风,{{msg}}說:</span><span>{{userSay}}</span> </div> <!--動(dòng)態(tài)組件--> <keep-alive> <component v-on:get-child-say="sayWhat" :user="msg" :is="which"></component><!-- 這個(gè)自定義事件get-child-say不能用駝峰命名,只能用羊肉串 --> </keep-alive> <!--打開vue tool觀察:加了這個(gè)keep-alive球凰,不顯示的子組件一直在父組件中保存著狮腿,不加的話父組件下只有正在顯示的子組件--> </div> </template> <template id="login"> <div style="border: 1px solid red;"> <h4>登錄組件內(nèi)容</h4> <span>{{user}},歡迎登陸弟蚀!</span> <br> <label>我說: <input type="text" v-model="childSay" @keyup.enter="sendToFoo"></label> </div> </template> <template id="register"> <div> <h4>注冊(cè)組件內(nèi)容</h4> </div> </template> <div id="app"> <www></www> </div>
- JS
↓ 在login
組件有一個(gè)sendToFoo()
蚤霞,當(dāng)該方法觸發(fā)時(shí),就會(huì)觸發(fā)get-child-say
事件义钉,并且會(huì)帶上參數(shù)this.childSay
昧绣,就是輸入的一句話,而這個(gè)事件在父組件中綁定的捶闸,故而執(zhí)行sayWhat(value)
獲取參數(shù)渲染到父組件中夜畴。Vue.component('www',{ template:'#account', data: function () { return { info: "賬戶組件內(nèi)容:", which: "login", msg: "", userSay: "" } }, methods: { sayWhat(value){ this.userSay = value; } }, components:{ "login":{ template: "#login", props:["user"], data:function () { return { childSay: "" } }, methods: { sendToFoo(){ this.$emit("get-child-say",this.childSay); } } }, "register":{ template: "#register" } } }); new Vue({ el:'#app' });
- html
- keep-alive
在開始寫基礎(chǔ)組件的時(shí)候就有疑問了:動(dòng)態(tài)組件中被keep-alive包著有什么用?終于搞完 子組件傳值父組件 之后大概知道了一點(diǎn)了删壮。-
用
keep-alive
包裹動(dòng)態(tài)組件:運(yùn)行基礎(chǔ)組件贪绘,打開Vue.js devtools,然后看↓
.
-
沒有用
keep-alive
包裹動(dòng)態(tài)組件:運(yùn)行基礎(chǔ)組件央碟,打開Vue.js devtools税灌,然后看↓
-
<keep-alive> 包裹動(dòng)態(tài)組件時(shí),會(huì)緩存不活動(dòng)的組件實(shí)例亿虽,而不是銷毀它們菱涤。為此可以添加一個(gè) keep-alive 指令參數(shù)。在API 參考查看更多
<keep-alive>
的細(xì)節(jié)洛勉。
- 路由參數(shù)實(shí)現(xiàn)url傳值
下面的這個(gè)栗子是:在根組件輸入數(shù)據(jù)作為路由參數(shù)(同時(shí)修改路由)粘秆,然后通過路由傳去組件。
// html
<div id="app">
<label>傳值:<input type="text" v-model="msg"></label>
<br>
<router-link :to="'/sub1/' + msg">sub1</router-link>
<router-link to="/sub2">sub2</router-link>
<!-- 組件的顯示占位區(qū)域 -->
<router-view></router-view>
</div>
<!-- 第一個(gè)子組件模板 -->
<template id="sub1">
<div>
<h3>這是第一個(gè)子路由</h3>
<div>傳來的值是:{{txt}}</div>
</div>
</template>
<!-- 第二個(gè)子組件模板 -->
<template id="sub2">
<div>
<h3>這是第2個(gè)子路由</h3>
</div>
</template>
// JS
// 定義第一個(gè)子組件
let sub1 = Vue.extend({
template: "#sub1",
data: function () {
return {
txt: ""
}
},
// 導(dǎo)航完成后收毫,在組件的 created 鉤子中獲取數(shù)據(jù)
// 還可以在數(shù)據(jù)獲取期間展示一個(gè) loading 狀態(tài)
created: function () {
this.txt = this.$route.params.id;
}
});
// 定義第二個(gè)子組件
let sub2 = Vue.extend({
template: "#sub2"
});
// 定義路由對(duì)象并且注冊(cè)路由規(guī)則
let vueRouter = new VueRouter({
routes: [
{path: '/',redirect: '/sub2'}, // 默認(rèn)路由
{path: '/sub1/:id',component: sub1},
{path: '/sub2', component: sub2}
]
});
// 使vueRouter生效
new Vue({
el: "#app",
data: {
msg: ""
},
router: vueRouter
})