注冊網(wǎng)站亂填郵箱廣州搜索seo網(wǎng)站優(yōu)化
二、自定義指令
1.指令介紹
-
內(nèi)置指令:v-html、v-if、v-bind、v-on… 這都是Vue給咱們內(nèi)置的一些指令,可以直接使用
-
自定義指令:同時Vue也支持讓開發(fā)者,自己注冊一些指令。這些指令被稱為自定義指令
每個指令都有自己各自獨立的功能
2.自定義指令
概念:自己定義的指令,可以封裝一些DOM操作,擴(kuò)展額外的功能
3.自定義指令語法
-
全局注冊
//在main.js中 Vue.directive('指令名', {"inserted" (el) {// 可以對 el 標(biāo)簽,擴(kuò)展額外功能,inserted表示綁定的組件一經(jīng)渲染就會觸發(fā)相應(yīng)的代碼el.focus()} })
-
局部注冊
//在Vue組件的配置項中 directives: {"指令名": {inserted () {// 可以對 el 標(biāo)簽,擴(kuò)展額外功能el.focus()}} }
-
使用指令
注意:在使用指令的時候,一定要先注冊,再使用,否則會報錯
使用指令語法: v-指令名。如:注冊指令時不用加v-前綴,但使用時一定要加v-前綴
4.指令中的配置項介紹
inserted:被綁定元素插入父節(jié)點時調(diào)用的鉤子函數(shù)
el:使用指令的那個DOM元素
5.代碼示例
需求:當(dāng)頁面加載時,讓元素獲取焦點(autofocus在safari瀏覽器有兼容性)
App.vue
<div><h1>自定義指令</h1><input v-focus ref="inp" type="text"></div>
6.總結(jié)
1.自定義指令的作用是什么?
2.使用自定義指令的步驟是哪兩步?
三、自定義指令-指令的值
1.需求
實現(xiàn)一個 color 指令 - 傳入不同的顏色, 給標(biāo)簽設(shè)置文字顏色
2.語法
1.在綁定指令時,可以通過“等號”的形式為指令 綁定 具體的參數(shù)值
<div v-color="color">我是內(nèi)容</div>
2.通過 binding.value 可以拿到指令值,指令值修改會 觸發(fā) update 函數(shù)
directives: {color: {inserted (el, binding) {el.style.color = binding.value},update (el, binding) {el.style.color = binding.value}}
}
3.代碼示例
App.vue
<template><div><!--顯示紅色--> <h2 v-color="color1">指令的值1測試</h2><!--顯示藍(lán)色--> <h2 v-color="color2">指令的值2測試</h2><button>改變第一個h1的顏色</button></div>
</template><script>
export default {data () {return {color1: 'red',color2: 'blue'}}
}
</script><style></style>
四、自定義指令-v-loading指令的封裝
1.場景
實際開發(fā)過程中,發(fā)送請求需要時間,在請求的數(shù)據(jù)未回來時,頁面會處于空白狀態(tài) => 用戶體驗不好
2.需求
封裝一個 v-loading 指令,實現(xiàn)加載中的效果
3.分析
1.本質(zhì) loading效果就是一個蒙層,蓋在了盒子上
2.數(shù)據(jù)請求中,開啟loading狀態(tài),添加蒙層
3.數(shù)據(jù)請求完畢,關(guān)閉loading狀態(tài),移除蒙層
4.實現(xiàn)
1.準(zhǔn)備一個 loading類,通過偽元素定位,設(shè)置寬高,實現(xiàn)蒙層
2.開啟關(guān)閉 loading狀態(tài)(添加移除蒙層),本質(zhì)只需要添加移除類即可
3.結(jié)合自定義指令的語法進(jìn)行封裝復(fù)用
.loading:before {content: "";position: absolute;left: 0;top: 0;width: 100%;height: 100%;background: #fff url("./loading.gif") no-repeat center;
}
5.準(zhǔn)備代碼
<template><div class="main"><div class="box" v-loading="isLoading"><ul><li v-for="item in list" :key="item.id" class="news"><div class="left"><div class="title">{{ item.title }}</div><div class="info"><span>{{ item.source }}</span><span>{{ item.time }}</span></div></div><div class="right"><img :src="item.img" alt=""></div></li></ul></div> </div>
</template><script>
// 安裝axios => yarn add axios || npm i axios
import axios from 'axios'// 接口地址:http://hmajax.itheima.net/api/news
// 請求方式:get
export default {directives: {loading: {inserted(el,binding){binding.value ? el.classList.add('loading') : el.classList.remove('loading')},update(el,binding){binding.value ? el.classList.add('loading') : el.classList.remove('loading')}}},data () {return {list: [],isLoading: false,isLoading2: false}},async created () {// 1. 發(fā)送請求獲取數(shù)據(jù)const res = await axios.get('http://hmajax.itheima.net/api/news')setTimeout(() => {// 2. 更新到 list 中,用于頁面渲染 v-forthis.list = res.data.data}, 2000)this.isLoading = false}
}
</script><style>
.loading:before {content: '';position: absolute;left: 0;top: 0;width: 100%;height: 100%;background: #fff url('./loading.gif') no-repeat center;
}.box2 {width: 400px;height: 400px;border: 2px solid #000;position: relative;
}.box {width: 800px;min-height: 500px;border: 3px solid orange;border-radius: 5px;position: relative;
}
.news {display: flex;height: 120px;width: 600px;margin: 0 auto;padding: 20px 0;cursor: pointer;
}
.news .left {flex: 1;display: flex;flex-direction: column;justify-content: space-between;padding-right: 10px;
}
.news .left .title {font-size: 20px;
}
.news .left .info {color: #999999;
}
.news .left .info span {margin-right: 20px;
}
.news .right {width: 160px;height: 120px;
}
.news .right img {width: 100%;height: 100%;object-fit: cover;
}
</style>