持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情。
今天主要学习toRefs函数的使用,computed的计算属性,watch与watchEffect。
toRefs函数
toRefs函数可以将响应式对象中所有属性包装为ref对象,并返回包含这些ref对象的普通对象,比如在setup函数中返回一个使用扩展运算符对象类型的响应式数据,这时候这个对象类型的属性不再是响应式的,可以使用toRefs将对象中的每个属性都转换为响应式的。
在代码中进行演示一下,先定义一个常规的变量state,包含两个属性,先正常引入使用,是可以正常的通过一个方法改变state中的属性值:
<template>
<div>
<div>{{ state.title }}:{{ state.price }}</div>
<button @click="setState">更新数据</button>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive } from "vue";
export default defineComponent({
name: "toRefs",
setup() {
let state = reactive({
title: "杯子",
price: 5,
});
let setState = () => {
state.title = "眼镜";
state.price = 100;
};
return {
state,
setState
};
},
});
</script>
这时候把setup中return state的使用扩展运算符,再去修改,state内部属性就不是响应式的了,就需要用到toRefs,
return {
...state,
setState
};
<template>
<div>
<div>{{ title }}:{{ price }}</div>
<button @click="setState">更新数据</button>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive, toRefs } from "vue"; // 使用前需要先引入toRefs
export default defineComponent({
name: "toRefs",
setup() {
let state = reactive({
title: "杯子",
price: 5,
});
let setState = () => {
state.title = "眼镜";
state.price = 100;
};
return {
...toRefs(state),
setState,
};
},
});
</script>
computed
vue2中已经使用的很普遍了,vue3是写法上有些不一样:
示例1:
<template>
<div>
<div>数量:{{ amount }}</div>
<div>价格:{{ price }}</div>
<div>总计:{{ total }}</div>
<button @click="amount++">新增数量</button>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, computed } from "vue";
export default defineComponent({
name: "computed",
setup() {
let amount = ref(1),
price = 20,
total = computed(() => {
return price * amount.value;
}),
return {
amount,
price,
total
};
},
});
</script>
示例2:
<template>
<div>
<div>用户名:<input v-model="setUsername" /></div>{{username}}
</div>
</template>
<script lang="ts">
import { defineComponent, ref, computed } from "vue";
export default defineComponent({
name: "computed",
setup() {
let username = ref(""),
setUsername = computed({
get() {
return username.value;
},
set(val: string) {
username.value = val;
},
});
return {
setUsername,
username
};
},
});
</script>
watch与watchEffect
watch
watch可以监听一个或多个响应式数据,一旦数据变化,就自动执行监听回调,如果是监听reactive对象中的属性,必须通过函数来指定,如果监听多个数据,需要使用数组来指定,默认初始时不执行回调,但可以通过配置immediate为true,来指定初始化的时候立即执行一次,通过配置deep为true,来指定深度监听。
watchEffect
watchEffect可以不用直接指定要监听的数据,回调函数中使用的哪些响应式数据就监听哪些响应式数据,默认初始化的时候就执行一次。
<template>
<div>
{{ name }},<button @click="setName">修改姓名</button><br />
{{ area.province }},{{ area.city }}
<button @click="setArea">修改省市</button>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, watch, reactive, watchEffect } from "vue";
export default defineComponent({
name: "watch",
setup() {
let name = ref("张三");
let setName = () => {
name.value = "李四";
};
//监听ref
watch(name, (newVal: string, oldVal: string) => {
console.log(newVal, oldVal);
});
let area = reactive({
province: "山西",
city: "大同",
});
//监听reactive
let setArea = () => {
area.province = "辽宁";
area.city = "沈阳";
};
watch(
() => area.province,
(newVal: string, oldVal: string) => {
console.log(newVal, oldVal);
}
);
// 监听多个数据;
watch(
[() => area.province, () => area.city],
(newVal: string, oldVal: string) => {
console.log(newVal[0], newVal[1], oldVal[0], oldVal[1]);
},
{
immediate: true, //初始化执行一次
deep: true, //深度监听
}
);
watchEffect(() => {
console.log(area.province, area.city, name.value);
});
return {
name,
setName,
area,
setArea,
};
},
});
</script>
接下来继续学习Vue3的知识点~