表達式
Vue的表達式不叫表達式,叫插值,寫法是
{{ 5*4 }}
或者 {{ [1.2.3].reverse().join("--") }}
單次插值:{{ *val }}
值插入后不能再改變
html 插值 : {{{ htmlStr }}}
輸出 html 標記
<div id="box">
<!--插值-->
{{ 5*4 }}
{{ [1,2,3].reverse().join("-") }}
{{ 4<6 ? 4<6 : false}}
{{ msg }}
<div v-html="html">{{ html }}</div> 會正確輸出Hello 中國
如果是{{ html }} 則會輸出 <h1>Hello 中國</h1> 帶標簽的原樣模板
</div>
<script src="vue2.0.js"></script>鏈接vue2.0
<script>
new Vue ({
//產生一個vue的實例
el : "#box", //指定掛載元素
data : { //初始化數據 data 是字面量對象
msg : "Hello Vue!!!",
html :"<h1>Hello 中國</h1>"
}
})
</script>
綁定 v-bind:attr
簡寫形式是 v-bind:style="styleObject"
可以簡寫為 :style="styleObject"
<div id="box">
<span title="這是 title">鼠標停一下</span>
<span v-bind:title="msg">鼠標停一下</span>
<span v-bind:style="styleObject" v-bind:id="a" v-bind:diy="msg">鼠標停一下</span>
{{ 5 }}
</div>
- 給span 綁定一個 title 事件,鼠標放上去就會顯示 " 這是 title"
- 但改一個形式 v-bind:title="msg"
msg 是我們在 data 里面初始化的變量 ,這樣,鼠標再放上去的時候 就會顯示 " Hello Vue!!! " - 我們又給 span 綁定一個 style 樣式 , 有兩個樣式,標準屬性前面寫上 v-bind: 就可以綁定變量了. span 就會變成紅色的 30px 的文字
- 用一個變量 vm 去接收 new Vue 的實例:
- 給span 綁定一個 id 屬性 a 再綁定一個 diy 屬性,也是 msg ,在腳本里面,如果沒有初始化 msg 會報一個錯誤,但可以初始化一個空.
msg:" "
然后我們去瀏覽器的后臺去輸出 vm 回車,
能 看到 $el : div #box
所以 可以通過 vm.$el 拿到#box 這個節點 vm.$el == #box
寫法是vm.$el
可以console.log() 一下,就能得到 id 是 box 的 div而且還能看到很多 比如: msg : "Hello Vue!!!"
還有 styleObject : 點開就能看到 fontSize 和 color
所以 : vue 把 所有 data 的東西都掛載在 實例上了.所以可以直接在后臺直接更改, 很方便
<script>
//vm 會接收所有data上的數據,vm.msg === data.msg
var vm = new Vue ({
//產生一個vue的實例
//el : "#box", //指定掛載元素
data : {
msg : "Hello Vue!!!",
a : "textId",
styleObject : {
fontSize : "30px",
color : "red",
}
}
})
// console.log(vm.$el);//拿到#box的div
vm.$mount("#box");
</script>
以上: 我們可以換一種掛載方式: vm.$mount ("#box")
mount 是掛載的意思 這樣也是可以的,也能實現掛載在某個節點上
$el 用于獲取 vue 所掛載的元素
而$mount 用于將 Vue 實例 掛載到指定元素
樣式綁定
<style>
.a{
color: blue;
}
.b{
color: pink;
}
.c{
font-size: 50px;
}
.d{
display: none;
}
</style>
- 以下 div 綁定了兩個 class 樣式, 但是 a 會被 b 覆蓋 ,
-
:class=[first,second]
樣式也可以用數組的形式來綁定, - 在數組里面寫一個三元表達式
:class="[first,isShow ? ' ' : third]"
這個
<div :class="{ a : isA,b : isB }" class="c">
div 內容
</div>
<div :class="[first,second]">
<!--綁定對象,綁定數組 class-->
div 內容2
</div>
<div :class="[first,isShow ? '' : third]">
div 內容3
</div>
<div :style="[styleObject,styleObject1]">
style 數組寫法
</div>
<script>
//vm 會接收所有data上的數據,vm.msg === data.msg
// 可以通過vm.$el 拿到#box 這個節點
var vm = new Vue ({
//產生一個vue的實例
data : {
msg : "Hello Vue!!!",//務必在 data 中初始化要使用的數據,否則會拋出警告
a : "testId",
isA : true,
isB : true,
first : "a",//字符串
second : "c",//字符串
isShow : true,
third : "d",
styleObject : {
fontSize : "50px",
color : "#ccc",
fontStyle : "italic",
},
styleObject1 : {
background : "#3e3e3e",
border : "2px solid cyan",
width:"500px",
},
}
})
vm.$mount("#box");// 將 Vue 實例掛載到指定的元素
</script>
條件
v-if 條件渲染 跟angular的 ng-if 是一樣的
- v-if 跟angular效果一樣,從DOM樹中移除
- v-else 緊鄰著 v-if
- v-else-if
<div id="box">
<span v-if="isShow">加油!!站起來!!</span>
<p v-else>看不到我</p>
<span v-if="isShow">Hello Vue!!!</span>
<!--<span v-else-if="!isShow">2,1新增的</span>-->
<span v-else> no Hello Vue!!!</span>
<span v-show="isShow">v-show content</span>
</div>
以上例子:
1.第一個 span 是默認顯示的,如果在瀏覽器的控制臺,改變vm.isShow=false 這樣 span 就不顯示了,而與 span 相反屬性的 p 標簽,就會顯示
- 最后一個 span 標簽 v-show 是隱藏元素 為 true 就顯示,為 false 就隱藏
v-if v-show 的區別
區別
- (1)手段:v-if是動態的向DOM樹內添加或者刪除DOM元素;v-show是通過設置DOM元素的display樣式屬性控制顯隱;
- (2)編譯過程:v-if切換有一個局部編譯/卸載的過程,切換過程中合適地銷毀和重建內部的事件監聽和子組件;v-show只是簡單的基于css切換;
- (3)編譯條件:v-if是惰性的,如果初始條件為假,則什么也不做;只有在條件第一次變為真時才開始局部編譯(編譯被緩存?編譯被緩存后,然后再切換的時候進行局部卸載); v-show是在任何條件下(首次條件是否為真)都被編譯,然后被緩存,而且DOM元素保留;
- (4)性能消耗:v-if有更高的切換消耗;v-show有更高的初始渲染消耗;
- (5)使用場景:v-if適合運營條件不大可能改變;v-show適合頻繁切換。
<script>
var vm = new Vue({
el : "#box",
data : {
isShow : true,
}
})
</script>
寫一個條件渲染的demo
<template v-if="loginType==='username'">
/* 這是判斷條件 */
<label> 用戶名</label>
<input type="text" placeholder="請輸入用戶名">
</template>
<template v-else>
<label> 郵箱</label>
<input type="text" placeholder="請輸入郵箱">
</template>
<button @click="toggle">點擊切換登錄方式</button>
data:{
loginType:' '
}
method:{
toggle:function(){
var a = this.loginType==="username" ? 'email' :'username';
this.loginType = a;
}
/*這個三元表達式不是很好理解,先判斷 this.loginType===username
true為email fasle為username 最后賦值,把this.loginType賦值為判斷過后a的結果. */
}
那么在上面的代碼中切換 loginType
將不會清除用戶已經輸入的內容。因為兩個模板使用了相同的元素,<input>
不會被替換掉——僅僅是替換了它的placeholder
。
如果想這兩個元素獨立出來,不復用,用一個key去命名就可以解決.這樣就不是簡單的更改playsholder這么簡單了,而是兩個單獨的模板
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email-input">
</template>
v-show
<template v-show="ok1">
<p> v-show用在template是沒有用的,例如這個v-show = 'ok1' ok1為false ,但是頁面上是可以渲染出來的.
</p>
</template>
data:{
ok1:false,
}
列表渲染
v-for
<script>
var vm = new Vue({
el : "#box",
data : {
arr :["a","b","c"],
num : 5,
obj :{
name : "zhar",
address : "北京",
age : 30,
},
arr2 : [1,2,3,3],
arr3 : [{
id : 1,
name :"zhar"
},{
id : 2,
name : "tom"
}]
}
})
</script>
以上數據: 遍歷出來的方法 :以下
- Vue1.0 :$index 2.0沒有$index 但是要想得到下標 ,就是 <li v-for="(x,index) in arr">{{ x }}---{{ index }}</li> 沒有$ 也能得到下標
值在前,下標在后
,如果index寫在前面,index 得到的就是值.所以,為了方便語義化,val寫在前面,index寫在后面
- 整數遍歷, 想當于一個 for 循環, vue 整數遍歷,比angualr 的整數遍歷簡單,不用初始化一個數組,只用初始化一個數字就OK
- 遍歷有相同元素的數組時;vue可以直接遍歷, 不用track by index 比angular 簡單
- vue1.0
<li v-for="x in arr" track-by="$index">
vue2.0
<li v-for="a in arr" :key="a.id">
- 遍歷數組的對象的下標,參考v-for="a in arr3" 通過綁定 :key 可以得到id,
<div id="box">
遍歷數組
<ul>
<li v-for="x in arr">{{ x }}</li>
</ul>
遍歷對象
<ul>
<li v-for="x in obj">{{ x }}</li>
<!--只拿到值,沒有鍵-->
</ul>
<ul>
<li v-for="(val,key) in obj">1++{{val +"--"+ key}}</li>
值在前, 鍵在后
</ul>
<ul>
<li v-for="(val,key,index) in obj">{{index +"--"+ key +"--"+ val}}</li>
值,鍵,下標,順序要寫對,得到的對應的數據就是語義化的數據,
</ul>
<ul>
<!--整數遍歷 -->
<li v-for="i in num">{{ i }}</li>
結果是1,2,3,4,5,
</ul>
<ul>
遍歷有相同元素的數組時;vue可以直接遍歷, 不用track by index 比angular 簡單
<li v-for="a in arr2">{{ a }}</li>
</ul>
<ul>
<!--angular 中碰見相同元素的數組時,是track by $index-->
<!--vue1.0 <li v-for="x in arr" track-by="$index">-->
<!--vue2.0 <li v-for="a in arr" :key="a.id">-->
<li v-for="a in arr3">{{ a }}</li>
<li v-for="a in arr3" :key="a.id">{{ a.name}}----{{a.id }}</li>
輸出結果是 zhar---1 tom---2
</ul>
</div>
v-if v-for一起使用
v-for比v-if有更高的優先級,所以如果v-if要判斷的話,在v-for的外層元素上加v-if進行判斷
事件
- 添加事件的方法是,
v-on:click
簡寫形式是@click
- 第一個 button ,點擊 {{ a }} 插值就會顯示 true 或者 false ,因為 a 就是腳本里面初始化的值,初始是true ,然后button 綁定的是 非a 所以點擊一下,就會顯示false 再點擊就會顯示true 默認是 true
- 第二個button 綁定的changeEvent 事件 ,是個函數,函數就不能寫在data里面初始化了,要寫在 methods 配置項里面去初始化,
- change 事件 可以不傳參,也可以傳參
先說不傳參的: change 綁定的還是 插值 a 的狀態 點擊false 再點擊就是true
------------分割線------------
再說傳參的: 第一個是默認的參數,$event 打印出來的是 mouseevent 和其他的兩個 a b 參數, - 又聲明了一個foo函數,在頁面輸出的時候,一定要 是
{{ foo() }}
返回的是一個隨機數, 而不能不加括號,否則輸出的是function boundFn(a) { var l = arguments.length; return l ? l > 1 ? fn.apply(ctx, arguments) : fn.call(ctx, a) : fn.call(ctx) }
是一堆看不太懂的東西 - 下面又初始化了一個數據, firstname 和lastname 在methods里面初始了一個函數,返回的是 firstname+lastname 方法的調用就是加上括號 也能用上data 的數據
添加事件的放法就是 v-on:click 或者 @click click可以換成別的事件,mouseenter mouseleave等
- 事件冒泡 ,如果子元素和父元素綁定上相同的click事件,就會由子觸發,一直觸發到父,一直往外冒泡, Vue 提出的解決辦法是
@click.stop
就可以阻止事件往外冒泡,
DOM 提供的方法是
event.stopPropagation() 和addEventlisten() 阻止冒泡,
jquery也提供了方法: 是
event.preventDefault()
event.stopPropagation();
- 下面代碼里面的 input 綁定了 v-model 綁定的是 firstName這個變量 , 添加事件叫
@keydown
鍵盤按下事件,后面的都是修飾符,按上下左右鍵和deleta鍵才會在控制臺輸出,否則,不管頁面怎么修改,控制臺都不會輸出
4.jpg
還有這么多修飾符可以添加
這個圖片是鍵盤修飾符,還有stop,還有preevent可以連用
<div id="box">
<button v-on:click="a=!a">點擊show/hide</button>
輸出 v-on:click="a=!a"{{ a }}
<button type="" v-on:click="changeEvent">clicktwo</button>
<button type="" @click="changeEvent($event,'a','b')">dian ji 3</button>
<!--$event 是默認的參數,如果在事件處理中,想同時使用時間對象和其余的參數,需要顯示傳入$event -->
<h1 v-show="a">{{ msg }} show is show </h1>
{{ foo() }}
{{ fullName()}}
<!-- 添加事件的方式, v-on:click=" " -->
<!-- v-on:eventName="" -->
<!-- @enentName 是 v-on-eventName 的簡寫形式-->
修飾符
<div @click="p1">
this is div
<button @click.stop="changeEvent">click it</button>
<!--引發冒泡-->
<!-- 修飾符: v-on:eventName.modifier.stop 阻止冒泡 -->
<input type="text" v-model="firstName" @keydown.left.right.up.down.delete="p2">
<!--跟一個 .left -->
{{ firstName }}
</div>
</div>
<script>
var vm = new Vue({
el : "#box",
data : {
msg : "HELLO VUE!!!",
a : true,
firstName : "tom",
lastName : "--merry",
},
//創建方法,
methods : {
//新的配置項 添加新的方法 都放在methods 里面
changeEvent : function(e,d,f){
//this 指向的是vm實例
this.a = !this.a;
console.log(e,d,f);
},
foo : function(){
return Math.random();
},
fullName : function(){
return this.firstName+this.lastName ;
},
p1 : function(){
console.log("div click event")
},
p2 : function(){
console.log(this.firstName)
}
}
})
</script>
model
v-model 就是將我們的數據和表單數據進行綁定
- c2 初始化是一個數組,給三個不同的checkbox 不同的 val , 如果 checkbox 是true ,他的 value 的值,就會被添加到 c2 數組,如果是 false , val 就會從數組里刪除
- v-model 還有單選還有下拉列表,自己看手冊練一練
- 最后一個input 綁定的事件有點多,可以單獨去練一練 但這里有一個知識點,就是
true-value="hello" false-value="bye"
這是綁定的字符串,點擊就是hello,再點擊就是bye , 但是如果想綁定變量,就要用v-bind:true-value="a" v-bind:false-value="b"
雖然看上去效果差不多,但是 一個是固定的字符串,一個是變量
我剛才試了一下,c3 如果是字符串的話,變量a 和變量b 的形式都得是字符串,
如果形式不一樣,就會得不到正確的輸出
<div id="box">
<input type="text" v-model="msg">
<h1>{{ msg }}</h1>
<input type="checkbox" v-model="c1">
<h1>{{ c1 }}</h1>
<input type="checkbox" v-model="c2" name="" value="a">
<input type="checkbox" v-model="c2" name="" value="b">
<input type="checkbox" v-model="c2" name="" value="c">
<h1>{{ c2 }}</h1>
<!--顯示在頁面上的是 input 的 value -->
<input type="checkbox" v-model="c3" name=""
true-value="hello" false-value="bye"
v-bind:true-value="a" v-bind:false-value="b"
>
<h1>{{ c3 }}</h1>
</div>
</body>
<script src="vue2.0.js"></script>
<script>
var vm = new Vue({
el : "#box",
data : {
msg : "hello china",
c1 : true,
c2 : ["tom"],
//數組,綁定空數組,把你選中的 value 放進數組 ,默認有一個 tom ,就會向后追加
c3 : "",//初始化 c3 是字符串,
a : "我是真的",
b : "我是假的",
},
})
</script>
計算屬性
{{ computedFullName() }}
這個方法是添加在 methods 里面的,沒毛病啊,之前說過的,方法是添加在 methods 里面的
- 但是 vue 提供了更加便利的配置項, computed ,所以那個依賴 data 的 函數,可以寫在 computed 這個配置項里面,data 里面的 fullname 就沒有必要了,因為他是計算出來的,再計算屬性里面 把 fullname 寫成一個函數,返回的是firsname + lastname 可以直接在body 里面用插值輸出fullname
- 用methods 也可是實現fullname 但為什么還存在計算屬性
他們之間的差別是:
A: 計算屬性是緩存的,只有依賴的值發生變化時,他才會發生變化,
給一個 button 點擊事件, 輸出 this,fullname 輸出的是同一個值
如果寫在methods 里面,每執行一次,會被重新調用一次,多使用計算屬性,
<div id="box">
{{ firstName+lastName }}
{{ computedFullName() }}
{{ fullName }}
{{ fullName }}
<button type="" @click="clickEvent">click it</button>
{{ str }}
<span v-html="str"></span>
</div>
</body>
<script src="vue2.0.js"></script>
<script>
var vm = new Vue({
el : "#box",
data : {
activeIndex : 0,//設置默認激活的面板
msg : "hello china",
firstName : "zhar",
lastName : "tom",
str : "<h1>this is HTMLstr</h1>",
// fullName : "",
},
computed :{
//計算屬性 多使用計算屬性,計算購物車 依賴單價和數量,聲明多個
//watch 的屬性監聽 事件
fullName : function(){
return this.firstName+this.lastName+new Date().getTime();
},
},
//創建方法,
methods : {
// computedFullName : function(){
// return this.fullName=this.firstName+this.lastName
// },
clickEvent : function(){
console.log(this.fullName);
},
}
})
</script>
補充一點,上面提到過的,初始化一個模板字符串,直接用插值輸出的話,輸出的是模板字符串原樣,如果用<span v-html="str"></span>
輸出的就是正確的被渲染過的標簽內容
fullName:{
get: function(){
return this.firstName +' '+ this.lastName;
},// 只寫get方法的話,是單向數據綁定,fullName的改變依賴于firstName或者lastName.
set: function (newValue){
var names = newValue.split(' ');
console.log(22,names)
this.firstName = names[0];
this.lastName = names[names.length - 1];
} // 加上set方法的話,就是雙向數據綁定,fullName改變,firstName和lastName也會改變
}
- 以上
fullName
方法寫在computed計算屬性里面,是通過計算得到的
- 以上
class 與 style 綁定
綁定HTML class
<div class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div>
data: {
isActive: true,
hasError: false
}
對象語法
- 綁定一個屬性,
<div v-bind:class="active"></div>
- 綁定多個屬性
<div v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>
括號里面用逗號隔開 - 綁定2個或者3個以上的屬性
<div v-bind:class="classObject"></div>
data:{
classObject:{
info : false,
info2 : true,
info3: true,
info4: false
}
}
- 還有就是通過計算屬性添加類(以后項目中會使用)
<div v-bind:class="classObject"></div>
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
這是綁定多個屬性的進階版.
數組語法
- 普通的數組語法
<p :class="[activeClass,errorClass]">{{ msg }}</p>
data:{
activeClass: 'info',
errorClass: 'info3',
}
最后的渲染結果就是兩個類都添加上了.
- 三元表達式的數組語法
<p :class="[ isactive ? activeClass : errorClass ]">{{ now }}</p>
<hr>
<button @click="click">點擊添加屬性</button>
data:{
isactive:false
}
methods:{
click:function(){
this.isactive = !isactive;
}
}
最后實現的效果就是點擊按鈕可以切換兩個屬性
不過,當有多個條件 class 時這樣寫有些繁瑣。所以在數組語法中也可以使用對象語法:
<div v-bind:class="[{ active: isActive }, errorClass]"></div>
用在組件上
跟用在html標簽上的用法一致, 可以用三元表達式,數組語法,對象語法
綁定內聯樣式
- 內聯跟class樣式差不多,也有對象語法,數組語法,不一樣的是,內聯樣式,是寫在style="{ }" 這個大括號里面的
對象語法
<div :style="{ color: 'red', background: 'cyan',fontSize: num+'px'}">這是style綁定的對象語法</div>
data:{
num: 30,
}
也可以不直接寫樣式,變成動態的,可變的
<div :style="styleObj">你好啊反饋的積分卡藍燈就估計得發老公覺得</div>
- 直接綁定到一個樣式對象通常更好,這會讓模板更清晰,同樣的,對象語法常常結合返回對象的計算屬性使用。以下:
data:{
styleObj:{
color:'#333',
background:"#f0f0f0",
fontSize: '24px'
},
}
數組語法
可以把多個 樣式對象 應用到同一個元素中
<div v-bind:style="[baseStyles, overridingStyles]"></div>
data:{
baseStyles:{
width:'200px',
height:'100px',
background:'cyan',
},
overridingStyles:{
color:'red',
fontSize:'30px'
}
}
自動添加前綴
當 v-bind:style
使用需要添加瀏覽器引擎前綴的 CSS 屬性時,如 transform
,Vue.js 會自動偵測并添加相應的前綴。