vue3中toRaw以及markRow情況(系列八)


reactive類型數據代碼

<template>
  <div>
      <p>{{state}}</p>
    <button @click="myFn">按鈕</button>
  </div>
</template>

<script>

  import {reactive} from 'vue';
export default {
  name: 'App',
  setup() {
      let obj = {name:'lnj', age:18};
      let state = reactive(obj);
      // console.log(obj === state); // false // state和obj的關系:
      // 引用關系, state的本質是一個Proxy對象, 在這個Proxy對象中引用了obj(同一個內存地址)

      function myFn() {
          // 如果直接修改obj, 那么是無法觸發界面更新的 // 只有通過包裝之后的對象來修改state, 才會觸發界面的更新
          obj.name='zs'
          console.log(obj)  // {name: "zs", age: 18}
          state.name = 'zs';
          console.log(state); // {name: "zs", age: 18}
      }
    return {state, myFn}
  }
}
</script>

<style>

</style>

我們點擊按鈕后,發現obj修改name的屬性的數據成功了,但是頁面視圖並沒有更新,不是響應式的。通過封裝了state的對象,修改name屬性,會更改頁面視圖更新

一句話,如果我們對 reactive 的源數據進行改變的時候,是不會引起界面的改變,也就不會產生有關的計算了。

如果我們有修改 obj的內容,又不想觸發界面改變的時候,我們就可以修改 obj

可問題是,如果我沒創建 obj 呢?又或者 obj 在另一個文件里創建了,怎么辦。

toRaw

reactive的toRaw

<template>
  <div>
      <p>{{state}}</p>
    <button @click="myFn">按鈕</button>
  </div>
</template>

<script>
  /*
  1.toRaw
  從Reactive 或 Ref中得到原始數據

  2.toRaw作用
  做一些不想被監聽的事情(提升性能)
  * */
  import {reactive, toRaw} from 'vue';
export default {
  name: 'App',
  setup() {
    
      /*
      ref/reactive數據類型的特點:
      每次修改都會被追蹤, 都會更新UI界面, 但是這樣其實是非常消耗性能的
      所以如果我們有一些操作不需要追蹤, 不需要更新UI界面, 那么這個時候,
      我們就可以通過toRaw方法拿到它的原始數據, 對原始數據進行修改 這樣就不會被追蹤, 這樣就不會更新UI界面, 這樣性能就好了
      * */
      let state = reactive(
        {name:'lnj', age:18}
      );
      // 獲取state的源數據
      let obj2 = toRaw(state); // console.log({name:'lnj', age:18} === obj2); // true

      // console.log({name:'lnj', age:18} === state); // false

      function myFn() {
        // 獲取的源數據更改,不會觸發頁面更新
          obj2.name = 'zs';
          console.log(obj2); // {name: "zs", age: 18}
          // state.name = 'zs';
          // console.log(state);// {name: "zs", age: 18}
      }
    return {state, myFn}
  }
}
</script>

<style>

</style>

 

ref的toRow

<template>
  <div>
      <p>{{state}}</p>
    <button @click="myFn">按鈕</button>
  </div>
</template>

<script>
  import { toRaw, ref} from 'vue';
export default {
  name: 'App',
  setup() {
      /*
      1.ref本質: reactive
      ref(obj) -> reactive({value: obj})
      * */
      let state = ref({name:'lnj', age:18});
      // 注意點: 如果想通過toRaw拿到ref類型的原始數據(創建時傳入的那個數據)
      //        那么就必須明確的告訴toRaw方法, 要獲取的是.value的值
      //        因為經過Vue處理之后, .value中保存的才是當初創建時傳入的那個原始數據
      // let obj2 = toRaw(state);
      let obj2 = toRaw(state.value);
      console.log(state);
      console.log(obj2);

      function myFn() {
        // 獲取的源數據更改,不會觸發頁面更新
          obj2.name = 'zs';
          console.log(obj2); // {name: "zs", age: 18}
          // state.name = 'zs';
          // console.log(state);// {name: "zs", age: 18}
      }
    return {state, myFn}
  }
}
</script>

<style>

</style>

 

markRow

<template>
  <div>
      <p>{{state}}</p>
    <button @click="myFn">按鈕</button>
  </div>
</template>

<script>
  /*
  1.markRaw
 將數據標記為永遠不能追蹤的數據 一般在編寫自己的第三方庫時使用
  * */
  import {reactive, markRaw} from 'vue';
export default {
  name: 'App',
  setup() {
      let obj = {name: 'lnj', age: 18};
      // 不能追蹤,監聽,作為響應式的數據
      obj = markRaw(obj);
      let state = reactive(obj);
      function myFn() {
        // 數據更改了,但是頁面ui還是沒有發生改變
          state.name = 'zs';
      }
    return {state, myFn}
  }
}
</script>

<style>

</style>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM