reactive – Vue3 composition(組合式)API

    reactive()–定義響應(yīng)式數(shù)據(jù)

    reactive()接受一個對象,包括json數(shù)據(jù)和數(shù)組都可以,返回一個對象的響應(yīng)式代理(Proxy對象)。

    <script src="https://unpkg.com/vue@next"></script>
    <div id="Application">
    
    </div>
    <script>
        const App = Vue.createApp({
            //進(jìn)行組件數(shù)據(jù)初始化
            setup() {
                //數(shù)據(jù)
                //基本類型使用ref,引用類型使用reactive
                //增刪改查都可以操作。
                //內(nèi)部是通過Proxy代理的形式
                let myData = Vue.reactive({
                    value: 0
                })
                //按鈕的單擊方法
                function click() {
                    myData.value += 1
                    console.log(myData.value)
                }
                //數(shù)據(jù)返回
                return {
                    myData,
                    click
                }
            },
            //模板中可以直接使用setup方法中定義的數(shù)據(jù)和函數(shù)
            template: `
            <h1>測試數(shù)據(jù):{{ myData.value }}</h1>
            <button @click="click">點擊</button>
            `
        })
        App.mount("#Application")
    </script>

    您可以打開瀏覽器控制臺,觀察控制臺的打印數(shù)據(jù)

    • eactive 是 Vue3 中提供的實現(xiàn)響應(yīng)式數(shù)據(jù)的方法。
    • 在 Vue2 中響應(yīng)式數(shù)據(jù)是通過 defineProperty 來實現(xiàn)的,
    • 在 Vue3 中響應(yīng)式數(shù)據(jù)是通過 ES6 的 Proxy來實現(xiàn)的。
    • reactive 參數(shù)必須是對象 (json / arr)
    • 如果給 reactive 傳遞了其它對象
    • 默認(rèn)情況下,修改對象無法實現(xiàn)界面的數(shù)據(jù)綁定更新。
    • 如果需要更新,需要進(jìn)行重新賦值。(即不允許直接操作數(shù)據(jù),需要放個新的數(shù)據(jù)來替代原數(shù)據(jù))

    在 reactive 使用基本類型參數(shù)

    基本類型(數(shù)字、字符串、布爾值)在 reactive 中無法被創(chuàng)建成 proxy 對象,也就無法實現(xiàn)監(jiān)聽。

    <script src="https://unpkg.com/vue@next"></script>
    <div id="Application">
    </div>
    
    <script>
        const App = Vue.createApp({
            setup() {
                let msg = Vue.reactive(0)
                function click() {
                    console.log(msg);
                    msg++;
                }
                return {
                    msg,
                    click
                };
            },
            template: `
            <h1>測試數(shù)據(jù):{{ msg }}</h1>
            <button @click="click">點擊</button>
            `
        })
        App.mount("#Application")
    
    </script>

    點擊 按鈕 ,我們期望的結(jié)果是數(shù)字從 0 變成 1,然而實際上界面上的數(shù)字并沒有發(fā)生任何改變。

    查看控制臺,它的輸出是這樣的(我點了 3 次)(您可以嘗試F12打開控制臺實時觀察效果)

    1
    2
    3

    出現(xiàn)提示

    value cannot be made reactive: 0

    而輸出的值確實發(fā)生了變化,只不過這種變化并沒有反饋到界面上,也就是說并沒有實現(xiàn)雙向數(shù)據(jù)綁定。當(dāng)然,如果是 ref 的話,就不存在這樣的問題。

    而如果要使用 reactive ,我們需要將參數(shù)從 基本類型 轉(zhuǎn)化為 對象。

    <script src="https://unpkg.com/vue@next"></script>
    <div id="Application">
    </div>
    
    <script>
        const App = Vue.createApp({
            setup() {
                let msg = Vue.reactive({ value: 0 })
                function click() {
                    console.log(msg);
                    msg.value++;
                }
                return {
                    msg,
                    click
                };
            },
            template: `
            <h1>測試數(shù)據(jù):{{ msg.value }}</h1>
            <button @click="click">點擊</button>
            `
        })
        App.mount("#Application")
    
    </script>

    將參數(shù)替換成了對象?{num: 0},此時,點擊按鈕界面就會產(chǎn)生改變(我點了 3 次)。

    控制臺打印消息(您可以在本頁點擊按鈕,觀察控制臺變化)

    Proxy?{value: 0}
    [[Handler]]: Object
    [[Target]]: Object
    [[IsRevoked]]: false
     Proxy?{value: 1}
    Proxy?{value: 2}
    

    可以看到,msg?成功被創(chuàng)建成了?proxy?對象,

    Proxy – Javascript中的代理器

    他通過劫持對象的?get?和?set?方法實現(xiàn)了對象的雙向數(shù)據(jù)綁定。

    對象內(nèi)部變化

    深層的、對象內(nèi)部的變化也能被察覺到(注意下面代碼中的?inner?)

    <script src="https://unpkg.com/vue@next"></script>
    
    <div id="Application">
    </div>
    
    <script>
        const App = Vue.createApp({
            setup() {
                let msg = Vue.reactive({
                    value: {
                        inner: 0
                    }
                })
                function click() {
                    console.log(msg);
                    msg.value.inner++;
                }
                return {
                    msg,
                    click
                };
            },
            template: `
            <h1>測試數(shù)據(jù):{{ msg.value.inner }}</h1>
            <button @click="click">點擊</button>
            `
        })
        App.mount("#Application")
    
    </script>

    可點擊按鈕,打開瀏覽器控制臺觀察變化

    數(shù)組變化

    <script src="https://unpkg.com/vue@next"></script>
    
    <div id="Application">
    </div>
    
    <script>
        const App = Vue.createApp({
            setup() {
                let msg = Vue.reactive([1, 2, 3])
                function click() {
                    console.log(msg);
                    msg[0] += 1;
                    msg[1] = 5;
                }
                return {
                    msg,
                    click
                };
            },
            template: `
            <h1>測試數(shù)據(jù):{{ msg }}</h1>
            <button @click="click">點擊</button>
            `
        })
        App.mount("#Application")
    
    </script>

    可點擊按鈕,打開瀏覽器控制臺觀察變化

    重新賦值

    在?reactive?使用?Date?參數(shù)

    如果參數(shù)不是數(shù)組、對象,而是稍微奇怪一點的數(shù)據(jù)類型,例如說?Date,我們需要重新賦值

    <script src="https://unpkg.com/vue@next"></script>
    
    <div id="Application">
    </div>
    
    <script>
        const App = Vue.createApp({
            setup() {
                let msg = Vue.reactive({
                    date: new Date()
                })
                function click() {
                    console.log("第一次打印", msg);
                    msg.date.setDate((msg.date.getDate() + 1));
                    msg.date = new Date(msg.date);
                    console.log("第二次打印", msg)
    
                }
                return {
                    msg,
                    click
                };
            },
            template: `
            <h1>測試數(shù)據(jù):{{ msg.date }}</h1>
            <button @click="click">點擊</button>
            `
        })
        App.mount("#Application")
    
    </script>

    這里我采用了拷貝的方案重新賦值了?msg.date,界面成功發(fā)生了變化(日期 + 1)。

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

    值得注意的是,reactive()?返回的是一個源對象的?Proxy,它和源對象是不相等的:

    const raw = {}
    const proxy = reactive(raw)
     
    // 代理和原始對象不是全等的
    console.log(proxy === raw) // false

    只有代理是響應(yīng)式的,更改原始的對象不會觸發(fā)更新。因此,使用 Vue 的響應(yīng)式系統(tǒng)的最佳實踐是 僅使用代理作為狀態(tài)。

    為保證訪問代理的一致性,對同一個對象調(diào)用 reactive() 會總是返回同樣的代理,而對代理調(diào)用 reactive() 則會返回它自己:

    // 在同一個對象上調(diào)用 reactive() 會返回相同的代理
    console.log(reactive(raw) === proxy) // true
    // 在一個代理上調(diào)用 reactive() 會返回它自己
    console.log(reactive(proxy) === proxy) // true

    這個規(guī)則對深層級的對象也適用。依靠深層響應(yīng)性,響應(yīng)式對象內(nèi)的深層級對象依然是代理:

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

    參考文章

    給TA贊賞
    共{{data.count}}人
    人已贊賞
    ??
    Npcink上的部份代碼及教程來源于互聯(lián)網(wǎng),僅供網(wǎng)友學(xué)習(xí)交流,若您喜歡本文可附上原文鏈接隨意轉(zhuǎn)載。
    無意侵害您的權(quán)益,請發(fā)送郵件至 1355471563#qq.com 或點擊右側(cè) 私信:Muze 反饋,我們將盡快處理。
    ?
    購物車
    優(yōu)惠劵
    搜索
    主站蜘蛛池模板: 亚洲视频一区二区三区| 无码AV一区二区三区无码 | 国产一区二区三区精品视频| 午夜福利一区二区三区在线观看| 久久久精品人妻一区亚美研究所 | 亚洲AV无码一区二区三区鸳鸯影院| 国产日韩高清一区二区三区| 国产av一区二区精品久久凹凸 | 偷拍激情视频一区二区三区| 精品欧美一区二区在线观看| 亚洲欧美国产国产综合一区| 日韩精品一区二区三区中文3d| 狠狠综合久久av一区二区| 乱码精品一区二区三区| 亚洲一区二区三区免费在线观看| 亚洲av无码一区二区乱子伦as| 久久青草国产精品一区| 久久精品一区二区| 久久精品国产一区二区三区不卡 | 亚洲高清一区二区三区电影| 亚洲av无码不卡一区二区三区 | 亚洲国产成人久久综合一区| 美女福利视频一区| 九九久久99综合一区二区| 亚洲av午夜福利精品一区| 国产婷婷色一区二区三区| 日本午夜精品一区二区三区电影| av无码人妻一区二区三区牛牛| 亚洲毛片αv无线播放一区| 中文字幕一区二区精品区| 一区二区和激情视频| 国产一区二区三区在线电影| 久久久久女教师免费一区| 日韩精品视频一区二区三区 | 中文字幕亚洲一区二区三区| 亚洲av日韩综合一区久热| 97av麻豆蜜桃一区二区| 国产亚洲一区二区三区在线观看| 精品人体无码一区二区三区| 日本在线视频一区| 亚洲国产成人久久综合一区77|