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

devtools/2024/12/28 7:28:11/

前文指路:《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零基础教程》


http://www.ppmy.cn/devtools/146043.html

相关文章

frameworks 之 WMS层级树

frameworks 之 WMS层级树 1. 容器类1. WindowContainer2. RootWindowContainer3. DisplayContent4. DisplayAreas4. 1 DisplayArea.Tokens4. 2 TaskDisplayArea4. 3 DisplayArea.Dimmable 5. WindowToken5.1 WallpaperWindowToken5.2 ActivityRecord 6. TaskFragment6.1 Task 7…

【QT】自定义QLabel

QLabel 既可以加载图片也可以绘制图形。 本章通过QLabel实现图片加载并在QLabel上绘制任意图形。 在使用 QLabel 实现加载图片功能&#xff0c;并在图片上绘制任意图形时&#xff0c;图片发生缩放后会存在图形拉伸情况&#xff0c;导致结果存在偏差。&#xff08;原因分析这里不…

[按键精灵IOS安卓版][脚本基础知识]按键post基本写法

这一期我们来讲按键post的写法&#xff0c;希望通过本期的学习&#xff0c;实现常见的post提交都能编写。 下面开始讲解&#xff1a; 一、使用的命令&#xff1a;url.httppost 选用这个命令的理由是它的参数比较全。 二、post请求都有哪些参数&#xff08;可能用到&#xf…

windows下vscode使用msvc编译器出现中文乱码

文章目录 [toc]1、概述2、修改已创建文件编码3、修改vscode默认编码 更多精彩内容&#x1f449;内容导航 &#x1f448;&#x1f449;C &#x1f448;&#x1f449;开发工具 &#x1f448; 1、概述 在使用MSVC编译器时&#xff0c;出现中文报错的问题可能与编码格式有关。UTF-…

qt创建线程的四种方式

第一种 继承QThread类&#xff0c;然后重写run()函数 // 线程一 Mythread1 new CMyThread; connect(Mythread1,&CMyThread::sig_num,this,&MainWindow::slots_thread1); connect(ui->pushButton,&QPushButton::clicked,[](){Mythread1->m_state ThreadSt…

[计算机网络]OSPF协议

开放最短路径优先OSPF 1&#xff09;OSPF的工作方式 1>和谁交换消息 使用洪泛法&#xff0c;向本自治系统的所有路由器发送消息。 2>交换什么消息 发送的消息就是与本路由器相邻的所有路由器的链路状态&#xff0c;但这只是路由器所知道的部分信息。 链路状态就是说…

【机器学习】因微知著,穷数通灵:微积分与机器学习的量化之美

文章目录 微积分基础&#xff1a;理解变化与累积的数学前言一、多重积分的基本概念与计算1.1 多重积分的定义与重要性1.1.1 多重积分的基本组成1.1.2 多重积分在机器学习中的应用 1.2 多重积分的历史与发展1.2.1 多重积分的历史1.2.2 多重积分的发展 二、微分方程的基本概念与解…

RCE-PLUS (学习记录)

源码 <?php error_reporting(0); highlight_file(__FILE__); function strCheck($cmd) {if(!preg_match("/\;|\&|\\$|\x09|\x26|more|less|head|sort|tail|sed|cut|awk|strings|od|php|ping|flag/i", $cmd)){return($cmd);}else{die("i hate this"…