前端Vue之发布订阅模式

news2025/1/24 22:33:56

目录

1.什么是发布订阅模式

2.实现简单的发布订阅

3.收集更新函数

4.触发更新函数

5.总结


一个响应式数据可能会有多个视图部分都需要依赖,也就是响应式数据变化之后,需要执行的更新函数可能不止一个,对于这种情况,有必要学习一下发布订阅模式。

1.什么是发布订阅模式

发布订阅模式定义了一种一对多的依赖关系,让多个订阅者对象同时监听某一个主题对象。这个主题对象在自身状态变化时,会通知所有订阅者对象,使它们能够自动更新自己的状态。(盗用一张图)

 现实生活中有很多类似的例子,比如我最近在网上看上一双鞋子,联系到卖家后,这双鞋已经卖光了,于是问卖家什么时候有货,卖家告诉我,要等一个星期后才有货,可以收藏店铺,等有货的时候再通知,所以我收藏了此店铺,但与此同时,其他人等也喜欢这双鞋,也收藏了该店铺;等来货的时候就依次会通知他们。这就是简单的发布订阅。

  • 指定发布者
  • 给发布者添加一个缓存列表,用于存放回调函数以便通知订阅者
  • 最后发布消息的时候,发布者遍历缓存列表,依次触发里面存放的订阅者回调函数

2.实现简单的发布订阅

先从dom绑定事件来说,一般一个事件绑定一个回调函数,但是也可以绑定多个回调函数。只不过方式不同,第二种就可以绑定多个。

  1. dom.οnclick=function(){}
  2. dom.addEventListener('click',()=>{})

实现简单的发布订阅

// 增加dep对象 用来收集依赖和触发依赖
const dep = {
    map: Object.create(null),
    // 收集
    collect(dataProp, updateFn) {
      if (!this.map[dataProp]) {
        this.map[dataProp] = []
      }
      this.map[dataProp].push(updateFn)
    },
    // 触发
    trigger(dataProp) {
      this.map[dataProp] && this.map[dataProp].forEach(updateFn => {
        updateFn()
      })
    }
}

3.收集更新函数

用于更新dom的更新函数集中起来

 // 编译函数
  function compile() {
    let app = document.getElementById('app')
    // 1.拿到app下所有的子元素
    const nodes = app.childNodes   //  [text, input, text]
    //2.遍历所有的子元素
    nodes.forEach(node => {
      // nodeType为1为元素节点
      if (node.nodeType === 1) {
        const attrs = node.attributes
        // 遍历所有的attrubites找到 v-model
        Array.from(attrs).forEach(attr => {
          const dirName = attr.nodeName
          const dataProp = attr.nodeValue
          console.log(dirName, dataProp)
          if (dirName === 'v-text') {
            console.log(`更新了${dirName}指令,需要更新的属性为${dataProp}`)
            node.innerText = data[dataProp]
            // 收集更新函数
            dep.collect(dataProp, () => {
              node.innerText = data[dataProp]
            })
          }
        })
      }
    })
 }

4.触发更新函数

当属性变化时,通过属性找到对应的更新函数列表

function defineReactive(data, key, value) {
    Object.defineProperty(data, key, {
      get() {
        return value
      },
      set(newValue) {
        // 更新视图
        if (newValue === value) return
        value = newValue
        // 再次编译要放到新值已经变化之后只更新当前的key
        dep.trigger(key)
      }
    })
}

5.总结

这是在vue框架之下的发布订阅,其原理中提到了几个专业名词

  1.  observe 对象指的是把数据处理成响应式的对象
  2.  watcher 指的其实就是数据变化之后的更新函数 (vue中的watcher有两种,一种是用来更新视图的watcher,一种是通过watch配置项声明的watcher)
  3.  dep 指的就是使用发布订阅实现的收集更新函数和触发更新函数的对象

发布订阅模式的本质是解决一对多的问题,在vue中实现数据变化之后的精准更新。

                                                 vue作者编程功力之深厚,运用之巧妙,令人叹服!!!!!!

                              

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/407869.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

node使用管理神器NVM安装配置超详细步骤(window10)

使用NVM对node进行版本管理前言一、什么是nvm?二、nvm下载安装配置1.下载2.nvm解压安装3.检查环境变量4.确认安装成功5.设置和安装node5.1 设置淘宝镜像5.2 安装node指定版本并使用5.2.1 执行以下命令自动安装指定版本的node和npm:5.2.2 查看已经安装的n…

Vue3.0项目——打造企业级音乐App(一)Tab栏、轮播图、歌单列表、滚动组件

系列文章目录 内容参考链接Vue3.0 项目启动Vue3.0 项目启动(打造企业级音乐App)Vue3.0项目——打造企业级音乐App(一)Tab栏、轮播图、歌单列表、滚动组件Vue3.0项目——打造企业级音乐App(二)图片懒加载、…

路由守卫的详解

路由守卫总共有7个 全局路由守卫: beforeEach 前置守卫 affterEach 后置守卫 beforeResolve 解析守卫 路由的守卫 beforeRouterEnter 进入组件之前触发,在Created前面 beforeRouterUpdated 路由更新但是内容不会改变 beforeRouterLeave 离开之前触发,在beforeDestory之前…

vue3 - ref和reactive的区别

文章搬运自wx60d4764eb475e 的vue3中ref和reactive的区别(系列六) 1. ref和reactive区别: 如果在template里使用的是ref类型的数据, 那么Vue会自动帮我们添加.value 如果在template里使用的是reactive类型的数据, 那么Vue不会自动帮我们添加.val…

ErrorCaptureStackTrace(err); Error [ERR_MODULE_NOT_FOUND]: Cannot find module

