Vue——ref/reactive、toRefs、计算属性、监视、Vue3响应式原理、Vue3生命周期
ref/reactive
ref函数创建单个数据的响应式对象
ref函数可以把数据创建成为ref对象,只要是ref对象,那么就一定是响应式
ref创建单个值的响应式对象
ref对象,在模板用的时候会自动拿value,不需要你去.value
ref对象,在js当中修改的时候,需要.value
<template>
<h2>{{ msg }}</h2>
<button @click="update">给我变!</button>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "About",
});
</script>
<script lang="ts" setup>
import { ref } from "vue";
let msg = ref('我是哈哈哈');
function update() {
msg.value = '我成为了嘿嘿嘿';
}
</script>
ref传递对象
如果使用ref传递一个对象,本质内部也是在使用reactive
ref传递对象,那么返回的仍然是ref对象,它的value是代理对象
<template>
<h2>{{ state.name }}</h2>
<button @click="update">给我变!</button>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "About",
});
</script>
<script lang="ts" setup>
import { ref } from "vue";
const state = ref({
name: '啊哈',
hobby: '诶嘿'
})
function update(){
state.value.name = '1111'
}
</script>
reactive
reactive是用来对一个对象创建代理对象,代理对象也是响应式的
reactive创建的代理对象,直接通过.语法去操作,不需要.value
不能传递非对象数据
<template>
<h2>{{ msg.name }}</h2>
<button @click="update">给我变!</button>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "About",
});
</script>
<script lang="ts" setup>
import { reactive } from "vue";
let msg = reactive({
name: '我是哈哈哈'
});
function update() {
msg.name = '我成为了嘿嘿嘿';
}
</script>
toRefs
默认代理对象被解构,数据将失去响应能力
如果非要去解构,并且保证响应能力依然存在,需要使用toRefs方法
把state内部所有的属性全部转化为ref对象
解构出来不再是基本值,而是ref对象,就有响应式能力
<template>
<h2>{{ state.name }}</h2>
<h2>{{ state.hobby }}</h2>
<button @click="update">给我变!</button>
</template>
<script lang="ts">
import { defineComponent, reactive } from "vue";
export default defineComponent({
name: "About",
});
</script>
<script lang="ts" setup>
import { ref, toRefs } from "vue";
const state = reactive({
name: '啊哈',
hobby: '诶嘿'
})
let result = toRefs(state)
console.log(result);
let {name, hobby} = result
console.log(name, hobby);
function update(){
state.name = '1111',
state.hobby = '2222'
}
console.log(state);
</script>
计算属性
<template>
count: {{count}}
<br>
double: {{double}}
<br>
trible: <input type="text" v-model="trible">
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "About",
});
</script>
<script lang="ts" setup>
import { ref, computed } from 'vue'
const count = ref(100)
//数据只是为了读取
const double = computed(() => {
return count.value * 2
})
//既可读又可写
const trible = computed({
get(){
return count.value * 3
},
set(val){
console.log(val);
count.value /= 2
}
})
</script>
监视
计算属性和watch监视都必须先保证数据是响应式数据才能进行
<template>
<button @click="update">点击修改</button>
</template>
<script lang="ts">
import { defineComponent, reactive } from "vue";
export default defineComponent({
name: "About",
});
</script>
<script lang="ts" setup>
import { ref, watch } from "vue";
const msg = ref("饿了但不想吃饭");
const data = ref({
a: 100,
b: 200,
});
const state = reactive({
name: "动漫",
num: 1000,
collection: [
{ id: 1, name: "海贼王" },
{ id: 2, name: "火影忍者" },
],
});
function update() {
msg.value = "好饿啊",
data.value.a = 300,
state.collection.push({ id: 3, name: "犬夜叉" })
state.name = '看看就看看'
}
watch(msg, (newVal, oldVal) => {
console.log(newVal, oldVal);
});
watch(() => data.value.a,(newVal, oldVal) => {
console.log(newVal, oldVal);
}
);
watch(() => state.name,(newVal, oldVal) => {
console.log(newVal, oldVal);
}
);
// 监视数组变化,地址不变只是修改数组内部的长度或者数据,监视不到
// 以后监视数组数据一定要深度监视
watch(() => state.collection,(newVal, oldVal) => {
console.log(newVal, oldVal);
},{ deep: true });
</script>

一、ref(基本值)
const msg = ref(100)
watch(msg,(0 => {})) //不能写msg.value
监视ref对象,默认监视的就是.value,监视的时候不能写.value,写了就是在监视
一个基本值,就不是响应式,报错
二、ref(对象)
const data = ref({
a:100,
b:200
})
data也是ref对象。data.value是一个代理对象
如果监视ref对象data,默认监视也是.value,监视代理对象的地址,代理对象内部数据发生变化,需要加深度监视
如果你修改代理对象的地址,可以监视到,但是代理对象没了,修改的新对象不是响应式
一般监视不监视ref对象本身(除非要深度监视代理对象内部数据)
监视单个ref对象内的代理对象数据 ref.value.xxx,就得写成回调 () => ref.value.xxx
三、reactive(对象)
返回的就是代理对象
监视直接监视的是代理对象本身,监视就是代理对象地址,
监视地址发生变化,或者深度监视代理对象内部所有数据发生变化
监视地址发生变化,同样修改了以后不再是响应式对象了,所以一般监视不监视代理对象本身
Vue3响应式原理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let obj = {
name:'赵丽颖',
age:35
}
const proxyObj = new Proxy(obj, {
// 操作代理对象的所有捕捉器(增删改查)
get(target, property) {
console.log('获取捕捉器执行',target,property);
// 读取捕捉器,如果用户后期在读取代理对象的属性
// 那么就会被此捕捉器捕捉
return Reflect.get(target, property)
},
set(target, property, value) {
console.log('设置捕捉器执行',target,property);
// 设置捕捉器,如果用户以后给代理对象添加或者修改属性
// 那么就会被此捕捉器捕捉
Reflect.set(target, property, value)
},
deleteProperty(target, property) {
console.log('删除捕捉器执行',target,property);
// 删除捕捉器,如果用户后期通过代理对象删除某个属性
// 那么就会被此捕捉器捕捉
Reflect.deleteProperty(target, property)
}
})
console.log(proxyObj.name);
proxyObj.heihei = '哈哈'
console.log(obj,proxyObj);
delete proxyObj.name
console.log(obj,proxyObj);
</script>
</body>
</html>
Vue3生命周期
vue3配置项生命周期写法只是修改了vue2最后的两个钩子名称
beforeCreate(){ },
created(){ },
beforeMount(){ },
mounted(){ },
beforeUpdate(){ },
updated(){ },
beforeUnmount(){ },
unmounted(){ }
vue3组合api生命周期写法
setup(){
onBeforeMount(() => { })
onMounted(() => { })
onBeforeUpdate(() => { })
onUpdated(() => { })
onBeforeUnmount(() => { })
onUnmounted(() => { })
}
更多推荐
所有评论(0)