这篇文章主要讲解了“Vue3中的ref和reactive响应式原理实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Vue3中的ref和reactive响应式原理实例分析”吧!
接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象仅有一个.value
property,指向该内部值。
案例
<template>
<div>
<button @click="changeMsg">change</button>
<div>{{ message }}</div>
</div>
</template>
<script setup lang="ts">
let message: string = "我是message"
const changeMsg = () => {
message = "change msg"
}
</script>
<style>
</style>
我们这样操作是无法改变message 的值 应为message 不是响应式的无法被vue 跟踪要改成ref。响应式就是在页面上实时显示修改的值。
Ref TS对应的接口:
interface Ref<T> {
value: T
} // 对于接口问题,是TS语法,如果不清楚,直接看TS
但是被ref包裹后需要使用value来进行赋值。
<template>
<div>
<button @click="changeMsg">change</button>
<div>{{ message }}</div>
</div>
</template>
<script setup lang="ts">
import {ref,Ref} from 'vue'
let message:Ref<string> = ref("我是message")let message= ref<string>("我是message") // 第二种方式const changeMsg = () => {
message.value = "change msg"
}
</script>
<style>
</style>
import { ref, Ref,isRef } from 'vue'
let message: Ref<string | number> = ref("我是message")
let notRef:number = 123
const changeMsg = () => {
message.value = "change msg"
console.log(isRef(message)); //true
console.log(isRef(notRef)); //false
}
例子1
修改其属性是非响应式的这样是不会改变的
<template>
<div>
<button @click="changeMsg">change</button>
<div>{{ message }}</div>
</div>
</template>
<script setup lang="ts">
import { Ref, shallowRef } from 'vue'
type Obj = {
name: string
}
let message: Ref<Obj> = shallowRef({
name: "唐少"
})
const changeMsg = () => {
message.value.name = '唐少2'
}
</script>
<style>
</style>
例子2
这样是可以被监听到的修改value,必须要修改整个对象才行
import { Ref, shallowRef } from 'vue'
type Obj = {
name: string
}
let message: Ref<Obj> = shallowRef({
name: "唐少"
})
const changeMsg = () => {
message.value = { name: "唐少2" }
}
为了解决shallowRef的问题,我们强制更新页面DOM,这样也是可以改变值的
<template>
<div>
<button @click="changeMsg">change</button>
<div>{{ message }}</div>
</div>
</template>
<script setup lang="ts">
import { Ref, shallowRef,triggerRef } from 'vue'
type Obj = {
name: string
}
let message: Ref<Obj> = shallowRef({
name: "唐少"
})
const changeMsg = () => {
message.value.name = '唐2'
triggerRef(message)
}
</script>
<style>
</style>
自定义ref ,customRef 是个工厂函数要求我们返回一个对象 并且实现 get 和 set
<script setup lang="ts">
import { Ref, shallowRef, triggerRef, customRef } from 'vue'
function Myref<T>(value: T) {
return customRef((track, trigger) => {
return {
get() {
track()
return value
},
set(newVal: T) {
console.log('set');
value = newVal
trigger()
}
}
})
}
let message = Myref('唐少')
const changeMsg = () => {
message.value = '唐少2'
// triggerRef(message)
}
</script>
例如 对象 数组
reactive源码约束了我们的类型,类型必须是object,不能绑定普通的类型,会报错。你如果用ref去绑定对象 或者数组等复杂的数据类型 我们看源码里面其实也是 去调用reactive,但使用reactive 去修改值无须.value
reactive 基础用法
import { reactive } from 'vue'
let person = reactive({
name:"唐少"
})
person.name = "唐少2"
数组异步赋值问题
// 这样赋值页面是不会变化的因为会脱离响应式<br data-filtered="filtered">let person = reactive<number[]>([])
setTimeout(() => {
person = [1, 2, 3]
console.log(person);
},1000)
解决方案1:push
import { reactive } from 'vue'
let person = reactive<number[]>([])
setTimeout(() => {
const arr = [1, 2, 3]
person.push(...arr)
console.log(person);
},1000)
解决方案2:包裹一层对象
type Person = {
list?:Array<number>
}
let person = reactive<Person>({
list:[]
})
setTimeout(() => {
const arr = [1, 2, 3]
person.list = arr;
console.log(person);
},1000)
拷贝一份proxy对象将其设置为只读
import { reactive ,readonly} from 'vue'
const person = reactive({count:1})
const copy = readonly(person)
//person.count++
copy.count++
只能对浅层的数据 如果是深层的数据只会改变值 不会改变视图
<template>
<div>
<div>{{ state }}</div>
<button @click="change1">test1</button>
<button @click="change2">test2</button>
</div>
</template>
<script setup lang="ts">
import { shallowReactive } from 'vue'
const obj = {
a: 1,
first: {
b: 2,
second: {
c: 3
}
}
}
const state = shallowReactive(obj)
function change1() {
state.a = 7
}
function change2() {
state.first.b = 8
state.first.second.c = 9
console.log(state);
}
</script>
<style>
</style>
如果原始对象是非响应式的就不会更新视图 数据是会变的,如果原始对象是响应式的是会更新视图并且改变数据的
<template>
<div>
<button @click="change">按钮</button>
{{state}}
</div>
</template>
<script setup lang="ts">
import { reactive, toRef } from 'vue'
const obj = {
foo: 1,
bar: 1
}
const state = toRef(obj, 'bar')
// bar 转化为响应式对象
const change = () => {
state.value++
console.log(obj, state);
}
</script>
可以帮我们批量创建ref对象主要是方便我们解构使用
import { reactive, toRefs } from 'vue'
const obj = reactive({
foo: 1,
bar: 1
})
let { foo, bar } = toRefs(obj)
foo.value++
console.log(foo, bar);
将响应式对象转化为普通对象
import { reactive, toRaw } from 'vue'
const obj = reactive({
foo: 1,
bar: 1
})
const state = toRaw(obj)
// 响应式对象转化为普通对象
const change = () => {
console.log(obj, state);
}
感谢各位的阅读,以上就是“Vue3中的ref和reactive响应式原理实例分析”的内容了,经过本文的学习后,相信大家对Vue3中的ref和reactive响应式原理实例分析这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。