目录结构 main.js import { Name, say, Person } from ./testconsole.log(Name)test.js const Name life function say() {console.log(Mine) } let Person { name: good }export { Name, say, Person }问题分析 步骤有点啰嗦,犯错的原因其实就很简单&#xff…

Vue自定义指令原来这么简单

本篇学习目标 能够了解组件进阶知识能够掌握自定义指令创建和使用能够完成tabbar案例的开发 1. 组件进阶 1.0 组件进阶 - 动态组件 目标: 多个组件使用同一个挂载点,并动态切换,这就是动态组件 需求: 完成一个注册功能页面, 2个按钮切换, 一个填写注册…

微信小程序(四)--- 自定义组件详解(properties,数据监听器,纯数据字段,插槽,父子间通信,behaviors)

目录 一、创建组件 二、引用组件 1、局部引用 2、全局引用 三、组件和页面的区别 四、组件样式隔离 1、注意点 2、修改组件的样式隔离选项 五、数据、方法、属性 1、data数据 2、methods方法 3、properties属性 4、data和properties的区别 5、使用setData修改proper…

AndroidStudio网格布局(制作计算机界面)

目录 网格布局特点(类似于表格) 常用属性: 针对布局的属性 针对子控件的属性 实例演示 创建一个安卓应用插入一张背景图片(可以不加) 打开字符串资源文件 strings.xml改应用标题名字(可不改&#xf…

uniapp微信公众号h5微信授权登录

前言 在微信客户端中访问第三方网页,公众号可通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。 关于公众号网页授权前期准备: 1.微信公众号开发,首先要搞一个公众号,开发阶段可以申请一个公众…

element ui+vue实现导航栏菜单以及页面跳转

关于博主: 不知道算不算的上入门,就是刚刚学习vue框架,断断续续的学习,所以有些地方讲的不正确也欢迎大家批评斧正,希望与大家共同进步 问题描述 对于初学前端的我们来说搭建一个路由导航界面还是比较困难的&#xf…

Web基础知识

1,Web基本概念和常识 ①web应用:网站(广义上的PC,手机app) ②浏览器(Browser):也称用户代理,web客户端,主要有IE、Edge、Chrome、Firefox、腾讯浏览器&#x…

nvm 安装使用及配置淘宝下载镜像

NVM介绍 NVM全称node.js version management ,专门针对node版本进行管理的工具,通过它可以安装和切换不同版本的node.js。 MVM下载 githhub下载地址,选择nvm-setup.zip:安装版,推荐使用 https://github.com/coreyb…

Antv X6 动态连线

这是我实际开发项目中&#xff0c;利用 X6 开发的一个关系图。具备连线功能。这里我尽可能全的记录整个开发思路和部分编码&#xff0c;如果你也用了 X6 希望对你有帮助。 创建画布 代码有删减&#xff0c;以下展示的代码全都有删减 index.vue <template><div id&q…

React组件化的额外知识补充

文章目录React的额外补充Portals的使用Fragment的使用严格模式StrictModeReact的额外补充 Portals的使用 某些情况下&#xff0c;我们希望渲染的内容独立于父组件&#xff0c;甚至是独立于当前挂载到的DOM元素中(默认都是挂载到id为root的DOM 元素上的)。 Portal 提供了一种…

【vue】 vue-router安装和配置方法

vue-router 是 vue.js 官方的路由插件&#xff0c;里面组件和 URL 的映射关系由 vue-route 帮我们管理。 在 vue-router 的单页面应用中&#xff0c;页面的路径的改变就是组件的切换。 第一步&#xff1a; 1.正常初始化项目的时候&#xff0c;会有个 vue-router 供我们选择。…

在VSCode中配置代码自动 eslint 格式化(修改eslint规则、eslint忽略文件)

一、Eslint Eslint 是用来检测和规范代码格式的工具&#xff0c;应用在工程化项目中&#xff0c;可以保证项目代码格式的一致性和规范性&#xff0c;大大提升了代码的可读性。 二、配置过程 本博客是讲述对一个已经引用 eslint 依赖Nuxt项目&#xff08;vue项目应该相同&…

vue-cli脚手架的下载安装(靠谱)

找了半天才找到一个靠谱的安装教程&#xff0c;分享给你们。 1. 先下载node.js&#xff0c;下载地址&#xff1a;Download | Node.jsNode.js is a JavaScript runtime built on Chromes V8 JavaScript engine.https://nodejs.org/en/download/直接进入下载电脑对应的版本&…

vue-cli创建vue项目详细步骤

一、安装node环境&#xff08;建议使用LTS&#xff09; Download | Node.js 二、下载vue和vue-cli脚手架 命令&#xff1a;npm i -g vue ; npm i -g vue/cli 三、在想要创建的位置路径下打开cmd&#xff08;直接点击路径输入cmd即可打开当前位置的终端&#xff09; 四、创建v…

Vue使用Element-UI的table组件和后端接口进行数据交互(包含前后端代码)

前言 本次用element-ui的table组件&#xff0c;简单案例演示下前后端数据交互。 前提声明&#xff1a;如果不知道如何在vue中引入element-ui&#xff0c;可以先看下这篇文章:Vue引入并使用Element-UI组件库的两种方式 静态页面 首先先写一个静态页面吧&#xff0c;数据都是…

Vue3的vue-router路由详解

这篇文章是接着【三分钟快速搭建Vue3webpack项目】的内容做的开发&#xff0c;有基础的可以跳过 【三分钟快速搭建Vue3webpack项目】&#xff0c;直接看以下的内容。 Vue3的vue-router路由详解&#xff1a; 首先安装路由依赖模块&#xff1a; npm install vue-router4 所需…