Vue3官網-深入組件(四)模板參考(ref 和 $refs)、處理邊界情況( v-once)
文章目錄
- Vue3官網-深入組件(四)模板參考(ref 和 $refs)、處理邊界情況( `v-once`)
- 1. 模板參考(ref 和 $refs)
- 1.1 vue中的 ref 和 $refs
- 1.1.1 ref作用于組件
- 1.1.2 ref作用于Html標簽
- 1.1.3 $nextTick()
- 1.1.4 使用Vue.nextTick()
- 1.2 模板參考
- 2. 處理邊界情況( `v-once`)
- 控制更新
- 強制更新
- 低級靜態組件與 `v-once`
總結:
補充
Vue (讀音 /vju?/,類似于 view) 是一套用于構建用戶界面的漸進式框架,與其它大型框架不同的是,Vue 被設計為可以自底向上逐層應用,Vue 的核心庫只關注視圖層,不僅易于上手,還便于與第三方庫或既有專案整合,
truthy(真值):在 JavaScript 中,truthy(真值)指的是在布林值背景關系中,轉換后的值為真的值,所有值都是真值,除非它們被定義為 假值(即除
false、0、""、null、undefined和NaN以外皆為真值),括號內都是假值falsy,.prevent 修飾符告訴 v-on 指令對于觸發的事件呼叫 event.preventDefault()
==Event.preventDefault方法取消瀏覽器對當前事件的默認行為,==比如點擊鏈接后,瀏覽器默認會跳轉到另一個頁面,使用這個方法以后,就不會跳轉了;再比如,按一下空格鍵,頁面向下滾動一段距離,使用這個方法以后也不會滾動了,該方法生效的前提是,事件物件的cancelable屬性為true,如果為false,呼叫該方法沒有任何效果,
vue:用組件(app.component)構建一個模板(template),并反復使用模板
父組件、子組件
const app = Vue.createApp({ components: { 'component-a': ComponentA, 'component-b': ComponentB } })上面代碼中app為父組件,ComponentA和ComponentB為子組件
Vue中美元$符號的意思
- 除了資料屬性,Vue 實體還暴露了一些有用的實體屬性與方法,它們都有前綴
$,以便與用戶定義的屬性區分開來,- vue中$refs的作用?
- 當我們需要獲取一個dom元素進行操作的時候 可以利用原生js的getElementByXxx 而在vue中可以設定refs來獲取這個dom元素
1. 模板參考(ref 和 $refs)
1.1 vue中的 ref 和 $refs
你應該學過jquery吧,沒用vue之前,我前端框架是用JS+Jquery+Bootstrap,因為不是資料驅動,為了獲取某些元素的value,我常常會使用Jquery.
$("#id").text('xxx') // 使用Jquery
document.getElementById("id") // 使用原生Dom
現在我們牛逼了,我們用vue,那vue中,如果我要獲取Dom,該怎么做?
這就進入本文的主題ref, $refs,官網解釋:
官網解釋
1.1.1 ref作用于組件
<div id="app">
<navbar></navbar>
<pagefooter></pagefooter>
</div>
Vue.component('navbar',{
template:'#navbar',
data:function () {
return {
navs:[]
}
}
});
Vue.component('pagefooter',{
template:'#pagefooter',
data:function () {
return {
footer:''
}
}
});
new Vue({
el:'#app',
mounted:function () {
//ready,
//這里怎么直接訪問navbar的navs和pagefooter的footer值呢,
}
})
這就用到ref了
修改組件
<div id="app">
<navbar ref="navbar"></navbar>
<pagefooter ref="pagefooter"></pagefooter>
</div>
new Vue({
el:'#app',
mounted:function () {
//ready,
//這里怎么直接訪問navbar的navs和pagefooter的footer值呢,
console.log(this.$refs.navbar.navs);
console.log(this.$refs.pagefooter.footer);
}
})
通過ref和refs,父組件可以輕松獲取子組件的資訊,很簡單!
1.1.2 ref作用于Html標簽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<p ref="thisP">{{name}}</p></div>
<script>
var vm = new Vue({
data:{
name:'小小陳先森'
}
}).$mount("#app")
// vm.name='Tom';
console.log(vm.$refs.thisP.textContent);
//vm.$nextTick(function () {
// console.log(vm.$refs.thisP.textContent);
//})
</script>
</body>
</html>
上面這個例子可以獲取P標簽中的文本資訊,這樣就不需要給P標簽設一個id,再document.getElementById('xx),這相當麻煩,
1.1.3 $nextTick()
<script>
var vm = new Vue({
data:{
name:'小小陳先森'
}
}).$mount("#app")
vm.name='Tom';
console.log(vm.$refs.thisP.textContent);
vm.$nextTick(function () {
console.log(vm.$refs.thisP.textContent);
})
</script>
控制臺顯示
看控制臺輸出,明明給name賦值‘Tom’,為啥還會列印出‘小小陳先森’,name賦值‘Tom’沒錯,但更新到Dom這個程序是異步的(根本原因是因為Vue中DOM更新是異步的).
所以當你列印console.log(vm.$refs.thisP.textContent);時,此時標簽的文本內容還是‘小小陳先森’,
但我想獲取Dom更新的資料啊,我想獲取到的是’Tom’,怎么辦?
1.1.4 使用Vue.nextTick()
在下次 DOM 更新回圈結束之后執行延遲回呼,在修改資料之后立即使用這個方法,獲取更新后的 DOM.
this.$nextTick(() => {
console.log(vm.$refs.thisP.textContent);
})
1.2 模板參考
該頁面假設你已經閱讀過了組件基礎,如果你還對組件不太了解,推薦你先閱讀它,
盡管存在 prop 和事件,但有時你可能仍然需要直接訪問 JavaScript 中的子組件,為此,可以使用 ref attribute 為子組件或 HTML 元素指定參考 ID,例如:
<input ref="input" />
例如,你希望在組件掛載時,以編程的方式 focus 到這個 input 上,這可能有用
此外,還可以向組件本身添加另一個 ref,并使用它從父組件觸發 focusInput 事件:
<base-input ref="usernameInput"></base-input>
this.$refs.usernameInput.focusInput()
WARNING
$refs只會在組件渲染完成之后生效,這僅作為一個用于直接操作子元素的“逃生艙”——你應該避免在模板或計算屬性中訪問$refs,
參考:在組合式 API 中使用 template refs
2. 處理邊界情況( v-once)
該頁面假設你已經閱讀過了組件基礎,如果你還對組件不太了解,推薦你先閱讀它,
提示
這里記錄的都是和處理邊界情況有關的功能,即一些需要對 Vue 的規則做一些小調整的特殊情況,不過注意這些功能都是有劣勢或危險的場景的,我們會在每個案例中注明,所以當你使用每個功能的時候請稍加留意,
控制更新
得益于其回應性系統,Vue 總是知道何時更新 (如果你使用正確的話),但是,在某些邊緣情況下,你可能希望強制更新,盡管事實上沒有任何回應式資料發生更改,還有一些情況下,你可能希望防止不必要的更新,
強制更新
如果你發現自己需要在 Vue 中強制更新,在 99.99%的情況下,你在某個地方犯了錯誤,例如,你可能依賴于 Vue 回應性系統未跟蹤的狀態,比如在組件創建之后添加了 data 屬性,
但是,如果你已經排除了上述情況,并且發現自己處于這種非常罕見的情況下,必須手動強制更新,那么你可以使用 $forceUpdate,
低級靜態組件與 v-once
在 Vue 中渲染純 HTML 元素的速度非常快,但有時你可能有一個包含很多靜態內容的組件,在這些情況下,可以通過向根元素添加 v-once 指令來確保只對其求值一次,然后進行快取,如下所示:
app.component('terms-of-service', {
template: `
<div v-once>
<h1>Terms of Service</h1>
... a lot of static content ...
</div>
`
})
TIP
再次提醒,不要過度使用這種模式,雖然在需要渲染大量靜態內容的極少數情況下使用這種模式會很方便,但除非你注意到先前的渲染速度很慢,否則就沒有必要這樣做,另外,過度使用這種模式可能會在以后引起很多混亂,例如,假設另一個開發人員不熟悉
v-once或者只是在模板中遺漏了它,他們可能會花上幾個小時來弄清楚為什么模板沒有正確更新,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/301779.html
標籤:其他
