Vue零基础教程|从前端框架到GIS开发系列课程(七)响应式系统介绍

前文指路:《Vue零基础教程》,从前端框架到GIS开发系列课程

Vue零基础教程|从前端框架到GIS开发系列课程(二)

Vue零基础教程|从前端框架到GIS开发系列课程(三)模板语法

Vue零基础教程|从前端框架到GIS开发系列课程(四)计算属性与侦听器

Vue零基础教程|从前端框架到GIS开发系列课程(五)组件式开发

Vue零基础教程|从前端框架到GIS开发系列课程(六)组合式API

Party1 什么是响应式

当数据改变时, 引用数据的函数会自动重新执行

Party2 手动完成响应过程

首先, 明确一个概念:响应式是一个过程, 这个过程存在两个参与者: 一方触发, 另一方响应

同样, 所谓数据响应式的两个参与者

●触发者: 数据

●响应者: 引用数据的函数

当数据改变时, 引用数据的函数响应数据的改变, 重新执行

我们先手动完成响应过程

示例

复制代码
<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>  </head>  <body>    <div id="app"></div>    <script>      // 定义一个全局对象: `触发者`      const obj = { name: 'hello' }
      // effect函数引用了obj.name, 这个函数就是 `响应者`      function effect() {        // 这里可以通过app拿到DOM对象        app.innerHTML = obj.name      }
      effect()
      // 当obj.name改变时, 手动执行effect函数, 完成响应过程      setTimeout(() => {        obj.name = 'brojie'        effect()      }, 1000)</script>  </body></html>

为了方便, 我们把引用了数据的函数 叫做副作用函数

Party3 副作用函数

如果一个函数引用了外部的资源, 这个函数会受到外部资源改变的影响

我们就说这个函数存在副作用. 因此, 也把该函数叫做副作用函数

这里, 大家不要被这个陌生的名字吓唬住

所谓副作用函数就是引用了数据的函数或者说数据关联的函数

Party4 自定义设置过程

如果我们能感知数据改变, 拦截到赋值操作. 自定义设置过程

在赋值的同时调用一下数据关联的副作用函数, 就可以实现自动重新执行

理论上可行, 开始动手实践

1) Proxy代理对象

这里我们需要先补充一下Proxy相关的知识. 如果已经知道的小伙伴可以略过

new Proxy: 传入一个源对象, 返回一个新对象(代理对象)

当访问代理对象的属性时, 可以自定义访问过程

当设置代理对象的属性时, 可以自定义设置过程

示例

复制代码
<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>  </head>  <body>    <script>      // 定义一个源对象(目标对象)      const obj = { name: 'xiaopang' }            // 创建一个代理对象      const proxy = new Proxy(obj, {        get(target, key) {          // 当访问proxy代理对象的属性时, 会执行get函数          // 将get函数的返回值作为表达式的值          console.log(target, key)          return target[key] // obj.name obj[name]        },        set(target, key, value) {          // 当设置proxy代理对象的属性时, 会执行set函数          console.log('自定义set操作', value)          target[key] = value          return true        },      })      // console.log(proxy.name)      // console.log(proxy.age)      proxy.name = 'xxp'      console.log(obj)</script>  </body></html>

这样就确定了思路

1先创建代理对象

2再操作代理对象(给代理对象赋值)

2) 最基本的reactive函数

定义一个函数reactive, 传入一个普通对象, 返回代理对象

示例​​​​​​​

复制代码
<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>  </head>  <body>    <script>      function isObject(value) {        return typeof value === 'object' && value !== null      }      /**       * 创建响应式数据       *  @param [object]: 普通对象       *  @return [Proxy]: 代理对象       */      function reactive(data) {        if (!isObject(data)) return
        return new Proxy(data, {          get(target, key) {            return target[key]          },          set(target, key, value) {            target[key] = value            return true          },        })      }
      const state = { name: 'xiaopang' }      const p = reactive(state)      p.name = 'xxp'      console.log(p.name)</script>  </body></html>

Party5 最基本的响应式

既然可以自定义set操作, 只需要在自定义set操作时, 重新执行属性关联的副作用函数

示例​​​​​​​

复制代码
<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>  </head>  <body>    <div id="app">hello</div>    <script>      /**       * 定义响应式       *  @param [object] : 普通对象       *  @return [Proxy] : 代理对象       */      function reactive(data) {        // 如果传入的data不是一个普通对象, 不处理        if (typeof data !== 'object' || data == null) return
        return new Proxy(data, {          get(target, key) {            console.log(`自定义访问${key}`)            return target[key]          },          set(target, key, value) {            console.log(`自定义设置${key}=${value}`)            target[key] = value // 先更新值            effect() // 再调用effect, 调用effect时会重新获取新的数据            return true          },        })      }
      const pState = reactive({ name: 'hello' })
      function effect() {        app.innerHTML = pState.name      }
      setTimeout(() => {        pState.name = 'brojie'      }, 1000)</script>  </body></html>

看到这里, 恭喜你, 已经掌握了最核心的原理🤝

💡小结

1响应式是一个过程, 存在触发者和响应者

2数据的改变, 触发关联的副作用函数响应(重新执行)

3通过Proxy代理源数据

4在Proxy的自定义set操作中, 重新执行副作用函数

需要vue教程资料,备注:《Vue零基础教程》

相关推荐
waterHBO1 分钟前
css 模拟一个动画效果,消息堆叠。
前端·css
前端加油站17 分钟前
在 cursor 成为流行的开发方式后,作为普通开发我们能做什么
前端
Cache技术分享25 分钟前
163. Java Lambda 表达式 - Function 的链式组合
前端·后端
柯南952737 分钟前
Vue 3 响应式系统源码解析
vue.js
Zestia42 分钟前
页面点击跳转源代码?——element-jumper插件实现
前端·javascript
前端小白199542 分钟前
面试取经:工程化篇-webpack性能优化之优化loader性能
前端·面试·前端工程化
PineappleCoder42 分钟前
大小写 + 标点全搞定!JS 如何精准统计单词频率?
前端·javascript·算法
zhangbao90s43 分钟前
Web组件:使用Shadow DOM
前端
hhy前端之旅44 分钟前
语义版本控制:掌握版本管理的艺术
前端
coding随想44 分钟前
深入浅出DOM操作的隐藏利器:Range(范围)对象——掌控文档的“手术刀”
前端