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

ops/2024/12/27 21:13:05/

前文指路:《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/ops/145482.html

相关文章

银河麒麟 SSH Vscode连接

SSH连接错误&#xff1a; [20:04:32.376] Failed to set up socket for dynamic port forward to remote port 38671: Socket closed. TCP port forwarding may be disabled, or the remote server may have crashed. See the VS Code Server log above for details. [20:04:3…

FastAPI 与 SQLModel 分页功能实现指南

FastAPI 与 SQLModel 分页功能实现指南 1. 基础分页模型 from typing import Generic, TypeVar, Optional, List from pydantic import BaseModel from sqlmodel import SQLModelT TypeVar("T")class PageParams(BaseModel):page: int 1size: int 10class PageR…

Ubuntu下ESP32-IDF开发环境搭建

Ubuntu下ESP32-IDF开发环境搭建 文章目录 Ubuntu下ESP32-IDF开发环境搭建一、前言二、软件安装三、开发环境搭建3.1 ESP-IDF安装&#xff1a;3.2 安装编译工具&#xff1a; 四、编译并烧录代码五、ESP32代码编辑工具 一、前言 ​ 开发ESP32&#xff0c;我们首先就要安装开发环…

WebRtc webrtc-streamer部署

文章目录 本文档只是为了留档方便以后工作运维&#xff0c;或者给同事分享文档内容比较简陋命令也不是特别全&#xff0c;不适合小白观看&#xff0c;如有不懂可以私信&#xff0c;上班期间都是在得 WebRtc webrtc-streamer 部署 docker run -p 8000:8000 -it mpromonet/webrt…

Linux的Java方向

RPM&#xff1a;Redhat软件包管理工具&#xff0c;类似windows里面的setup.exed,是Linux这系列操作系统里面的打包按照工具&#xff0c;它虽然是Redhat的标志&#xff0c;但理念是通用的 查询命令 rpm -qa&#xff1a;查询所安装的所有rpm软件包 rpm -ql 服务名&#xff1a;查…

【Docker命令】如何使用`docker exec`在容器内执行命令

大家好&#xff0c;今天我们来聊聊Docker容器管理中的一个非常有用的命令&#xff1a;docker exec。在日常工作中&#xff0c;我们经常需要在运行中的Docker容器内执行各种命令&#xff0c;docker exec正是帮助我们实现这一需求的利器。下面我将通过一个简单的例子&#xff0c;…

定位方式:css

使用相对路径 div ul #div下的所有ul&#xff0c;空格表示相对路径&#xff08;这个实际中用的多一些&#xff09; 绝对路径-一般不用绝对路径 html>head>div&#xff0c;“>”表示根路径 使用class名称定位 使用.表示 使用id定位 使用#表示 使用属性定位 [属性名…

Mac 查询IP配置,网络代理

常用命令 1.查询IP ifconfig | grep "inet" 2.ping查询 ping 172.18.54.19&#xff08;自己IP&#xff09; 3.取消代理&#xff0c;通过在终端执行以下命令&#xff0c;可以取消 Git 的代理设置 git config --global --unset http.proxy git config --global …