Vue學習筆記
Vue初始化對象
var vm = new Vue({
el:"#box", //綁定的元素
template:"<h1>{{money}}</h1>", //使用的模板
data:function () { //綁定的數據
return{
money:"123"
}
}
})
data和methods里面的屬性都是Vue這個實例對象的代理屬性,例:vm.money = 123;
而vm本來的自身屬性則是vm.template,vm.
符號區分開來,就是內置的自帶的屬性和方法
var vm = new Vue({
// el:"#box", //綁定的元素
data:function () { //綁定的數據
return{
age:12
}
}
}).$mount("#box");
option可以讀取vue實例對象上面的靜態方法和屬性,也就是自定義方法和屬性
$log查看數據的一個狀態
注意,不要在實例屬性或者回調函數中使用箭頭函數,因為箭頭函數會綁定父級的上下文,會導致里面的this不會指向Vue實例
Vue實例對象的聲明周期
渲染方式
文本插值
<div id="box" >
{{money}}
</div>
單次渲染 v-once
<div id="box">
<button @click="changeData">456</button>
<span v-once>{{money}}</span>
</div>
渲染html v-html
<div id="box">
<span v-html="money"></span>
</div>
注意點:v-html是渲染html片段的,里面數據綁定會被忽略
屬性綁定 v-bind
vue中的屬性綁定和ng的有些不一樣,ng的可以在屬性上隨意添加插值語法,但是在vue中不可以,要利用v-bind綁定屬性,傳入的也可以是布爾值
<div id="box">
<span v-bind:title="money">{{money}}</span>
<input type="radio" v-bind:checked = "true">
</div>
簡寫:
<span :title="money">{{money}}</span>
事件處理器
<button v-on:click="warn('Form cannot be submitted yet.', $event)">Submit</button>
傳入$event可以操作dom節點
vue提供了一些內置修飾符也可以操作dom節點
- @click.stop阻止事件冒泡
- @click.prevent阻止事件默認行為
- @keydown/@keyup后面可以點鍵碼(@keydown.13),可以點英文(@keydown.enter)
表單控件
表單控件多數利用v-model來實現數據的雙向綁定
多個勾選框綁定到同一個數組
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<br>
<span>Checked names: {{ checkedNames }}</span>
new Vue({
el: '...',
data: {
checkedNames: []
}
})
指令的一些注意事項和注意點
v-model和ng-model作用一樣,都是實現數據雙向綁定的,但是有一個區別就是,ng-model綁定的對象可以不用聲明,但是v-model綁定的對象一定要聲明
-
v-if有時候要切換多個元素的時候,可以用template
<template v-if="true"> <h1>Title</h1> <p>Paragraph 1</p> <p>Paragraph 2</p> </template>
并且template并不會被顯示出來;也可以和if-else,v-else-if配合使用,if-else,v-else-if要緊挨著v-if的元素
computed能做到的事情,methods也能做到,那么兩者有什么區別呢?
computed會把計算結果保存在緩存當中,只有計算的值發送變化了才會重新計算,但是methods只要重新渲染就會重新計算,兩者的區別在于你是否希望保存到緩存當中并讀取它.-
vue為了提高渲染速度,通常會復用已有元素而不是從頭開始渲染
<template v-if="loginType === 'username'"> <label>Username</label> <input placeholder="Enter your username"> </template> <template v-else> <label>Email</label> <input placeholder="Enter your email address"> </template>
例如上面的代碼,當切換到email的時候,input里面的數值還是會存在,因為復用了這個元素
這種方式有一定的好處和壞處,當你需要分開這兩個input的聯系的時候,可以在input上添加一個唯一的key,vue就會重新渲染,不會復用前一個input v-show和v-if的區別
v-show和v-if同ng-show和ng-if很類似,v-if是惰性的,只要不需要它的時候,這個元素就不會被渲染,直到首次需要它的時候,而v-show不一樣,不管需不需要它,都會被渲染出來,之后css的display隱藏它,但是v-if切換所耗費的性能比較多,v-show耗費的性能比較少,所以如果元素需要不斷切換的還是利用v-show比較好,只要出現一次,不用頻繁切換的則用v-if-
v-for遍歷數據
(item,key) in array,vue里面是item在前面,key在后面,v-for的優先級會比v-if的優先級高
v-for遍歷數據可以設置一個template然后遍歷,這樣瀏覽器并不會讀取這個template模板標簽<template v-for="product in productList"> <h3>{{product.title}}</h3> <ul v-for="item in product.list"> <li> <a :href="item.url">{{item.name}}</a> </li> </ul> <div v-if="!product.last" class="hr"></div> </template>
:class的使用
:class和ng-class的使用方法差不多,:class="{'red':true}"
還可以和數組混搭
:class="[{'red':true},'bule']" 這樣有bule一個類,red會判斷是否添加當使用js吧圖片的src利用v-bind綁定到圖片上的時候,要利用require,否則會拿不到圖片
v-model.lazy方法就是當失去焦點時才刷新數據的綁定,有利于性能的提升
計算屬性computed
雖然插值語法也是可以解析js的代碼的,但是一些復雜的計算都寫在插值語法上會導致模板不清晰和邏輯復雜,稍微復雜的計算都盡量寫在計算屬性當中,改變計算前的數據,計算后的數據也會實時跟著改變的
<div id="box">
<span>{{message}}</span>
<span>{{reversedMessage}}</span>
</div>
var vm = new Vue({
el:"#box", //綁定的元素
data:function () { //綁定的數據
return{
message:"<h1>123456789</h1>"
}
},
computed:{
reversedMessage:function () {
return this.message.split('').reverse().join('');
}
}
});
computed:{
reversedMessage:{
get:function () {
return this.message.split('').reverse().join('');
},
set:function () {
this.message+=1;
}
}
}
computed完整的寫法有兩個,一個是get獲取數值,一個是set設置數值
Vue手動監聽屬性變化
vue也有一個類似angular的$watch屬性,可以監聽數據的變換
vm.$watch("red",function () {
alert("發生變化了");
});
但這種方法是一種淺監聽,如果遇到對象類型里的某個屬性變化就會監聽不到了
這時候要利用vue的一個深監聽
vm.$watch("people",function () {
alert("發生變化了");
},{deep:true});
發送網絡請求
vue并沒有內置http請求的東西,所以要發送http需要導入vue-resource,導入之后就可以使用$http請求了
利用get請求數據
methods:{
get:function () {
this.$http.get("a.txt").then(function (res) {
res.status //是狀態碼,成功一般200
res.data //res.data才是結果
alert("成功了");
},function () {
alert("失敗了");
})
}
}
利用get發送數據
methods:{
get:function () {
this.$http.get("get.php",{
a:1,
b:2
}).then(function (res) {
alert(res.data);
},function () {
alert("失敗了");
})
}
}
利用post上傳數據
post:function () {
this.$http.post("post.php",{
a:1,
b:2
},{
emulateJSON:true
}).then(function (res) {
alert(res.data);
},function () {
alert("失敗了");
})
}
一般在created里面執行數據的請求
created:function () {
this.$http.get("static/08-Ajax-get.php").then((data) =>{
this.data = data;
},(err)=> {
console.log(err);
})
}
最好利用es6的箭頭函數,保證this是外部的this
Vue生命周期(鉤子函數)
網上找到一張非常棒的圖
Vue組件
Vue的組件其實就等于新建了一個對象,一樣享有template,data,methods等方法
生成組件的幾種方式
var Aaa = Vue.extend({
template:"<h1>i am h1</h1>"
});
Vue.component("aaa",Aaa);
通過Vue對象生成組件
Vue.component("my-header",{
template:"<p>this is my header</p>"
});
生成組件然后綁定
var myHeader = {
template:"<p>this is my header</p>"
};
new Vue({
el:"#box", //綁定的元素
data:function () { //綁定的數據
return{
money:"123"
}
},
components:{
"my-header": myHeader
}
})
作用域
組件之間的作用域都是獨立的,意味著子組件不能獲取到父組件上面的數據
Vue.component("my-child",{
props:['message'],
template:"<div>{{message}}</div>"
});
props:{
slides:{
type:Array,
default:[] //如果沒傳入,默認為一個空數組
},
interval:{
type:Number,
default:1000 //如果沒傳入,默認為1000毫秒
}
}
<my-child :message="colorArr"></my-child>
這種方式就可以從父組件上面獲取數據,先聲明props然后用:message來接收,props還有另外一種方式
Vue.component("my-child",{
props:{
'message':String,
'myMsg':Number
},
template:"<div>{{message}}</div>"
});
這種方式會限定傳進來數據的格式,如果格式不對,就傳不進來了
同樣,父組件也是不能獲取到子組件上面的數據的
先是利用子組件$emit事件吧數據傳遞出去
<child @emit-msg="get"></child>//觸發emit-msg的傳遞方法,get是要父組件調用的方法的名稱
在子組件中
this.$emit("emit-msg",this.msg);//第一個參數是傳遞方法的名稱,第二個是數據
在父組件中
get:function (m) {
this.msg = m; //獲取到的m就是從子組件上面傳遞過來的數據
}
注意點:如果要在父組件上面獲取的方法里面傳入參數,例如這樣
<v-selection :selections="buyTypes" @on-change="onParamChange('buyType',$event)"></v-selection>
如果有另外傳入的參數,那么本來從子組件里面傳過來的參數就會獲取不到,所以要加一個$event參數,就可以獲取得到原本傳過來的參數了
去github搜索awesome-vue里面可以搜到許多組件!!!!!!!!!!!!!!
渲染的方式
<my-header></my-header>
但是在一些標簽內,例如table,ul,等標簽內可能會導致這樣的渲染方式失效,也有另外的方法
<table>
<tr is="my-row"></tr>
</table>
綁模板的方式
第一種直接寫在template里面
-
第二種寫在script里面type="x-template" id=名稱
<script type="x-template" id="aaa">
<h1 @click='myAlert()'>{{msg}}</h1>
</script>
然后template里面寫入id名稱就可以了template:"#aaa"
-
第三種寫在一個template標簽里面,和第二種有些類似
<template id="aaa"> <h1 @click='myAlert()'>{{msg}}</h1> </template>
在綁定
有些時候,模板標簽里面可能也會有東西,為了不要讓模板的內容完全覆蓋標簽里面的東西要利用到slot這個標簽
渲染模板里面
<div id="box" >
<aaa>
這里這里這里
</aaa>
</div>
如何才能保留"這里這里這里"同時又能渲染模板呢
這是aaa的模板
<template id="aaa">
<div>
<slot></slot> //slot里面就是aaa標簽里面原有的東西
<h1>我是aaa的模板</h1>
<slot></slot> //這里可以放置多個,可以渲染多次
</div>
</template>
當出現多個模板的時候,可以分配那個slot展示的是哪一塊
<aaa>
<ul slot="ul-slot">
<li>uuuuu</li>
<li>uuuuu</li>
<li>uuuuu</li>
<li>uuuuu</li>
</ul>
<ol slot="ol-slot">
<li>oooo</li>
<li>oooo</li>
<li>oooo</li>
<li>oooo</li>
<li>oooo</li>
</ol>
</aaa>
<div>
<slot name="ol-slot"></slot>
<h1>我是aaa的模板</h1>
<slot name="ul-slot"></slot>
</div>
動態組件
<component :is="tem"></component>
用一個component標簽,可以是:is或者is,is就填入不變的字符串,:is就可以填入vue實例的變量,達到動態切換的效果
自定義過濾器
Vue.filter("todo",function (input) {
return input<10?"0"+input:input;
});
<p>{{age | todo}}</p>
自定義指令
自定義指令擴展了html語法
Vue.directive("red",function (el) {
el.style.background = "red";//el就是綁定的元素
});
使用方式
<p v-red></p>
Vue-router
引入組件
import VueRouter from "vue-router"
Vue.use(VueRouter)
routes:[
{
path:"/",
component:IndexPage
},
{
path:"/detail",
component:DetailPage,
redirect:"/detail/analysis",
//這樣一進入detail就會去到analysis頁面,不會出現空白的頁面
children:[
{
path:"analysis", //這里不寫'/',寫了'/'會默認是跟目錄的
component:DetailAnalysis
},
{
path:"count",
component:DetailCount
},
{
path:"forecast",
component:DetailForecast
},
{
path:"publish",
component:DetailPublish
}
]
}
]
<router-link>是用來跳轉路由的指令
<router-link v-for="item in products" :to="item.path" tag="li" active-class="active">{{item.name}}</router-link>
//v-for遍歷幾個需要跳轉的入口,to就是跳轉到哪個路由上,tag就是這個標簽會以什么html標簽渲染,不寫的話默認是a標簽,acive-class就是選中的樣式,不設定的話會默認有個router-link-active類的
獲取當前路由地址this.$route.path 注意這里是沒有r的!!!!!!!!!!!!!
this.$router.push({path:"/detail"})可以使路由跳轉
瀏覽器插件
Vue-devtools
在vue中引入jquery插件
https://segmentfault.com/a/1190000007020623
登錄框的時候可以用computed監聽輸入框的規則
computed:{
userError(){
let errorText, status;
if(this.usernameModel.length<6 ){
status = false;
errorText = "不能小于6位"
}else{
status = true;
errorText = "";
}
if(!this.userFlag){
errorText = "";
this.userFlag = true;
}
return {
status,
errorText
}
},
passwordError(){
let errorText, status;
if(this.passwordModel.length<6 ){
status = false;
errorText = "密碼不能小于6位"
}else{
status = true;
errorText = "";
}
if(!this.passwordFlag){ //因為沒有在頁面渲染,所以也不用聲明
errorText = "";
this.passwordFlag = true;
}
return {
status,
errorText
}
}
}