模板語法 插值語法 Mustache插值採用{{ }},用於解析標簽體內容,將Vue實例中的數據插入DOM中 <h1>Hello {{name}}</h1> 指令語法 指令用於解析標簽,是vue為開發者提供的一套模板語法,輔助開發者渲染頁面的基本結構。 (指令是vue開發中最基礎、最常用、最簡單的知 ...
模板語法
插值語法
Mustache插值採用{{ }}
,用於解析標簽體內容,將Vue實例中的數據插入DOM中
<h1>Hello {{name}}</h1>
指令語法
指令用於解析標簽,是vue為開發者提供的一套模板語法,輔助開發者渲染頁面的基本結構。
(指令是vue開發中最基礎、最常用、最簡單的知識點)(支持綁定簡單的數據值之外,還支持js表達式運算)
內容渲染指令
1、v-text=" "
會覆蓋元素內預設的值、無法寫HTML標簽語句
2、{{ }}
插值表達式(Mustache) 不會覆蓋元素中預設的內容
3、v-html
可以渲染包含HTML標簽的字元串
v-html
有安全性問題,在網站上動態渲染任意HTML是非常危險的,容易導致XSS攻擊;永遠不要再用戶提交的內容上使用v-html
。
屬性綁定指令
v-bind:
為元素的屬性動態綁定屬性值
屬性:placeholder、src等
簡寫::
<a v-bind:href="url">點擊跳轉</a>
<a :href="url">點擊跳轉</a>
事件綁定指令
v-on:
為DOM元素綁定事件監聽
v-on:click=” “、v-on:input、v-on:keyup
事件處理函數,需要在methods節點中進行聲明
簡寫:@、如果事件處理函數的代碼足夠簡單,只有一行代碼,則可以簡寫到行內
事件對象event
<body>
<div id="app">{{username}}</div>
<button @click="addcount($event,88)">
點擊我
</button>
<script src="vue.js"></script>
<script>
const vm=new Vue({
el:'#app',
data:{
username:'zs',
count:0
},
methods:{
addcount(e,88){
const nowBgColor =e.target.style.backgroundColor
console.log(nowB gColor)
this.count+=1
}
}
})
</script>
</body>
綁定事件並傳參,使用() 小括弧,但會占用event的位置
$event是vue提供的特殊變數用於占位,用來表示原生事件參數對象event,使用e接受
事件修飾符
vue提供事件修飾符,來輔助程式員更方便的對事件的觸發進行控制
-
.stop
阻止事件冒泡()里到外 -
.prevent
阻止預設行為()比如阻止跳轉 -
.capture
以捕獲模式觸發當前事件處理函數(外到里) -
.self
只有在event.target是當前元素自身時觸發事件處理函數 -
.once
綁定的事件只觸發一次 -
.passive
事件的預設行為立即執行,無需等待事件回調執行完畢
按鍵修飾符
監聽鍵盤事件時,我們經常需要判斷詳細的按鍵,此時可為鍵盤相關的事件添加按鍵修飾符
- .enter、.delete、.esc、.space、.tab(特殊:只適用於keydown)、.up、.down、.left、.right
- 系統修飾符(用法特殊):ctrl、alt、shift、mta 配合keyup使用:按下按鍵的同時需要再按下其他鍵,隨後事件才被觸發;keydown正常觸發事件
- 也可以使用keyCode去指定具體的按鍵(不推薦)
- Vue.config.keyCodes.自定義鍵名=鍵碼 可以去定製按鍵別名
雙向綁定指令
v-model 在不操作DOM的情況下,快速獲取表單數據(只能配合表單元素一起使用)
<input type="text" v-model:value="username"/>
<input type="text" v-model="username"/>
v-model 指令的修飾符
方便用戶對輸入的內容進行處理
.number
自動將用戶輸入值轉化為數值.trim
自動過濾用戶輸入的首尾空白字元.lazy
在change時更新而非input時更新(不實時更新,文本框失去焦點更新)
條件渲染指令
按需控制DOM的顯示和隱藏
v-if =" "
動態創建或移除DOM元素,有更高的切換開銷(重繪和迴流)
v-else-if =" "
、v-else =" "
v-show=" "
動態為元素添加或移除display樣式,有更高的初始渲染開銷。
列表渲染指令
v-for=" "
輔助開發者基於一個數組來迴圈渲染相似的UI結構
特殊語法:item in items
<body>
<div id="root">
<!-- 遍曆數組 -->
<ul>
<li v-for="item in persons" :key="item.id">
{{item.id}}-{{item.name}}-{{item.age}}
</li>
</ul>
<!-- 遍歷對象 -->
<ul>
<li v-for="(value,key) of cars" :key="key">
{{key}}-{{value}}
</li>
</ul>
<!-- 遍歷字元串 -->
<ul>
<li v-for="(char,index) of str" :key="index">
{{index}}-{{char}}
</li>
</ul>
<!-- 遍歷指定次數 -->
<ul>
<li v-for="(number,index) of 5" :key="index">
{{index}}-{{number}}
</li>
</ul>
</div>
<script type="text/javascript">
Vue.config.productionTip = false;
const vm=new Vue({
el:'#root',
data:{
persons:[
{id:'001',name:'張三',age:18},
{id:'002',name:'李四',age:17},
{id:'003',name:'王五',age:42},
],
cars:{
name:'Audi',
price:"70W",
color:"black"
},
str:"hello"
}
})
</script>
</body>
for in和for of
for in一般遍歷對象,不建議遍曆數組。遍曆數組請使用for of或forEach。
v-for中的索引
(item,index) in items
註:v-for中的item項和index索引都是形參,任意命名
key作用和原理
當列表的數據變化(添加、刪除)時,vue會儘可能復用已存在的DOM元素,從而提升渲染的性能,但這種性能優化策略會導致有狀態的列表無法被正確更新,key的使用將減少不必要的DOM操作,提高更新效率。
解釋:
Vue根據初始數據生成初始虛擬DOM(Vnodes),將虛擬DOM轉為真實DOM,用戶添加新的數據,產生新虛擬DOM(Vnodes),此時將兩份虛擬DOM根據key進行對比(diff 演算法),如果對比一樣的直接復用,將之前的真實DOM直接渲染;不一樣的無法復用,將其生成真實DOM。
- 如果使用index作為key,diff對比時會完全錯位,所有節點都無法復用,效率降低。
- 如果不指定key時,vue自動使用遍歷時的索引值index作為key。
為了給vue一個提示,以便它能跟蹤每個節點的身份,需要為每項提供一個唯一的key屬性
註:
-
key只能是字元串或數字類型
-
key的值必須具有唯一性
-
建議把數據項id屬性的值作為key的值,將index的值作為key的值沒有任何意義(https://blog.csdn.net/z591102/article/details/106682298/)
-
建議使用v-for時一定要指定key的值(提升性能,防止列表狀態紊亂)
-
但不存在對數據的操作,僅是渲染列表用於展示,使用index作為key沒有問題
其他內置指令
v-cloak
沒有值,配合CSS,解決網速慢、伺服器響應慢時未經解析的模板渲染到頁面上,Vue實例創建並接管容器後,會刪掉該屬性。
[v-cloak]:{
display:none;
}
v-once
沒有值,記錄初始值,在初次動態渲染後,就視為靜態內容,以後數據的改變不會引起v-once
所在結構的更新,可以用於性能優化。
v-pre
沒有值,跳過其所在節點的編譯過程,可以用它跳過:沒有使用指令語法、插值語法的節點,會加快編譯。
自定義指令
本質:將原生操作DOM進行二次封裝。
<body>
<div id="root">
<!-- v-big放大10倍 -->
<h2>當前的n值是:<span v-text="n"></span></h2>
<h2>放大10倍後的n值是:<span v-big="n"></span></h2>
<button @click="n++">點位n++</button>
<hr>
<!-- v-fbind在v-bind基礎上,自動獲得焦點 -->
<input type="text" v-fbind:value="n">
</div>
<script type="text/javascript">
Vue.config.productionTip = false;
const vm=new Vue({
el:'#root',
data:{
n:0,
},
directives:{
//函數式
//何時會被調用:1、指令和元素成功綁定;2、指令所在的模板被重新解析時
big(element,binding){
element.innerText=binding.value*10
},
//錯誤寫法:
fbind(element,binding){
element.value=binding.value
element.focus()//.focus()調用時機不對,此時input還未被插入頁面
},
//對象式
fbind:{
//指令與元素成功綁定時調用
bind(element,binding){
element.value=binding.value
},
//指令所在元素被插入頁面時調用
inserted(element,binding){
element.focus()
},
//指令所在模板被重新解析時調用
update (element,binding) {
element.value=binding.value
},
}
},
})
</script>
</body>
註意:
- 命名多個單詞使用
-
分隔; - 指令中
this
的指向是window
; - 自定義指令預設都是局部指令,全局寫法:
Vue.directive
;
計算屬性
計算屬性本質上就是一個function函數,它可以實時監聽data中數據的變化,並return一個計算後的新值,供組件渲染DOM時使用。
開發者需要以function函數的形式聲明到組件的computed節點中
<template>
<div>
<input type="text" name="" id="" v-model.number="count">
<p>{{count}} 乘以2的值為:{{plus}}</p>//必須當做普通屬性使用
</div>
</template>
<script>
export default {
name:'MyCount',
data(){
return{
count:1,
}
},
//必須定義在computed節點
computed:{
//必須是一個function函數
plus(){
//必須具有返回值
return this.count*2
}
//相當於
plus:{
//當讀取plus,get會被調用,且返回值作為plus的值
//get何時被調用?1、初次調用plus;2、所依賴的數據發生變化
get(){
return this.count*2
}
}
}
}
</script>
側重於得到一個計算的結果,必須有return返回值
計算屬性(computed)vs方法(methods):
相對於方法,計算屬性會緩存計算結果,只有計算屬性的依賴項發生變化時,才會重新進行運算,因此計算屬性的性能會更好。
watch偵聽器
watch偵聽器允許開發者監視數據的變化,從而針對數據的變化做特定的操作
開發者需要在watch節點之下,定義自己的偵聽器
<script>
export default {
name:'MyCount',
data(){
return{
username:'',
}
},
watch:{
//當username發生改變時,調用 handler
username:{
handler(newVal,oldVal){
console.log(newVal,oldVal)
}
}
//簡寫
username(newVal,oldVal){
console.log(newVal,oldVal)
}
}
}
</script>
<body>
<div id="app">{{username}}</div>
#導入腳本文件
<script src="vue.js"></script>
<script>
const vm=new Vue({
data(){
return{
username:'zs'
}
}
})
vm.$mount=('#app')//掛載
vm.$wtach('username',{ //第二種寫法
handler(newVal,oldVal){
console.log(newVal,oldVal)
}
})
//簡寫
vm.$wtach('username',function(newVal,oldVal){
console.log(newVal,oldVal)
}
})
</script>
</body>
應用場景
使用watch檢測用戶名是否可用,監聽username值得變化,並使用axios發起ajax請求,檢測當前輸入的用戶名是否可用
<script>
import axios from 'axios'
export default {
name:'MyCount',
data(){
return{
username:'',
}
},
watch:{
async username(newVal,oldVal){
console.log(newVal,oldVal)
const {data:res}=await axios.get('https://www.escook.cn/api/finduser'+newVal)
//await簡化promise實例對象為數據
console.log(res)
}
}
}
</script>
immediate選項
預設組件在初次載入完畢後不會調用watch偵聽器,如果想讓watch偵聽器立即被調用,則需要使用immediate選項
<script>
import axios from 'axios'
export default {
name:'MyCount',
data(){
return{
username:'',
}
},
watch:{
//不能直接定義成方法,要讓監聽的數據指向一個配置對象
username:{
async handler(newVal,oldVal){
const {data:res}=await axios.get('https://www.escook.cn/api/finduser'+newVal)
//await簡化promise實例對象為數據
console.log(res)
},
//立即觸發watch偵聽器
immediate:true,
}
}
}
</script>
deep選項
當watch偵聽的是一個對象,如果對象中的屬性值發生了變化,則無法被監聽到,需要使用deep
選項偵聽所有屬性的變化。
<script>
import axios from 'axios'
export default {
name:'MyCount',
data(){
return{
username:'',
}
},
watch:{
//不能直接定義成方法,要讓監聽的數據指向一個配置對象
username:{
async handler(newVal,oldVal){
const {data:res}=await axios.get('https://www.escook.cn/api/finduser'+newVal)
//await簡化promise實例對象為數據
console.log(res)
},
deep:true,//監視多級結構(對象)中所有屬性的變化
}
}
}
</script>
監視多級結構(對象)中單個屬性的變化
<script>
import axios from 'axios'
export default {
name:'MyCount',
data(){
return{
info:{username:'zs',password:'123456'}
}
},
watch:{
//不能直接定義成方法,要讓監聽的數據指向一個配置對象
'info.username':{//只想監聽info.username的屬性變化
async handler(newVal,oldVal){
const {data:res}=await axios.get('https://www.escook.cn/api/finduser'+newVal)
//await簡化promise實例對象為數據
console.log(res)
},
deep:true,
}
}
}
</script>
計算屬性vs偵聽器
- computed能完成的功能,watch都可以完成,都能完成的,優先使用computed。
- watch可以完成的,computed不一定能完成,例如watch可以處理非同步任務。
- 計算屬性和偵聽器側重的應用場景不同。
-
前者側重監聽多個值的變化,最終計算返回一個新值
-
後者側重於單個數據的變化,最終執行特定的業務處理,不需要任何返回值
兩個原則:
- Vue所管理的函數,最好寫成普通函數,這樣this的指向才是vm或組件實例對象,否則指向window。
- 所有不被Vue所管理的函數(定時器的回調函數、ajax的回調函數、Promise的回調函數),最好寫成箭頭函數,這樣this的指向才是vm或組件實例對象,否則指向window。
綁定樣式
綁定class樣式
<!--字元串寫法,適用於樣式的類名不確定,需要動態指定-->
<h1 class="basic" :class:"className">Hello World!</h1>
<!--數組寫法,適用於樣式的個數和類名都不確定-->
<h1 class="basic" :class:"classArr">Hello World!</h1>
<!--對象寫法,適用於樣式的個數和類名都確定,但要動態覺得用不用-->
<h1 class="basic" :class:"classObj">Hello World!</h1>
綁定style樣式
<!--動態指定-->
<h1 class="basic" :style="{fontSize: fsize+'px';}">Hello World!</h1>
<h1 class="basic" :style="styleObj">Hello World!</h1>
<h1 class="basic" :style="[styleObj1,styleObj2]">Hello World!</h1>
過濾器
(Vue3.x廢棄,用計算屬性、方法代替)
什麼是過濾器?
過濾器(Filters)常用於文本的格式化,本質是一個函數
過濾器應該被添加到js表達式的尾部,由“管道符”進行調用
- 用於插值表達式
- 用於v-bind屬性綁定
定義(局部)過濾器
在創建vue實例期間,可以在filters節點中定義過 濾器
私有和全局過濾器
私有過濾器:只能在被vm實例控制的區域下控制
如果想在多個vue實例之間共用過濾器,則可以按照如下格式聲明全局過濾器:
<script>
vue.filter('capitalize',(str)=>{
return str.charAt(0).toUpperCase() + str.slice(1)+'--'
})
new Vue...
</script>
註:如果二者衝突以私有過濾器為準,就近原則
連續調用多個過濾器
過濾器可以串聯的地調用
{{message | capitalize | maxlength}
過濾器傳參
過濾器本質是js函數,第一個參數永遠是管道符前面的值,第二個參數開始才是arg1、arg2...
{{message | filterA(agr1,arg2)}
vue.filter('filterA',(msg,arg1,aarg2)=>{})
過濾器的相容性
在vue3.x版本中已經剔除了過濾器相關功能,可以使用計算方法或屬性來代替