zoukankan      html  css  js  c++  java
  • 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>
  • 相关阅读:
    antd vue如何在父组件里打开子组件(子组件是个模态框)?
    webpack知识点整理
    JavaScript中常用的方法汇总,全部整理好了,一定要收藏!
    从地址栏里面获取参数的值
    何为垫片?垫片是一种什么概念在js中?
    async 与 await使用
    纯手撸Promise
    如何使用 Promise?
    Notification 浏览器桌面通知的使用
    学习骨架屏(Skeleton Screens)技术
  • 原文地址:https://www.cnblogs.com/fsg6/p/14485117.html
Copyright © 2011-2022 走看看