前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >vue3 day02

vue3 day02

作者头像
花花522
发布2023-03-07 16:05:24
2270
发布2023-03-07 16:05:24
举报
文章被收录于专栏:花花爱咖啡

reactive

  • 作用: 定义一个对象类型的响应式数据(基本类型不要用它,要用ref函数)
  • 语法: const 代理对象 = reactive(源对象) 接收一个对象(或数组),返回一个代理对象(Proxy的实例对象,简称proxy对象)
  • reactive定义的响应式数据是深层次的
  • 内部基于es6的proxy实现的,通过代理对象操作源对象内部数据进行操作

如果使用reactive来定义基本类型,会有如下报错

代码语言:javascript
复制
let number = reactive(666)
  • 使用reactive代理ref 避免.value写法
代码语言:javascript
复制
<template>

  <h1>我是setup测试</h1>
  <h1>个人信息</h1>
  <h2>{{ person.name }}</h2>
  <h2>{{ person.age }}</h2>
  <button @click="sayHello">sayHello</button>
  <h2>职业:{{ person.job.jobs }}</h2>
  <h2>薪水:{{ person.job.salary }}</h2>
  <h2>爱好{{person.hobby}}</h2>
</template>

<script>


import {reactive} from "vue";

export default {
  name: 'App',
  setup() {


    let person = reactive({
      name: "花花",
      age: 18,
      job: {
        jobs: "前端开发工程师",
        salary: '3k'
      },
      hobby: ['游戏', '篮球', '花花']
    });

    function sayHello() {
      person.name = "花花2";
      person.age = 20;
      person.job.salary = '6k'
      person.job.jobs = "全栈开发工程师"
      person.hobby[0] = '学习'
    }

    return {
      person, sayHello
    }
  }

}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

新特性:数组可以直接使用下标修改

应式原理

vue2的响应式原理

  • vur2,0实现的原理
    • 对象类型,通过Object.defineProperty()对属性的读取,修改进行拦截(数据劫持)
    • 数组类型:通过重写数组的更新等一系列方法来实现拦截.(对数组的变更方法进行了包裹) Object.defineProperty(data,'count',{ set(){}, get(){} })
  • vue2存在的问题<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><script> let person = { name: '花花', age: 20 } let p= {}; Object.defineProperty(p, 'name', { configurable: true, set(v) { console.log(`有人修改了person的name属性,修改后为
    • 新增属性,删除属性,界面不会更新
    • 直接通过下标修改数组,界面不会在自动更新

vue3响应式原理

  • 实现初版
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<script>
    let person = {
        name: '花花',
        age: 20
    }

    let p = new Proxy(person, {
        set(target, p, value, receiver) {
            console.log(`修改${target}的${p}属性,修改后为${value}`)
            target[p] = value
        },

        get(target, p, receiver) {
            console.log(`获取${target}的${p}属性`)
            return target[p];
        },

        deleteProperty(target, p) {
            console.log(`删除${target}身上的 ${p}`)
            return delete target[p]
        }
    })

</script>
<body>
</body>
</html>
  • 使用反射实现响应式
代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<script>
    let person = {
        name: '花花',
        age: 20
    }


     let p = new Proxy(person, {
         set(target, p, value, receiver) {
             console.log(`修改${target}的${p}属性,修改后为${value}`)
             // target[p] = value
             Reflect.set(target,p,value)
         },

         get(target, p, receiver) {
             console.log(`获取${target}的${p}属性`)
             // return target[p];
             return Reflect.get(target,p)
         },

         deleteProperty(target, p) {
             console.log(`删除${target}身上的 ${p}`)
             // return delete target[p]
             return Reflect.deleteProperty(target,p)

         }
     })
</script>
<body>
</body>
</html>

效果是一样的 ,而且更为贴近框架

总结

  • 实现原理
    • 通过Proxy(代理):拦截对象中任意属性的变化,包括:属性值的读写,属性的添加,属性的删除等
    • 通过Reflect(反射):对源对象的属性进行操作
  • MDN的文档
    • https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect
    • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy
代码语言:javascript
复制
const target = {
 notProxied: "original value",
 proxied: "original value"
};

const handler = {
 get: function(target, prop, receiver) {
   if (prop === "proxied") {
     return "replaced value";
  }
   return Reflect.get(...arguments);
}
};

const proxy = new Proxy(target, handler);

console.log(proxy.notProxied); // "original value"
console.log(proxy.proxied);    // "replaced value"
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 花花爱咖啡 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • reactive
  • 应式原理
    • vue2的响应式原理
      • vue3响应式原理
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档