計算屬性
使用場景:當變量的值, 依賴其他變量計算而得來才用
特點:計算屬性的依賴項發(fā)生改變的時候, 重新計算結果返回并重新緩存,如果沒變化,直接從緩存取結果
注意: 計算屬性也是vue數(shù)據(jù)變量, 所以不要和data里重名, 用法和data相同
語法:
computed:{
"計算屬性名" (){
return "值"
}
}
<template>
<div>
# computed 再使用時,是讀取緩存 不會重復計算
<h1>{{num}}</h1>
<h1>{{num}}</h1>
<h1>{{num}}</h1>
# 函數(shù)調用,進行較復雜運算時,性能就比computed差
<h2>{{getnum()}}</h2>
<h2>{{getnum()}}</h2>
<h2>{{getnum()}}</h2>
<input type="text" v-model.number="a">
<input type="text" v-model.number="b">
</div>
</template>
<script>
export default {
data () {
return {
a:0,
b:0
}
},
computed: {
num(){
console.log("computed");
return this.a+this.b
}
},
methods: {
getnum(){
console.log("getnum");
return this.a+this.b
}
}
}
</script>
計算屬性完整寫法
如果想直接賦值,需要使用完整寫法
語法:
computed: {
"計算屬性名": {
set(值){
},
get() {
return "值"
}
}
}
<template>
<div>
名字
<input type="text" v-model="full" />
</div>
</template>
<script>
export default {
computed: {
// 這種函數(shù)寫法其實是get的簡寫,問題:不能修改變量的值
// full(){
// return "烏拉拉"
// }
// 注意:如果要對對象計算屬性的值進行修改,就必須帶set的完整寫法,否則報錯
full: {
get() {
return "什么鬼";
},
//修改的值自動被set的形參接收
set(val) {
console.log(val);
},
},
},
};
</script>
偵聽器--watch
偵聽簡單數(shù)據(jù)類型
目標: 可以偵聽data/computed屬性值改變
語法:
watch: {
"被偵聽的屬性名" (newVal, oldVal){
}
}
<template>
<div>
<input type="text" v-model="name" />
</div>
</template>
<script>
/*
偵聽器watch
作用:偵聽data/computed數(shù)據(jù)值的變化
語法:
watch:{
"被偵聽的屬性名"(val,oldVal){
val:第一個參數(shù) 表示現(xiàn)在的值
oldVal:第二個參數(shù) 表示原本的值
}
}
*/
export default {
data() {
return {
name: "",
};
},
watch: {
name(newval, oldval) {
console.log("新值:", newval);
console.log("舊值:", oldval);
},
},
};
</script>
偵聽復雜數(shù)據(jù)類型
目標: 偵聽復雜類型, 或者立即執(zhí)行偵聽函數(shù)
語法:
watch: {
"要偵聽的屬性名": {
immediate: true, // 立即執(zhí)行
deep: true, // 深度偵聽復雜類型內變化
//handler固定方法觸發(fā)
handler (newVal, oldVal) {
}
}
}
<template>
<div>
<input type="text" v-model.trim="user.name" />
<input type="text" v-model.trim="user.age" />
</div>
</template>
<script>
export default {
data() {
return {
user: {
name: "哈哈",
age: 18,
},
};
},
watch: {
user: {
immediate: true, //立即偵聽
deep: true, //深度偵聽
// handler固定方法觸發(fā)
handler() {
console.log("user變化了");
},
},
},
};
</script>
$refs知識
利用ref和$refs可以獲取dom元素,獲取組件對象,調用組件方法
<template>
<div>
<h1 id="h1Id" ref="h1Ref">這是一個h1標題</h1>
<!-- 子組件 -->
<son ref="de" />
</div>
</template>
<script>
import son from "@/components/son.vue";
export default {
// 注冊組件
components: {
son,
},
mounted() {
console.log(document.querySelector("#h1Id"));
// 獲取dom
console.log(this.$refs.h1Ref);
// 獲取組件實例梢为,可以對組件為所欲為
// ?? 開發(fā)經驗:一般只調用組件內部的方法粤铭,不會這種方式改變組件內的數(shù)據(jù)(修改數(shù)據(jù)還用父傳子,子傳父的方式)
console.log(this.$refs.de);
// 調用組件內部的方法
this.$refs.de.fn();
},
};
</script>
$nextTick知識
Vue更新DOM-異步的
<template>
<div>
<p ref="PP">數(shù)字:{{ count }}</p>
<button @click="btn">點擊加1</button>
</div>
</template>
<script>
export default {
data() {
return {
count: 1,
};
},
methods: {
btn() {
this.count++;
// 以下沒有辦法得到最新的數(shù)據(jù)(點擊后的數(shù)字)
// DOM的更新是異步的
// console.log(this.$refs.PP.innerHTML);
this.$nextTick(() => {
console.log(this.$refs.PP.innerHTML);
});
},
},
};
</script>
$nextTick使用場景
點擊搜索按鈕, 彈出聚焦的輸入框, 按鈕消失
<template>
<div>
<input type="text" ref="II" placeholder="請輸入內容" v-if="isShow" />
<button @click="btn">點擊進行搜索</button>
</div>
</template>
<script>
export default {
data() {
return {
isShow: false,
};
},
methods: {
btn() {
this.isShow = true;
// DOM的更新是異步的
// 所以點擊后的輸入還是沒有焦點
// 所以用$nextTick
this.$nextTick(() => {
this.$refs.II.focus();
});
},
},
};
</script>
自定義指令
自定義指令也分局部注冊和全局注冊
全局(main.js中注冊):
Vue.directive("自定義指令名", {
inserted(el){
el: 表示使用指令時的標簽
}
})
局部(組件中注冊):
directives:{
"自定義指令名": {
inserted(el){
el: 表示使用指令時的標簽
}
}
}
<template>
<div>
<!-- 使用指令:v-指令名稱 -->
<!-- <input type="text" v-focus /> -->
<!-- 使用指令:v-指令名稱 -->
<h1>我是大標題-什么顏色呢?</h1>
<h2 v-color="'red'">我是二標題-什么顏色呢舀奶?</h2>
<h3 v-color="myColor">我是三標題-什么顏色呢疼蛾?</h3>
<button @click="myColor = 'green'">改顏色變量</button>
<br />
<input type="text" v-focus />
<input type="text" />
</div>
</template>
<script>
export default {
data() {
return {
myColor: "pink",
};
},
directives: {
// 指令名稱
focus: {
// 掛載到頁面后觸發(fā) el
inserted(el, binding) {
console.log(el, binding);
el.focus();
},
},
},
};
</script>