计算属性
使用场景:当变量的值, 依赖其他变量计算而得来才用
特点:计算属性的依赖项发生改变的时候, 重新计算结果返回并重新缓存,如果没变化,直接从缓存取结果
注意: 计算属性也是vue数据变量, 所以不要和data里重名, 用法和data相同
语法:
computed:{
"计算属性名" (){
return "值"
}
}
<template>
<div>
# computed 再使用时,是读取缓存 不会重复计算
<h1>{{num}}</h1>
<h1>{{num}}</h1>
<h1>{{num}}</h1>
# 函数调用,进行较复杂运算时,性能就比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: {
// 这种函数写法其实是get的简写,问题:不能修改变量的值
// full(){
// return "乌拉拉"
// }
// 注意:如果要对对象计算属性的值进行修改,就必须带set的完整写法,否则报错
full: {
get() {
return "什么鬼";
},
//修改的值自动被set的形参接收
set(val) {
console.log(val);
},
},
},
};
</script>
侦听器--watch
侦听简单数据类型
目标: 可以侦听data/computed属性值改变
语法:
watch: {
"被侦听的属性名" (newVal, oldVal){
}
}
<template>
<div>
<input type="text" v-model="name" />
</div>
</template>
<script>
/*
侦听器watch
作用:侦听data/computed数据值的变化
语法:
watch:{
"被侦听的属性名"(val,oldVal){
val:第一个参数 表示现在的值
oldVal:第二个参数 表示原本的值
}
}
*/
export default {
data() {
return {
name: "",
};
},
watch: {
name(newval, oldval) {
console.log("新值:", newval);
console.log("旧值:", oldval);
},
},
};
</script>
侦听复杂数据类型
目标: 侦听复杂类型, 或者立即执行侦听函数
语法:
watch: {
"要侦听的属性名": {
immediate: true, // 立即执行
deep: true, // 深度侦听复杂类型内变化
//handler固定方法触发
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固定方法触发
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);
// 获取组件实例,可以对组件为所欲为
// 🔔 开发经验:一般只调用组件内部的方法,不会这种方式改变组件内的数据(修改数据还用父传子,子传父的方式)
console.log(this.$refs.de);
// 调用组件内部的方法
this.$refs.de.fn();
},
};
</script>
$nextTick知识
Vue更新DOM-异步的
<template>
<div>
<p ref="PP">数字:{{ count }}</p>
<button @click="btn">点击加1</button>
</div>
</template>
<script>
export default {
data() {
return {
count: 1,
};
},
methods: {
btn() {
this.count++;
// 以下没有办法得到最新的数据(点击后的数字)
// 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: {
// 挂载到页面后触发 el
inserted(el, binding) {
console.log(el, binding);
el.focus();
},
},
},
};
</script>