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零基础教程》

相关推荐
雨汨16 分钟前
el-input限制输入数字,输入中文后数字校验失效
前端·javascript·vue.js
保持学习ing22 分钟前
帝可得- 人员管理
前端·vue.js·elementui
難釋懷23 分钟前
Vue全局事件总线
前端·javascript·vue.js
独立开阀者_FwtCoder37 分钟前
使用这个新的 ECMAScript 运算符告别 Try/Catch!
前端·javascript·github
云浪37 分钟前
让元素舞动!深度解密 CSS 旋转函数
前端·css
cdcdhj38 分钟前
vue中events选项与$on监听自定义事件他们的区别与不同,以及$emit与$on之间通信和mounted生命周期钩子函数有哪些作用和属性
前端·javascript·vue.js
Jinxiansen02111 小时前
Vue 3 弹出式计算器组件(源码 + 教程)
前端·javascript·vue.js
东京老树根1 小时前
SAP学习笔记 - 开发22 - 前端Fiori开发 数据绑定(Jason),Data Types(数据类型)
前端·笔记·学习
前端 贾公子1 小时前
手写 vue 源码 === runtime-dom 实现
前端·javascript·css
江城开朗的豌豆1 小时前
JavaScript篇:typeof 的魔法:原来你是这样判断类型的!
前端·javascript·面试