日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > vue >内容正文

vue

Vue3官方文档翻译之Reactivity Fundamentals

發(fā)布時間:2024/3/24 vue 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Vue3官方文档翻译之Reactivity Fundamentals 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

引言

突然不知道這章寫了啥, 感覺內(nèi)容有點干, 顧著翻譯去了, 沒有吸收消化. 還是總結(jié)下, 主要是就是響應(yīng)式的對象如何和template結(jié)合的, 響應(yīng)式對象是通過JavaScript的代理對象實現(xiàn)的; 響應(yīng)式的對象有分為深響應(yīng)和淺響應(yīng); 完成響應(yīng)式的對象在作為函數(shù)參數(shù)或者解構(gòu)的時候會有局限性,因此提出了ref()來避免此問題,并講接了ref的拆箱問題.

原文地址: http://blog.duhbb.com/2022/02/11/translation-of-reactivity-fundamentals-in-vue-3-offiicial-doc/

歡迎訪問我的博客: http://blog.duhbb.com/

Vue3官方文檔翻譯之Reactivity Fundamentals

Reactivity Fundamentals: 我也不知道怎么翻譯, 就當(dāng)作是響應(yīng)式原理或者基礎(chǔ)吧.

P.S. 我看的這個版本是 Composition API, 所以如果有偏差的話, 應(yīng)該是API風(fēng)格上的不同, 請自行甄別.

聲明響應(yīng)式的狀態(tài)

我們可以使用 reactive() 函數(shù)創(chuàng)建一個響應(yīng)式的對象或者數(shù)組.

妙啊, 創(chuàng)建之后呢?

import { reactive } from 'vue'const state = reactive({ count: 0 })

響應(yīng)時的對象都是JavaScript代理對象, 學(xué)過代理模式的應(yīng)該都懂吧, 不會有人覺得用common 對象就能響應(yīng)式吧, 我瞎逼逼的.

但是這些代理對象看上去和普通對象并沒有什么區(qū)別. 不同的是Vue可以跟蹤代理對象的屬性訪問以及響應(yīng)式對象的變更. 如果你好奇這個在Vue中的實現(xiàn)原理, 那么我推薦你了解一下Reactivity in Depth, 不要猴急, 你先把這篇看完了, 再去深入了解.

也可以參考: Typing Reactive

為了在組件模板中使用響應(yīng)式的對象, 聲明并且從組件的setup()函數(shù)中返回這個對象.

P.S. Options API 應(yīng)該是從data()返回的吧.

