Vue指令
- VUE指令:directive
1.都是按照v- xxx處理的,它是vue中規定給元素設置的自定義屬性, v-開頭,放在元素的行間屬性,有着特殊意義的一些詞;
2.當vue加載成功並進行處理的時候,會按照相關的規則解析和宣傳視圖,遇到對應的指令實現對應的功能
命令;
3.指令放在行間的屬性值,當編譯時,首先會去查找在vue的data中是否有這個屬性,如果沒有,就報錯;
4.在使用指令時,會先找數據類型中的值,如果數據類型中沒有,那麼就去找data或methods中的屬性名;
1.基礎指令
- {{}}: 小鬍子語法可以將data中數據放入其中
- v-model-般給表單元素設置的,實現表單元素和數據之間的相互綁定
1)先把數據綁定給表單元素,一般把數據賦值給表單元素的value、
2)監聽表單元素的內容改變
3)內容改變後,會把對應的數據也改變
4)對應的數據改變,視圖中所有用到數據的地方都會重新渲染
視圖<=>數據
在vue框架中給表單元素設置value等屬性是沒有意義的。
- v-html/v-text:給非表單元素設置內容,v-html支持對於標籤的自動識別,v-text 會把所有內容分都當做文本,傳統的鬍子語法,在vue沒有 加載完成之前,會把{{xxx}}展示在頁面中,當vue 加載完纔會出現真正的內容,這樣體驗不好
- v-bind:給元素的內置屬性動態綁定數據,例如:給img綁定動態的圖片路徑地址
可以簡寫成爲:,也就是v-bind:src 等價於:src
- v-once:綁定的數據是一次性的, 後面不論數據怎麼改變,視圖也都不會重新渲染
- v-if:如果對應的值是TRUE,當前元素會在結構中顯示,如果是FALSE,當前元素會在結構中移除(它控制的是組件的加載和卸載的操作=>DOM的增加和刪除) ;還有對應的v-else-if /v-else等指令;
v-if: 控制元素的顯示隱藏;如果不是布爾,會默認轉成布爾;如果是false,直接刪除了原有的元素;
v-else-if: v-if成立就不走這個,if條件不成立走這個
v-else: v-else-if不成立走這個,成立不走,if連寫成立一個
- v-show:和v- if類似,只不過它是控制元素樣式的顯示隱藏(display的操作)
- v- if是控制組件存不存在,對於結果是FALSE,不存在的組件來說,視圖渲染的時候無需渲染這部分內容;而v-show則不行,因爲不管是顯示還是隱藏,結構都在,所以視圖渲染的時候這部分也要渲染;
- 在過於頻繁的切換操作中,v-if明顯要比v-show要低一些
- 通過設置布爾值來控制元素是否顯示,如果是true,則顯示,false,則隱藏;如果不是一個布爾值,那麼會默認轉布爾;通過設置元素的display屬性來控制是否顯示;
<body>
<div id="app">
<div v-text="x"></div>
<div v-html="x"></div>
<div v-show="1" r-yy="1">中國加油</div>
<div v-if="1===1">武漢加油</div>
<div v-else-if="3===3">天氣真好</div>
<div v-else>北京加油</div>
<input type="text" v-model="a">
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
// 指令: v-開頭,放在元素的行間屬性,有着特殊意義的一些詞;
// v-model:一般用於表單元素;將data中數據放在input框中,當input值發生改變,數據也會跟着發生改變;
// {{}}: 小鬍子語法可以將data中數據放入元素中
// v-text: 可以將data中的文本放入元素中
// v-html:可以識別標籤
// v-show :通過設置布爾值來控制元素是否顯示,如果是true,則顯示,false,則隱藏;如果不是一個布爾值,那麼會默認轉布爾;通過設置元素的display屬性來控制是否顯示;
// 以指令放在行間的屬性值,當編譯時,首先會去查找在vue的data中是否有這個屬性,如果沒有,就報錯;
// v-if: 控制元素的顯示隱藏;如果不是布爾,會默認轉成布爾;如果是false,直接刪除了原有的元素;
// v-else-if:
// v-else:
let vm = new Vue({
el:"#app",
data:{
a:1,
x:"<span>好好學習</span>"
}
})
</script>
</body>
</html>
2.v-for:循環動態綁定數據
- v-for:循環動態綁定數據( v-for="(item,index) in arr")
- 可以循環數字:item從1開始到當前數字, index從0開始
- 可以循環字符串:item是每一個字符,index索引
- 可以循環對象:item是屬性值,index是屬性名,第三個參是索引
- 可以循環數組:item是每一項,index是索引
<body>
<div id="app">
<!-- a 代表數組的每一項,index代表數組的索引 arr是data中一個變量-->
<!-- 需要創建什麼元素,就把v-for放在哪個元素身上 -->
<!-- v-for可以循環數字 -->
<div v-for="(a,index) in arr">{{a}}索引{{index}}</div>
<ul>
<!-- <li v-for="a in num">{{a}}</li> -->
<!-- 也可以循環字符串 -->
<!-- <li v-for="(a,index) in str">{{a}}索引{{index}}</li> -->
<!-- a是屬性值,b是屬性名 -->
<li v-for="(a,b,c) in obj">{{a}}{{b}}{{c}}</li>
<!-- <li v-for="a in ary">{{a.fruit}}</li> -->
</ul>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
// v-for : 可以循環數組,字符串,數字,對象
let vm = new Vue({
el:"#app",
data:{
arr:[100,200,300,400],
num:6,
str:"zhonghua",
obj:{name:"zfpx",age:10},
ary:[{fruit:"草莓"},{fruit:"蘋果"}]
}
})
</script>
</body>
v-for練習
<div id="app">
<ul>
<li v-for="(a,index) in fruits">
{{index+1}}.{{a.name}}
<ul>
<!--a 只在當前子集可以使用-->
<li v-for="(b,index) in a.color">
<!--index如果在這個循環中不存在,會向上一級循環查找;-->
{{index+1}}.{{b}}
</li>
</ul>
</li>
</ul>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
fruits: [{
name: "蘋果",
color: ["green", "red"]
}, {
name: "香蕉",
color: ["yellow", "green"]
}, {
name: "西瓜",
color: ["red", "white"]
}]
}
})
</script>
v-for要加:key
- 不加key當選中呂不爲時,添加楠楠後選中的確是李斯,並不是我們想要的結果,我們想要的是當添加楠楠後,一種選中的是呂不爲
- 加key同樣當選中呂不爲時,添加楠楠後依舊選中的是呂不爲。
- vue中列表循環需加:key=“唯一標識” 唯一標識可以是item裏面id index等,因爲vue組件高度複用增加Key可以標識組件的唯一性,爲了更好地區別各個組件 key的作用主要是爲了高效的更新虛擬DOM
<body>
<div id="app">
<div>
<input type="text" v-model="name">
<button @click="add">添加</button>
</div>
<ul>
<li v-for="(item, i) in list" :key="item.id">
<input type="checkbox"> {{item.name}}
</li>
</ul>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
// 創建 Vue 實例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
name: '',
newId: 3,
list: [
{ id: 1, name: '李斯' },
{ id: 2, name: '呂不韋' },
{ id: 3, name: '嬴政' }
]
},
methods: {
add() {
//注意這裏是unshift
this.list.unshift({ id: ++this.newId, name: this.name })
this.name = ''
}
}
});
</script>
</div>
</body>
</html>
3.v-bind :class :style
v-bind
將普通的屬性轉成動態的屬性,可以去獲取data中的數據;
v-bind:class :屬性是可以是對象,裏面的屬性名是class的名字,後面需要跟布爾值,屬性值時true,該樣式有效,false該樣式無效;如果是數組的話,是去獲取data中的屬性名對應的屬性值就是class的名字
v-bind:style: 後面可以是對象 數組 或者data中屬性名
<div id="app">
<!-- v-bind:可以省略 -->
<!-- <img :src="imgSrc" alt=""> -->
<!-- <div :a="imgSrc"></div> -->
<div v-bind:class="{x:flag}">中國</div>
<div v-bind:class="{x:flag,y:flag}">北京</div>
<!-- 如果是數組的話,是去獲取data中的屬性名對應的屬性值就是class的名字 -->
<div v-bind:class="a">中國</div>
<div v-bind:class="[a,b]">北京</div>
<ul>
<li v-for="(a,index) in arr" :class="{y:index%2}">{{a}}</li>
</ul>
<div v-bind:style="{fontSize:num+'px'}">加油</div>
<div v-bind:style='z'>666888</div>
<div :style="[z]">666888</div>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
// v-bind
// 1.將普通的屬性轉成動態的屬性,可以去獲取data中的數據;
// 2. v-bind:class :屬性是可以是對象,裏面的屬性名是class的名字,屬性值時true,該樣式有效,false該樣式無效
// 3. v-bind:style
new Vue({
el: "#app",
data: {
imgSrc: "../../images/16.jpg",
flag: true,
a: "x",
b: "y",
arr: [1, 2, 3, 4, 5],
num: 60,
z: {
color: "red"
}
},
methods: {
},
filters: {
}
});
</script>
4.v-model(表單)
v-model : 雙向數據綁定;一般用於表單元素
在單選框中,被選中的那一項,會把input框的value值賦值給sex;v-model的值如果在單選框中相同,他們就互斥;
多選框:v-model可以綁定一個數組,那麼當該項被選中時,會把該input框中value放到數組裏面;如果多選框v-model綁定的不是一個數組,那麼默認會將該值轉成布爾值,控制所有複選框的選中狀態
<body>
<div id="app">
<!-- <input type="text" v-model="msg"> -->
<!-- <input type="radio" v-model="sex" value="1">男
<input type="radio" v-model="sex" value="2">女
<input type="radio" v-model="food" value="3">水餃 -->
<input type="checkbox" v-model="hobby" value="游泳">游泳
<input type="checkbox" v-model="hobby" value="爬山">爬山
<input type="checkbox" v-model="hobby" value="打球">打球
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
// v-model : 雙向數據綁定;一般用於表單元素
// 在單選框中,被選中的那一項,會把input框的value值賦值給sex;v-model的值如果在單選框中相同,他們就互斥;
// 多選框:v-model可以綁定一個數組,那麼當該項被選中時,會把該input框中value放到數組裏面;如果多選框v-model綁定的不是一個數組,那麼默認會將該值轉成布爾值,控制所有複選框的選中狀態
let vm = new Vue({
el:"#app",
data:{
msg:"上課了",
sex:"1",//數字和字符串都可以
food:"3",
hobby:["游泳"]
//hobby:1
},
created(){
},
methods:{
},
filters:{
}
});
</script>
</body>
Vue優化指令
- v-pre : 跳過這個元素的編譯;加快了它的編譯過程
- v-cloak : 未編譯完,頁面看不到鬍子
- v-once : 只渲染一次;以後更改數據也不再更新了;
v-pre : 跳過這個元素的編譯;加快了它的編譯過程
v-cloak : 未編譯完,頁面看不到鬍子
這個指令保持在元素上直到關聯實例結束編譯。和 CSS 規則如 [v-cloak] { display: none } 一起用時,這個指令可以隱藏未編譯的 Mustache 標籤直到實例準備完畢。
[v-cloak] {
display: none;
}
v-once : 只渲染一次;以後更改數據也不再更新了;
當寫的結構時靜態的時候,可以使用這個指令;
<head>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id="app">
<button @click="fn">顯示/隱藏</button>
<div v-once>{{msg}}</div>
<br>
<div v-cloak>{{msg}}</div>
<ul>
<li>button1</li>
<li>button2</li>
<li>button3</li>
</ul>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
// v-pre : 跳過這個元素的編譯;加快了它的編譯過程
// v-cloak : 未編譯完,頁面看不到鬍子
// 這個指令保持在元素上直到關聯實例結束編譯。和 CSS 規則如 [v-cloak] { display: none } 一起用時,這個指令可以隱藏未編譯的 Mustache 標籤直到實例準備完畢。
// [v-cloak] {
// display: none;
// }
// v-once : 只渲染一次;以後更改數據也不再更新了;
// 當寫的結構時靜態的時候,可以使用這個指令;
let vm = new Vue({
el: "#app",
data: {
show: true,
msg: "你很好"
},
methods: {
fn() {
//this.show=!this.show;
this.msg = "你很帥"
}
}
})
</script>
</body>
Vue事件指令
- 給元素綁定的事件的方法,需要放在methods中
- 方式:v-on (簡寫@) :用來實現事件綁定的指令
- v-on:click=’ xxx’
- @click='xxx
<body>
<!--
v-on (簡寫@) :用來實現事件綁定的指令
v-on:click=' xxx'
@click='xxx
1.事件觸發的時候,需要傳遞參數信息,把方法加小括號,$event是事件對象
v-on:click='sum( $event,10,20)
2.事件修飾符
常規修飾符: @click . prevent/stop = 'xxx'
按鍵修飾符: @keydown. enter/space/delete/up/right/ down/left...=' xxx’
鍵盤碼: @keydown.13 = 'xxx'
組合按鍵: @keydown.al1t.67 = 'xxx’ //=>ALT+C
-->
<div id="app">
<a href="https://www.baidu.com/" @click.prevent.stop='func'>
666</a>
<!-- <button v-on:click='func' ></button> -->
<!-- <button v-on:click='sum( $event,10, 20)'></button> -->
<input type="text" placeholder="請輸入搜索內容" v-model="text" @keydown.alt.67="func">
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
text: ""
},
methods: {
func(ev) {
// console.log(this);
// if(ev.keyCode===13){
// alert("666")
// }
alert("666");
},
sum(ev, n, m) {
console.log(arguments);
}
}
})
</script>
</body>
vue的事件對象
-
綁定事件時,可以有小括號,也可以沒有
1.在綁定事件時,如果沒有小括號,那麼第一個參數就是事件對象
2. 如果有小括號,但是沒有傳參,那麼e默認是undefined;
3. 如果需要事件對象,並且需要傳參,那麼需要在綁定時使用$event進行佔位; -
事件觸發的時候,需要傳遞參數信息,把方法加小括號,$event是事件對象
- v-on:click=‘sum( $event,10,20)’
<div id="app">
<button @click="fn($event,100,200)">提交</button>
<input type="text" @keyup="fn">
{{msg}}
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
msg: "該喫飯了"
},
methods: {
// 綁定事件時,可以有小括號,也可以沒有
// 1.在綁定事件時,如果沒有小括號,那麼第一個參數就是事件對象
// 2. 如果有小括號,但是沒有傳參,那麼e默認是undefined;
// 3. 如果需要事件對象,並且需要傳參,那麼需要在綁定時使用$event進行佔位;
fn(e, a) { // e: 事件對象
console.log(e, a);
}
}
});
</script>
2.vue事件修飾符
- vue事件修飾符
常規修飾符: @click . prevent/stop = ‘xxx’
按鍵修飾符: @keydown. enter/space/delete/up/right/ down/left…=’ xxx’
鍵盤碼: @keydown.13 = ‘xxx’
組合按鍵: @keydown.alt.67 = 'xxx’ //=>ALT+C - vue常規事件修飾符:
- 原生JS中e.stopPropagation() => @click . stop="”
- 原生JS中e.stopPropagation() => @click . stop="”
.stop: 阻止事件的冒泡傳播; 從裏向外
.prevent: 阻止事件的默認行爲
.capture: 控制事件在捕獲階段執行 從外向裏
.once : 只執行一次
.passive: 修飾onscroll事件,不會等到onscroll執行完,就會立即執行下一次,提高代碼的性能;
.self:只有點擊自己的時候纔會執行
- 按鍵修飾符:
.enter .tab .delete .esc .space .up .down .left .right
<body>
<div id="app">
<div @click.capture="fn1" style="width:100px;height:100px;background: red;">
grandparent
<div @click.self="fn2">
parent
<div @click.once="fn3">
child
</div>
</div>
</div>
<input type="text" @keyup.left="fn">
<div @click="fn1">123456</div>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
// 原生JS中e.stopPropagation()
// 事件修飾符
// .stop: 阻止事件的冒泡傳播;
// .prevent: 阻止事件的默認行爲
// .capture: 控制事件在捕獲階段執行
// .once : 只執行一次
// .passive: 修飾onscroll事件,不會等到onscroll執行完,就會立即執行下一次,提高代碼的性能;
// .self:只有點擊自己的時候纔會執行
// 鍵盤修飾符:
// .enter .tab .delete .esc .space .up .down .left .right
let vm = new Vue({
el:"#app",
data:{
msg:"該喫飯了"
},
methods:{
fn1(){
console.log("outer");
},
fn2(){
console.log("inner");
},
fn3(){
console.log("center");
},
fn(){
console.log("快下課了");
}
}
});
// 1. button div:點擊按鈕隱藏,再點擊顯示
// 2. input 框,輸入內容,回車
</script>
</body>
Vue自定義指令
- Vue除了核心的內置指令,vue還可以自定義指令
- 自定義指令:
- 全局自定義指令
- 局部自定義指令
<body>
<div id="app">
<div v-drag style="width:100px;height:100px;background: red;position: absolute;">
<div v-drag></div>
</div>
</div>
<script src="../node_modules/vue/dist/vue.js"></script>
<script>
// 全局指令
Vue.directive("drag", {
inserted: function (ele) {
ele.onmousedown = function (e) {
// this -->
// 點擊時,記錄鼠標距離盒子邊框的位置
this.l = e.clientX - this.offsetLeft;
this.t = e.clientY - this.offsetTop;
document.onmousemove = function (e) {
ele.style.left = e.clientX - ele.l + "px";
ele.style.top = e.clientY - ele.t + "px";
}
document.onmouseup = function () {
document.onmousemove = null;
document.onmouseup = null;
}
}
console.log(1);
}
});
let vm = new Vue({
el: "#app",
directives: {
// 定義局部指令 局部命令優先級高
drag(ele) { // ele: 代表加上v-drag的元素 drag 用了幾次,輸出幾次;
ele.onmousedown = function (e) {
// this -->
// 點擊時,記錄鼠標距離盒子邊框的位置
this.l = e.clientX - this.offsetLeft;
this.t = e.clientY - this.offsetTop;
document.onmousemove = function (e) {
ele.style.left = e.clientX - ele.l + "px";
ele.style.top = e.clientY - ele.t + "px";
}
document.onmouseup = function () {
document.onmousemove = null;
document.onmouseup = null;
}
}
}
}
});
// let vm1 = new Vue({
// el:"#app1"
// });
</script>
</body>