<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
Vue3系列4--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響應式內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45