import { reactive } from 'vue'export default {// `setup`是一個特殊的鉤子, 專門用于composition API.setup() {const state = reactive({ count: 0 })// 將響應(yīng)式狀態(tài)暴露給模板return {state}} }

這樣, state就和template關(guān)聯(lián)起來了, 你瞧瞧多么牛逼的框架…

<div>{{ state.count }}</div>

類似的, 我們可以在同一個域中聲明函數(shù)來操作響應(yīng)式的狀態(tài), 并將將她作為方法和state一起暴露.

import { reactive } from 'vue'export default {setup() {const state = reactive({ count: 0 })// 擦, mutation的函數(shù)是放在scope中的?function increment() {state.count++}// don't forget to expose the function as well.return {state,increment}} }

被暴露的方法一般都是作為事件響應(yīng)的監(jiān)聽器:

<button @click="increment">{{ state.count }} </button>

<script setup>

通過setup手動的暴露響應(yīng)式對象或者方法可能會比較繁瑣.

幸運滴是, 不需要build步驟的時候才需要這么做.

當(dāng)使用Single-File Component的時候, 我們可以通過<script setup>進行極大的簡化:

<!-- 歪日, 還真是方便 --> <script setup> import { reactive } from 'vue'const state = reactive({ count: 0 })function increment() {state.count++ } </script><template><button @click="increment">{{ state.count }}</button> </template>

在<script setup>中的頂層引入以及變量都會在同一個組件的模板中變得可用.

在本文檔的剩下內(nèi)容中, 我們將會主要使用SFC + <script setup> 語法來編寫Composition API風(fēng)格的代碼例子, 應(yīng)為這種用法對于Vue開發(fā)者來說是最常用的.

我是個偽前端, 偽Vue開發(fā)者…

DOM更新Timing

不好意思, timing我不會翻譯了, 感覺應(yīng)該是"時機"的意思.

當(dāng)你修改了響應(yīng)式的對象的時候, DOM會被自動地更新. But, 但是, 然而, 你應(yīng)該注意到, DOM的更新并不是同步的.

令人震驚的消息, ??? 什么, 就這點更新, 為什么不能同步呢?

實際上Vue會將這些變更緩沖起來, 直到下一次"next click"的更新周期中來確保每個組件只被更新一次, (我擦, 這還整上了時鐘周期?), 而不管你怎么修改state.

喲, 怎么玩兒的呢?

為了在state修改后, DOM的所有的update都能被執(zhí)行完畢, 你可以使用nextTick()這個API:

import { nextTick } from 'vue'function increment() {count.value++// nextTick的回調(diào)就表示DOM中的組件都被個更新了?nextTick(() => {// access updated DOM}) }

更深層次的響應(yīng)性

在Vue中, state默認(rèn)是深度響應(yīng)(這翻譯我都看不下去了, 應(yīng)該是和深拷貝淺拷貝類似吧?).

這意味著, 即使你對嵌套的對象, 或者數(shù)組中的對象進行修改的時候, 這種響應(yīng)也能被檢測到.

(果然是深拷貝的概念, 所以嵌套的對象和數(shù)組也是代理的? 代理模式果然牛逼, Spring框架也是靠代理模式)

import { reactive } from 'vue'const obj = reactive({nested: { count: 0 },arr: ['foo', 'bar'] })function mutateDeeply() {// these will work as expected.obj.nested.count++obj.arr.push('baz') }

當(dāng)然, 你可以顯式地創(chuàng)建淺響應(yīng)對象, 那么只根節(jié)點的對象的變更才會被追蹤, 但是這種變態(tài)的用法只是在高級場所, 啊不, 高級場景中才用得到.

響應(yīng)式的代理對象 VS. 原始對象

需要注意的式, 從reactive()方法中返回的對象式原始對象的代理, 和原始的對象不是等同滴.

const raw = {} const proxy = reactive(raw)// proxy is NOT equal to the original. console.log(proxy === raw) // false

只有代理對象是reactive的, 修改原始對象并不會觸發(fā)更新. 隱刺, 當(dāng)使用Vue響應(yīng)式系統(tǒng)的最佳方式就是使用你的狀態(tài)的代理對象, 不要直接去操作原始對象(后面是我加的).

為了確保對代理對象訪問的一致性, 對同一個對象使用reactive()返回的總是同一個代理對象, 哇偶, 這玩意兒還是冪等的咧, 同樣對代理對方使用reactive()方法, 返回的還是它自己(應(yīng)該很好理解吧).

// calling reactive() on the same object returns the same proxy console.log(reactive(raw) === proxy) // true// calling reactive() on a proxy returns itself console.log(reactive(proxy) === proxy) // true

這個規(guī)則也同樣適用于嵌套對象. 由于是深層響應(yīng)的, 響應(yīng)式對象中的嵌套對象也是代理的:

const proxy = reactive({})const raw = {} proxy.nested = rawconsole.log(proxy.nested === raw) // false

reactive()函數(shù)的局限性

reactive()這么牛逼的函數(shù)也有她的局限性:

  • 她只能作用于對象類型(對象, 數(shù)組或者集合類型, 比如Map和Set). 而不能作用于原始類型, 比如string, number或者boolean. (沒得拆箱裝箱咩?)
  • 由于Vue的響應(yīng)式追蹤屬性的訪問, 我們對響應(yīng)式對象保留同一個引用. 這意味著我們不能替換響應(yīng)式的對象:
  • let state = reactive({ count: 0 })// this won't work! state = reactive({ count: 1 })

    這也意味著當(dāng)我們賦值或者解構(gòu)一個響應(yīng)式對象的屬性到局部變量或者當(dāng)我們將屬性傳遞給函數(shù),或者從響應(yīng)式對象解構(gòu)屬性,我們都將失去響應(yīng)式鏈接(good! 感覺和Hibernate的狀態(tài)管理有點類似鴨, de-attach):

    const state = reactive({ count: 0 })// n is a local variable that is disconnected // from state.count. let n = state.count // does not affect original state n++// count is also disconnected from state.count. let { count } = state // does not affect original state count++// the function receives a plain number and // won't be able to track changes to state.count callSomeFunction(state.count)

    通過ref()獲得響應(yīng)式變量(大概就這?)

    為了解決reactive()的不便之處, Vue也提供了一個ref()函數(shù), 它允許我們創(chuàng)建任何值類型的響應(yīng)式引用:

    import { ref } from 'vue'const count = ref(0)

    ref()接受參數(shù), 并返回一個ref對象, 屬性是.value:

    const count = ref(0)console.log(count) // { value: 0 } console.log(count.value) // 0count.value++ console.log(count.value) // 1

    P.S.: 這他喵的是裝箱和拆箱?

    參考: Typing Refs

    和響應(yīng)式對象的屬性類似, ref的.value屬性也是響應(yīng)式的. 除此之外, 當(dāng)手里拿著一個對象類型的時候, ref會自動將.value交給reactive()處理.

    ref中包含的對象值可以響應(yīng)式地替代整個對象(沒看懂?):

    const objectRef = ref({ count: 0 })// this works reactively objectRef.value = { count: 1 }

    哦哦, 懂了, reactive()不是不能替換嗎, ref可以替換.

    refs可以被傳遞到函數(shù)中或者從普通的對象解構(gòu)而不會失去reactivity:

    const obj = {foo: ref(1),bar: ref(2) }// the function receives a ref // it needs to access the value via .value but it // will retain the reactivity connection callSomeFunction(obj.foo)// still reactive const { foo, bar } = obj

    換句話說, ref() 允許我們創(chuàng)建一個對任何值得引用, 并且傳遞她的時候不會丟失reactivity.

    這個特性非常重要, 在將邏輯提取到Composable Functions的時候就顯得非常重要了.

    在模板中進行引用拆箱

    當(dāng)引用在模板中被作為頂層屬性使用的時候, 她們會自動地被拆箱, 因此就不需要我們再使用 .value 了. 下面將之前計數(shù)地例子用ref()進行了改造:

    <script setup> import { ref } from 'vue'/* 嘿嘿, 這個是時候原始值也可以獲得reactivity了 */ const count = ref(0)function increment() {count.value++ } </script><template><button @click="increment">{{ count }} <!-- no .value needed --></button> </template>

    小心: 自動地拆箱僅適用于頂層屬性, 對于refs的嵌套訪問則不會被拆箱:

    const object = { foo: ref(1) } <!-- object只是一個普通的對象, 剛才的規(guī)則也說了只有top-level的才會被自動拆箱 --> {{ object.foo }} <!-- does NOT get unwrapped -->

    正如設(shè)想的那樣, foo 并不會被拆箱, 呵呵, 我還沒有驗證.

    響應(yīng)式對象中的ref的拆箱

    當(dāng)一個ref作為一個響應(yīng)式的對象的屬性進行訪問或者修改的時候, 她會被自動的進行拆箱, 就像正常的屬性那樣:

    const count = ref(0)/* state已經(jīng)是一個響應(yīng)式的對象, 她有一個ref形式的屬性, 這個會被自動拆箱, 不需要是top-level了 */ /* 感覺我已經(jīng)理解了這個, 但是沒有實踐 */ const state = reactive({count })console.log(state.count) // 0state.count = 1 console.log(count.value) // 1

    如果一個新的ref替換了原來的ref, 她將會替代原來的ref:

    const otherCount = ref(2)state.count = otherCount console.log(state.count) // 2 // original ref is now disconnected from state.count console.log(count.value) // 1

    ref的拆箱只會發(fā)生在作為深層的響應(yīng)式對象的時候, 而作為淺層響應(yīng)對象的屬性時, 則不會被拆箱.

    數(shù)組和集合中的ref的拆箱

    和響應(yīng)式對象不一樣, 當(dāng)ref作為響應(yīng)式數(shù)組或者集合類型的元素被訪問的時候并不會發(fā)生拆箱(這是為什么呢?):

    const books = reactive([ref('Vue 3 Guide')]) // need .value here console.log(books[0].value)const map = reactive(new Map([['count', ref(0)]])) // need .value here console.log(map.get('count').value)

    響應(yīng)式的傳遞性(實驗特性)

    必須將 .value 和 refs 進行配合使用時JavaScript這個語言所施加的限制. 然而, 通過運行期的轉(zhuǎn)換在合適的位置追加 .value 則可以提高 ergonomics. Vue提供了編譯期的轉(zhuǎn)換使我們可以將之前的 “counter” 例子寫成這樣:

    <script setup> let count = $ref(0)function increment() {// no need for .valuecount++ } </script><template><button @click="increment">{{ count }}</button> </template>

    關(guān)于Reactivity Transform可以在她的專題了解, 提醒各位這個目前還只是實驗性滴.

    結(jié)束語

    突然不知道這章寫了啥, 感覺內(nèi)容有點干, 顧著翻譯去了, 沒有吸收消化. 還是總結(jié)下, 主要是就是響應(yīng)式的對象如何和template結(jié)合的, 響應(yīng)式對象是通過JavaScript的代理對象實現(xiàn)的; 響應(yīng)式的對象有分為深響應(yīng)和淺響應(yīng); 完成響應(yīng)式的對象在作為函數(shù)參數(shù)或者解構(gòu)的時候會有局限性,因此提出了ref()來避免此問題,并講接了ref的拆箱問題.

    原文地址: http://blog.duhbb.com/2022/02/11/translation-of-reactivity-fundamentals-in-vue-3-offiicial-doc/

    歡迎訪問我的博客: http://blog.duhbb.com/

    總結(jié)

    以上是生活随笔為你收集整理的Vue3官方文档翻译之Reactivity Fundamentals的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 欧美手机在线观看 | 视频在线观看网站免费 | 一本久久综合亚洲鲁鲁五月天 | 激情久久久久久久 | 精品一区二区三区人妻 | 美景之屋电影免费高清完整韩剧 | 色播导航 | 张柏芝亚洲一区二区三区 | 亚洲专区第一页 | 国产在线一二 | 黄色成人免费网站 | ,国产精品国产三级国产 | av在线播放不卡 | 激情文学8888 | 日本嫩草影院 | 特黄大片又粗又大又暴 | 欧美日韩a级片 | 轮番上阵免费观看在线电影 | 免费无码不卡视频在线观看 | 色爱成人综合 | 国产又大又长又粗 | 青青草91视频 | 亚洲国产成人久久 | 曰韩av | 午夜在线影院 | 日韩av网站在线播放 | 日韩精品色呦呦 | 日韩一区二区影视 | 老太太av | 亚洲最新av在线 | 日本在线不卡一区二区三区 | 超碰97在线免费 | 国产福利在线免费观看 | 久草国产精品 | 少妇视频在线播放 | 自拍偷拍专区 | 国产精品久久无码 | 狠狠躁日日躁夜夜躁 | 很黄很黄的网站 | 亚洲成人福利在线 | 美腿丝袜av| 国产吞精囗交久久久 | 日日射日日干 | 国产精品婷婷午夜在线观看 | 天天摸天天碰 | 亚洲一区二区自偷自拍 | 亚洲免费观看 | 久久99深爱久久99精品 | 69av在线播放 | 黄色一级图片 | 欧洲美一区二区三区亚洲 | 97视频在线免费观看 | 精品欧美一区二区在线观看 | 成人在线免费高清视频 | 久久中文免费视频 | 亚洲男人的天堂在线观看 | 天堂社区av | 天天干视频在线观看 | 国产精品高潮呻吟AV无码 | 国产全是老熟女太爽了 | 在线播放你懂得 | 男男上床视频 | 日本乱偷中文字幕 | 一道本在线播放 | 欧洲成人在线观看 | 国产视频在线观看一区二区 | 久久久久久蜜桃一区二区 | 911香蕉视频 | 手机在线一区二区三区 | 一级黄色大毛片 | 少妇真实被内射视频三四区 | 国产 日韩 一区 | 精品中文字幕在线观看 | 97影院手机版 | 免费在线视频你懂的 | 一区二区高清在线观看 | 国产精品久久999 | 亚洲中文字幕在线观看 | 香蕉视频成人在线 | 国产老头户外野战xxxxx | 精品一二三区久久aaa片 | 亚洲欧洲日本一区二区三区 | 午夜电影在线播放 | 中文字幕另类 | 亚洲一二三四五 | 一起草国产 | 灌篮高手全国大赛电影 | 澳门av在线| 日本福利视频导航 | 欧美日韩不卡一区二区 | 妞妞av| 无码少妇一级AV片在线观看 | 三级在线网址 | 成人在线不卡 | 国产精品无码免费专区午夜 | 亚洲高清视频一区二区 | 亚洲精品一区二区三区蜜桃久 | 亚洲国产精品av | 日本在线视频一区 |