前言
Vue爲我們提供了很多內置指令,如 v-bind, v-on,v-text等等。但是有時候我們需要自己定義一些我們自己的指令來實現我們自己的功能。
下面我們就來看看如何自定義指令:
自定義全局指令
案例一:自定義全局v-focus指令
自定義一個指令來實現讓文本框獲取焦點 ,同時元素賦給值
<html>
<head>
<script src="~/Scripts/vue.js"></script>
</head>
<body>
<div id="app">
使用自定義v-focus指令:<input type="text" v-focus/>
</div>
<script>
//自定義一個全局指令:名字爲focus 在調用的時候,必須在指令前加上 v- 來進行調用(vue規定)
Vue.directive('focus', {
//參數element是這個指令所綁定的元素,例如:<input type="text" v-focus /> 那麼這個element就是這個input元素(這個元素就是一個原生的JS對象)
bind: function (element) {
//每當指令綁定到元素上的時候,會立即執行這個bind函數,只執行一次
//在元素剛綁定指令的時候,此時元素還沒有插入到DOM中去,此時還元素還在內存當中,所有此時調用元素(原生JS對象)的事件方法是無效的
//只有在元素插入到DOM之後,調用這個元素(原生JS對象)事件方法纔有效
//element.focus();
},
inserted: function (element) {
// 單元素插入到DOM中的時候,會執行這個inserted函數 (觸發一次)
// 每當指令綁定到元素上的時候,如果執行到inserted方法的時候,說明這個元素從內存加載到渲染到頁面的工作已經做完了,
// 此時我們調用一下元素的focus事件,就可以獲取焦點了
element.focus(); //獲取焦點
element.value = "你好,元素"; //既然這個element是一個原生JS對象,那麼我們就可以像操作JS一樣來操作這個對象了,比如可以給他賦值
},
updated: function (element) {
//當VNode更新的時候,會執行這個updated函數,可能會觸發多次
}
})
var vm = new Vue({
el: "#app",
data: {
name: '',
},
methods: {
add: function (name) { alert(name) },
},
filters: {
}
})
</script>
</body>
</html>
案例二:自定義全局 v-color指令
案例2.1 不帶參數的指令
<html>
<head>
<script src="~/Scripts/vue.js"></script>
</head>
<body>
<div id="app">
使用自定義v-color指令:<input type="text" v-color/>
</div>
<script>
//自定義一個全局指令:名字爲color 在調用的時候,必須在指令前加上 v- 來進行調用(vue規定)
Vue.directive('color', {
//參數element是這個指令所綁定的元素,例如:<input type="text" v-color /> 那麼這個element就是這個input元素(這個元素就是一個原生的JS對象)
bind: function (element) {
//每當指令綁定到元素上的時候,會立即執行這個bind函數,只執行一次
//在元素剛綁定指令的時候,此時元素還沒有插入到DOM中去,此時還元素還在內存當中,所有此時調用元素(原生JS對象)的事件方法是無效的
//只有在元素插入到DOM之後,調用這個元素(原生JS對象)事件方法纔有效
//element.focus(); //無效
//但是這裏是可以設置樣式
//樣式與事件不同,樣式,只要通過指令綁定給了元素,不管這個元素有沒有被插入到頁面中去,這個元素肯定有了一個內聯的樣式
//將來元素肯定會被顯示到頁面,這時候瀏覽器的渲染引擎比如會解析樣式,應用給這個元素
element.style.color = 'red';
},
inserted: function (element) {
},
updated: function (element) {
}
})
var vm = new Vue({
el: "#app",
data: {
}
})
</script>
</body>
</html>
案例2.2 帶參數的指令
https://cn.vuejs.org/v2/guide/custom-directive.html#鉤子函數參數
<html>
<head>
<script src="~/Scripts/vue.js"></script>
</head>
<body>
<div id="app">
使用自定義v-color指令:<input type="text" v-color="'yellow'"/> <!--注意:此時yellow需要用單引號引起來-->
</div>
<script>
//自定義一個全局指令:名字爲color 在調用的時候,必須在指令前加上 v- 來進行調用(vue規定)
Vue.directive('color', {
//參數element是這個指令所綁定的元素,例如:<input type="text" v-color /> 那麼這個element就是這個input元素(這個元素就是一個原生的JS對象)
//參數colour是我們自定義指令的綁定值
bind: function (element, colour) {
//每當指令綁定到元素上的時候,會立即執行這個bind函數,只執行一次
//在元素剛綁定指令的時候,此時元素還沒有插入到DOM中去,此時還元素還在內存當中,所有此時調用元素(原生JS對象)的事件方法是無效的
//只有在元素插入到DOM之後,調用這個元素(原生JS對象)事件方法纔有效
//element.focus(); //無效
//但是這裏是可以設置樣式
//樣式與事件不同,樣式,只要通過指令綁定給了元素,不管這個元素有沒有被插入到頁面中去,這個元素肯定有了一個內聯的樣式
//將來元素肯定會被顯示到頁面,這時候瀏覽器的渲染引擎比如會解析樣式,應用給這個元素
element.style.color = colour.value;
console.log(colour.name); //輸出color 【指我們自定義指令的名稱】
console.log(colour.value); //輸出 yellow 【指令的綁定值】
console.log(colour.expression) //輸出 'yellow' 【指令綁定值的字符串形式】
},
inserted: function (element, colour) {
},
updated: function (element, colour) {
}
})
var vm = new Vue({
el: "#app",
data: {
}
})
</script>
</body>
</html>
自定義私有指令
<html>
<head>
<script src="~/Scripts/vue.js"></script>
</head>
<body>
<div id="app">
使用自定義v-color指令:<input type="text" v-color="'red'" v-fontweight="900"/> <!--注意:此時yellow需要用單引號引起來-->
使用自定義v-fontweight指令:<p v-fontweight="900" >你好中國</p> <!--注意:數字不需要用單引號引起來-->
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
},
directives: { //這裏面是自定義私有指令的地方
"color": { //定義一個v-color指令:實現自定義字體顏色
bind: function (element, colour) {
element.style.color = colour.value;
}
},
"fontweight": { //定義一個v-fontweight指令:實現自定義字體粗細
bind: function (element, bingding) {
element.style.fontWeight = bingding.value;
}
}
}
})
</script>
</body>
</html>
自定義指令的簡寫
大多數情況下,我們可能想在bind 和update鉤子函數上做重複動作,並不想關心其他的鉤子函數,我們就可以簡寫
自定義全局指令的簡寫
<html>
<head>
<script src="~/Scripts/vue.js"></script>
</head>
<body>
<div id="app">
使用自定義v-color指令:
<input type="text" v-color="'red'" />
<div></div>
<!--注意:此時yellow需要用單引號引起來-->
</div>
<script>
//這個function等同於 同時把函數中的代碼寫到了bind 和 update 函數中去了
Vue.directive("color", function (element, colour) {
element.style.backgroundColor = colour.value;
})
//上面的這段代碼等同於下面這段代碼
Vue.directive("color", {
bind: function (element, colour) {
element.style.backgroundColor = colour.value;
},
updated: function (element, colour) {
element.style.backgroundColor = colour.value;
}
})
var vm = new Vue({
el: "#app",
})
</script>
</body>
</html>
自定義私有指令的簡寫
<html>
<head>
<script src="~/Scripts/vue.js"></script>
</head>
<body>
<div id="app">
使用自定義v-color指令:<input type="text" v-color="'red'" /> <!--注意:此時yellow需要用單引號引起來,如果是純數組則不需要用單引號引起來-->
使用自定義v-fontsize指令: <p v-fontsize="'50px'">你好中國</p> <!--注意:此時50px需要用單引號引起來,如果是純數組則不需要用單引號引起來-->
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
},
directives: { //這裏面是自定義私有指令的地方
//私有指令定義的正常寫法
"color": { //定義一個v-color指令:實現自定義字體顏色
bind: function (element, colour) {
element.style.color = colour.value;
},
inserted: function (element, colour) {
},
updated: function (element, colour) {
}
},
//私有指令定義的簡寫:這個function等同於 同時把函數中的代碼寫到了bind 和 update 函數中去了
"fontsize": function (element, bingding) { //定義一個v-fontsize指令:實現自定義字體大小
//element.style.fontSize = bingding.value;
//在設置字體大小的時候,程序員本意是想設置一個50px大小的字體,但是程序員可能存在忘記寫px了
//爲了防止這種情況發生,我們可以用以下方式防止下
element.style.fontSize = parseInt(bingding.value) + 'px'; //即便程序員寫了 50px,但是通過parseInt方法後,50px也會變成50,然後我們手動給他加個px 就兼容啦
}
}
})
</script>
</body>
</html>
總結
在我們自定義vue指令的時候:
和Js事件有關的操作,一般在inserted 函數中去執行,防止JS行爲不生效
和Js樣式有關的操作,一般都可以在bind函數中執行(當然你如果想放在inserted中去執行也是可以的)