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(() => { })
?}
|