Rumah > hujung hadapan web > View.js > teks badan

Bagaimana untuk menyelesaikan masalah yang disebabkan oleh kehilangan responsif dalam tugasan struktur dalam Vue3

王林
Lepaskan: 2023-05-10 08:46:13
ke hadapan
3543 orang telah melayarinya

    Pelaksanaan sistem responsif dengan nilai asal

    Sebelum memahami pelaksanaan sistem responsif dengan nilai asal, mari kita semak dahulu keupayaan proksi !

    const obj = {
      name: 'win'
    }
    const handler = {
      get: function(target, key){
        console.log('get--', key)
        return Reflect.get(...arguments)  
      },
      set: function(target, key, value){
        console.log('set--', key, '=', value)
        return Reflect.set(...arguments)
      }
    }
    const data = new Proxy(obj, handler)
    data.name = 'ten'
    console.log(data.name,'data.name22')
    Salin selepas log masuk

    Dalam kod di atas, kami mendapati bahawa penggunaan proksi itu sendiri adalah pemintasan objek Melalui nilai pulangan new Proxy, objek obj dipintas dengan cara ini, apabila anda mengakses nilai dalam objek, Ia akan mencetuskan kaedah get Apabila anda mengubah suai nilai dalam objek, ia akan mencetuskan kaedah set Tetapi apabila ia mencapai nilai asal, ia tidak mempunyai objek. new proxy tidak berguna lagi. Dalam keadaan terdesak, kami hanya boleh membungkusnya, jadi kami perlu menggunakan .value untuk mengakses

    Mari kita lihat pelaksanaan khusus:

    import { reactive } from "./reactive";
    import { trackEffects, triggerEffects } from './effect'
    export const isObject = (value) => {
        return typeof value === 'object' && value !== null
    }
    // 将对象转化为响应式的
    function toReactive(value) {
        return isObject(value) ? reactive(value) : value
    }
    class RefImpl {
        public _value;
        public dep = new Set; // 依赖收集
        public __v_isRef = true; // 是ref的标识
        // rawValue 传递进来的值
        constructor(public rawValue, public _shallow) {
            // 1、判断如果是对象 使用reactive将对象转为响应式的
            // 浅ref不需要再次代理
            this._value = _shallow ? rawValue : toReactive(rawValue);
        }
        get value() {
            // 取值的时候依赖收集
            trackEffects(this.dep)
            return this._value;
        }
        set value(newVal) {
            if (newVal !== this.rawValue) {
                // 2、set的值不等于初始值 判断新值是否是对象 进行赋值
                this._value = this._shallow ? newVal : toReactive(newVal);
                // 赋值完 将初始值变为本次的
                this.rawValue = newVal
                triggerEffects(this.dep)
            }
        }
    }
    Salin selepas log masuk

    Kod di atas , Ia adalah pembungkusan nilai asal Ia dibungkus sebagai objek, dan nilai asal diakses melalui kaedah get value dan set value, yang membawa kepada keperluan .value operasi ini sebenarnya tidak berdaya pilihan

    Ia bersamaan dengan dua botol racun, anda perlu memilih satu Anda tidak boleh memiliki kek anda dan memakannya juga

    Mengapa ES6 dibongkar dan tidak boleh digunakan secara sembarangan, yang akan. musnahkan ciri responsifnya

    Pertama Masalahnya akhirnya jelas, jadi mari kita lihat soalan kedua paling penting, mengapa tugasan struktur memusnahkan ciri responsif

    latar belakang proksi

    Sebelum ini kita mulakan, mari mula-mula Bincangkan mengapa penyelesaian responsif perlu diubah

    vue2 adalah berdasarkan Object.defineProperty, tetapi ia mempunyai banyak kecacatan, seperti tidak boleh memantau pengubahsuaian tatasusunan berdasarkan subskrip, dan tidak menyokong Map, Set, WeakMap dan WeakSet Defects seperti ,

    sebenarnya tidak melambatkan pembangunan kami masih menjadi aliran utama pemahaman ialah

    ,

    , walaupun 与时俱进Terdapat banyak penambahbaikan berbanding Object.defineProperty, tetapi ia bukan tanpa sebarang kekurangan Contohnya, 新一代的版本,一定要紧跟语言的特性,一定要符合新时代的书写风格proxy不兼容IE Bagaimana apa-apa dalam dunia menjadi sempurna? Keberanian Youda terletak pada melepaskan sedikit masa kini dan mendapatkan masa depan!

    Prinsip Pelaksanaan

    Setelah memahami latar belakang, mari kita semak prinsip

    dengan cara yang palsu, walaupun perkara ini telah dijelaskan dengan teruk.

    proxyWalau bagaimanapun, apa yang penting semasa menulis hidrologi: dua perkataan - koherensi

            const obj = {
                count: 1
            };
            const proxy = new Proxy(obj, {
                get(target, key, receiver) {
                    console.log("这里是get");
                    return Reflect.get(target, key, receiver);
                },
                set(target, key, value, receiver) {
                    console.log("这里是set");
                    return Reflect.set(target, key, value, receiver);
                }
            });
            
            console.log(proxy)
            console.log(proxy.count)
    Salin selepas log masuk

    Kod di atas ialah penggunaan Proksi khusus Dengan bekerjasama dengan Reflect, pemintasan objek boleh dicapai

    Bagaimana untuk menyelesaikan masalah yang disebabkan oleh kehilangan responsif dalam tugasan struktur dalam Vue3Dengan pergantungan sedemikian, responsif boleh dicapai Anda boleh mendapati bahawa keseluruhan objek obj dipintas, tetapi anda mendapati objek itu bersarang satu tahap lebih dalam

    < 🎜. >

    Contohnya:

        const obj = {
                count: 1,
                b: {
                    c: 2
                }
            };
         console.log(proxy.b)
         console.log(proxy.b.c)
    Salin selepas log masuk
    Dia tidak boleh memintas, kita perlu membungkusnya
        const obj = {
                a: {
                    count: 1
                }
            };
            function reactive(obj) {
                return new Proxy(obj, {
                    get(target, key, receiver) {
                        console.log("这里是get");
                        // 判断如果是个对象在包装一次,实现深层嵌套的响应式
                        if (typeof target[key] === "object") {
                            return reactive(target[key]);
                        };
                        return Reflect.get(target, key, receiver);
                    },
                    set(target, key, value, receiver) {
                        console.log("这里是set");
                        return Reflect.set(target, key, value, receiver);
                    }
                });
            };
            const proxy = reactive(obj);
    Salin selepas log masuk

    Baiklah, prinsipnya sudah selesai, mari kita kaji secara formal dan sekarang senaraikan ia Berikut adalah beberapa situasi di mana tindak balas hilang yang saya ketahui:

    1 Nyahbina objek
      kerana ia akan kehilangan tindak balas
    • props<. 🎜> 2. Penugasan langsung

      objek responsif
    • reactive3. akan Kehilangan responsif

             const obj = {
                  a: {
                      count: 1
                  },
                  b: 1
              };
                  //reactive 是上文中的reactive
                 const proxy = reactive(obj);
              const {
                  a,
                  b
              } = proxy;
              console.log(a)
              console.log(b)
              console.log(a.count)
      Salin selepas log masuk
    • vuexDalam kod di atas, kami mendapati tugasan yang memusnahkan,

      ,
    • , akan mencetuskan respons

    ini kenapa kain bulu? Jangan risau, mari kita jelaskan setiap satu? Mari kita bincangkan dahulu mengapa kereaktifan hilang semasa memusnahkan tugasan? Kami tahu bahawa tugasan memusnahkan membezakan antara penugasan jenis primitif dan penugasan jenis rujukan

    Bagaimana untuk menyelesaikan masalah yang disebabkan oleh kehilangan responsif dalam tugasan struktur dalam Vue3Penugasan jenis primitif adalah bersamaan dengan nilai lulus dan nilai jenis rujukan adalah bersamaan dengan rujukan lulus<🎜. >

    b 不会触发响应式 bersamaan dengan: a如果你访问的时候

       // 假设a是个响应式对象
      const a={ b:1}
      // c 此时就是一个值跟当前的a 已经不沾边了
      const c=a.b
    // 你直接访问c就相当于直接访问这个值 也就绕过了 a 对象的get ,也就像原文中说的失去响应式
    Salin selepas log masuk

    Kalau begitu kenapa

    responsif? Kerana
    ialah jenis rujukan, kita masih ingat? Adakah terdapat penghakiman dalam kod di atas? Jika ia adalah

    maka bungkusnya semula sebagai responsif

    Disebabkan ciri semasa, jika ia adalah jenis rujukan, anda tidak akan kehilangan responsif apabila mengakses kandungan

      // 假设a是个响应式对象
     const a={ b:{c:3}}
     // 当你访问a.b的时候就已经重新初始化响应式了,此时的c就已经是个代理的对象
     const c=a.b
    // 你直接访问c就相当于访问一个响应式对象,所以并不会失去响应式
    Salin selepas log masuk
    . Di atas secara kasar menerangkan mengapa tugasan yang memusnahkan boleh menyebabkan kehilangan responsif Saya rasa dokumen itu terlalu malas untuk menerangkan sebabnya, jadi ia hanya membuat peraturan, anda! Jangan gunakan

    , jika tidak, anda mungkin fikir ia adalah pepijat

    dan ubah tabiat penggunaan pengguna terlebih dahulu! Tidak biasa dengan a

    secara langsung memberikan objek reaktif

    a Apabila kami mula-mula menggunakan vue3, kami menyatakan bahawa kami akan menulis kod berikut object

     const vue = reactive({ a: 1 })
     vue = { b: 2 }
    Salin selepas log masuk

    然后就发出疑问reactive不是响应式的吗? 为啥我赋值了以后,他的响应式就没了 ,接着破口大骂,垃圾vue

    其实啊,这就是您对于js 原生的概念不清除,其实尤大 已经做了最大的努力,来防止你进行错误操作了

    比如,由于解构赋值的问题, 他直接禁止了reactive的解构赋值

    Bagaimana untuk menyelesaikan masalah yang disebabkan oleh kehilangan responsif dalam tugasan struktur dalam Vue3

    当你用解构赋值操作的时候,他直接禁用了那有人又问了, 为啥props 不给禁用了呢?因为你的props 的数据可能不是响应式的啊,不是响应式的,我得能啊,尤大他也不能干涉用户使用新语法啊

    所以还是那句话:框架现在的呈现,其实充满了取舍,有时候真是两瓶毒药,挑一瓶!

    回归正题,我们再来说说 原生js 语法,首先需要确认的是,原生js 的引用类型的赋值,其实是 按照引用地址赋值!

     // 当reactive 之后返回一个代理对象的地址被vue 存起来,
     // 用一个不恰当的比喻来说,就是这个地址具备响应式的能力
     const vue = reactive({ a: 1 })
     //  而当你对于vue重新赋值的时候不是将新的对象赋值给那个地址,而是将vue 换了个新地址
     // 而此时新地址不具备响应式,可不就失去响应式了吗
     vue = { b: 2 }
    Salin selepas log masuk

    在这里我要替,尤大说句公道话,人家又没收你钱,还因为他,你有口饭吃,您自己不能与时俱进,拥抱新事物,那是您没能耐,这是典型的端起碗吃肉,放下筷子骂娘

    vuex中组合API赋值

    在vuex 用赋值也可能会失去响应式:

    import { computed } from &#39;vue&#39;
    import { useStore } from &#39;vuex&#39;
    export default {
      setup () {
        const store = useStore()
        return {
          // 在 computed 函数中访问 state
          count: computed(() => store.state.count),
    
          // 在 computed 函数中访问 getter
          double: computed(() => store.getters.double)
        }
      }
    }
    Salin selepas log masuk

    以上代码中我们发现store.getters.double 必须用computed 包裹起来,其实道理是一样的,也是变量赋值的原因,在这里我们就不再赘述!

    Atas ialah kandungan terperinci Bagaimana untuk menyelesaikan masalah yang disebabkan oleh kehilangan responsif dalam tugasan struktur dalam Vue3. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

    Label berkaitan:
    sumber:yisu.com
    Kenyataan Laman Web ini
    Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
    Tutorial Popular
    Lagi>
    Muat turun terkini
    Lagi>
    kesan web
    Kod sumber laman web
    Bahan laman web
    Templat hujung hadapan