Vue探索之Vue2.x源码分析(一)

一.响应式数据之数组的处理

<template><div><ul><li v-for="(item, index) in items" :key="index">{{ item }}<button @click="removeItem(index)">Remove</button></li></ul><input v-model="newItem" @keyup.enter="addItem"><button @click="addItem">Add</button></div>
</template><script>
export default {data() {return {items: ['Apple', 'Banana', 'Cherry'],newItem: ''}},methods: {addItem() {if (this.newItem.trim()) {this.items.push(this.newItem.trim());this.newItem = '';}},removeItem(index) {this.items.splice(index, 1);}}
}
</script>

二.nextTick异步更新队列

nextTick是Vue框架中的一个重要概念,它利用了JavaScript的事件循环机制和异步回调任务队列来实现其功能,本质是对JavaScript执行原理EventLoop的一种应用。在Vue中,数据变化不会立即导致DOM更新,而是等到当前事件循环结束,统一进行视图更新。这就意味着,如果你在数据变化后立即访问DOM,你看到的仍然是更新前的DOM。

nextTick的实现原理是利用JavaScript的微任务机制,将回调函数添加到微任务队列中,确保在当前任务执行完成后立即执行微任务。当前任务完成后,JavaScript引擎会执行微任务队列中的任务,其中就包括nextTick添加的回调函数。这使得回调函数可以在DOM更新之后执行。

在Vue.js中,数据变化后会经历一个过程:

  1. 修改数据

  2. 视图更新(DOM更新)

  3. nextTick的回调函数被执行

// 这是一个使用nextTick的例子
// 假设有一个Vue实例
new Vue({el: '#app',data: {message: 'Hello Vue!'}
});// 修改数据
this.message = 'Hello World!';// DOM还没有更新
this.$nextTick(() => {// DOM现在更新了// 我们可以执行依赖DOM的操作console.log(document.getElementById('app').textContent);
});

三.手写Vue核心代码

class Vue {constructor(options) {this.$el = document.querySelector(options.el);this.$data = options.data;// 初始化响应式系统this.observeData(this.$data);// 编译模板this.$el.innerHTML = this.compileTemplate(this.$el.outerHTML);// 挂载实例this.mount();}observeData(data) {if (typeof data !== 'object' || data === null) {return;}for (let key in data) {let dep = new Dep();let value = data[key];Object.defineProperty(data, key, {enumerable: true,configurable: true,get() {dep.addSub(Dep.target);return value;},set(newValue) {if (value === newValue) return;value = newValue;dep.notify();}});}}compileTemplate(template) {// 简单文本替换,例如 {{ message }} 替换为实例的响应式数据return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {return this.$data[key];});}mount() {// 挂载逻辑,例如将编译后的模板挂载到对应的DOM元素this.$el.innerHTML = this.compileTemplate(this.$el.outerHTML);}
}class Dep {constructor() {this.subs = [];}addSub(sub) {if (sub) {this.subs.push(sub);}}notify() {this.subs.forEach(sub => {sub.update();});}
}Dep.target = null; // 全局Dep.target,用于跟踪当前响应式依赖// 使用Vue
const app = new Vue({el: '#app',data: {message: 'Hello Vue!'}
});

四.Vue-Router核心源码解析

// Vue Router安装

npm install vue-router

// 以下是Vue Router的核心文件:

1.create-matcher.js:用于创建路由匹配器的工厂函数

2.create-route-map.js:用于创建路由映射的工厂函数

3.history.js:处理不同模式的History的API

4.index.js:Vue Router的入口文件,用于初始化Vue Router

5.install.js:用于Vue Router插件安装的工厂函数

6.location.js:处理URL解析和编码

7.route.js:定义路由记录的构造函数

8.router.js:定义Router类的构造函数

9.create-web-hash-history.js:创建使用hash模式的Web History

10.create-web-history.js:创建使用history模式的Web History

// 以下是一个简单的vue router使用示例
import Vue from  'Vue'
import VueRouter from 'vue-router'
import Home from './components/Home.vue'
import About from './components/About.vue'Vue.use(VueRouter);const routes = [{path: '/', component: Home},{path: '/about', component: About}
]const router = new VueRouter({mode: 'History',routes
})new Vue({router,template: '<div><h1>Vue Router Demo</h1><router-link to="/">Home</router-link><router-link to="/about">About</router-link><router-view></router-view></div>'
}).$mount('#app')

五.Vuex核心源码解析

Vuex是Vue.js应用的状态管理模式,Vuex的核心包括state、mutations、actions和getters

// 以下是 vuex核心概念的简化版核心源码解析// 模拟 Vuex 的 state
const state = {count: 0
}// 模拟 Vuex 的mutations
const mutations = {INCREMENT (state) {state.count++;}
}// 模拟 Vuex 的actions
const actions = {increment ({commit}) {commit('INCREMENT');}
}// 模拟Vuex的getters
const getters = {count: state => state.counet
}// 模拟 Vuex的store创建过程
const store = new Vuex.Store({state,mutations,actions, getters
})// 使用 store
store.dispatch('increment')
console.log(store.getters.count)

六.Axios核心源码解析

Axios是一个非常流行的javascript库,用于浏览器和node.js中发送HTTP请求。以下是一个简化的Axios核心功能的代码示例,展示了如何创建一个用于发送Http请求的简易版本:

// 引入axios依赖的库
const util = require('util');
const http = require('http');
const https = require('https');// 创建一个用于处理HTTP请求的函数
function axios(options) {// 返回一个Promise,允许异步处理return new Promise((resolve, reject) => {// 确定使用http还是httpsconst lib = options.protocol === 'http:' ? http : https;// 解析URL以提取主机名和端口const { hostname, port, path: pathname } = new URL(options.url);// 设置默认的端口const defaultPort = options.protocol === 'http:' ? 80 : 443;const portOrDefault = port || defaultPort;// 创建HTTP请求const req = lib.request({hostname,port: portOrDefault,path: pathname,method: options.method,headers: options.headers,}, (res) => {let data = '';// 接收数据片段res.on('data', (chunk) => {data += chunk;});// 请求完成res.on('end', () => {// 解析响应头const response = {status: res.statusCode,statusText: res.statusMessage,headers: res.headers,data: data,};// 解析数据(可以添加对JSON/其他格式的处理)try {response.data = JSON.parse(data);} catch (e) {response.data = data;}// 调用resolve或rejectif (res.statusCode >= 200 && res.statusCode < 300) {resolve(response);} else {reject(response);}});});// 错误处理req.on('error', (e) => {reject({status: null,statusText: e.message,headers: null,data: null});});// 可以添加超时处理等// 发送数据(如果有的话)if (options.data) {req.write(options.data);}// 结束请求req.end();});
}// 使用示例
axios({method: 'GET',url: 'http://example.com'
}).then(response => {console.log(response.data);
}).catch(error => {console.error(error.statusText);
});

七.Vue初始化流程

Vue 初始化主要涉及以下几个步骤:

1.创建Vue实例

  

new Vue({el: '#app',data: {message: 'Hello Vue!'}
})

2.模板编译:Vue 将el选项中的DOM元素编译成渲染函数

3.数据观测: Vue使用Object.defineProperty来实现数据的响应式,并且在内部保存依赖。

4.编译模板: 将渲染函数与数据进行结合生成最终的DOM

5.挂载:将编译好的模板挂载到el选项指定的DOM上

6.更新DOM:当数据发生变化时,Vue的响应式系统会重新渲染虚拟DOM并对比差异,然后应用到真实DOM上。

八.Vue异步更新策略

在Vue中,响应式系统会尝试尽可能高效地更新Dom。为此,Vue提更了几种异步更新策略,以应对不同的场景。

1.nextTick:用于访问更新后的DOM。

Vue.nextTick(callback);

2.vm.$nextTick:实例方法,用于访问data更新后的DOM。

this.$nextTick(callback);

3.v-for 中的 key:有助于Vue识别数组中哪些项被添加、删除或重新排序。

<div v-for="item in items" :key="item.id">{{ item.text }}
</div>

4.v-ifv-show:根据条件渲染元素,v-if是真正的条件渲染,因为它会确保条件块在值为false时不会出现在DOM中;v-show则是简单地通过CSS切换。

<div v-if="condition">...</div>
<div v-show="condition">...</div>

5.watch:监听数据变化,并执行异步操作。

watch: {someData: function (val, oldVal) {this.asyncMethod();}
}

6.watch 的 immediate 和 deep 选项:immediate 会在watcher被创建时立即触发,deep 会监控一个对象内部属性的变化。

watch: {someObject: {handler: 'handlerMethod',immediate: true,deep: true}
}

7.computed:计算缓存其结果,并且只有当依赖发生变化时才会重新计算。

computed: {computedProperty: function () {return this.someOtherProperty + 1;}
}

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

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

相关文章

Python卷积网络车牌识别系统(V2.0)

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

基于单片机的无线红外报警系统

**单片机设计介绍&#xff0c;基于单片机的无线红外报警系统 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的无线红外报警系统是一种结合了单片机控制技术和无线红外传感技术的安防系统。该系统通过无线红外传感器实…

SpringBoot -- 外部化配置

我们如果要对普通程序的jar包更改配置&#xff0c;那么我们需要对jar包解压&#xff0c;并在其中的配置文件中更改配置参数&#xff0c;然后再打包并重新运行。可以看到过程比较繁琐&#xff0c;SpringBoot也注意到了这个问题&#xff0c;其可以通过外部配置文件更新配置。 我…

鸿蒙系统前端:构建智能互联新时代的界面之美

随着华为鸿蒙系统的推出&#xff0c;前端技术也迎来了新的挑战与机遇。鸿蒙系统&#xff0c;作为华为自主研发的分布式操作系统&#xff0c;旨在打通各类智能设备&#xff0c;为用户提供一个无缝的智能互联体验。在这个宏大的愿景下&#xff0c;鸿蒙系统的前端设计显得尤为重要…

Java作业练习_第六周作业多态性(小白学习记录,仅供参考,有错指出)

题目排序&#xff08;点击直达&#xff09; 第一题第二题第三题第四题第五题第六题第七题第八题免责声明 第一题 写出下列程序的运行结果&#xff1a; package com.cxl.ch5.demo5; public class Base {int m0;public int getM(){return m;} } package com.cxl.ch5.demo5;publ…

第18章 JDK8-17新特性

1. Java版本迭代概述 1.1 发布特点&#xff08;小步快跑&#xff0c;快速迭代&#xff09; 发行版本发行时间备注Java 1.01996.01.23Sun公司发布了Java的第一个开发工具包Java 5.02004.09.30①版本号从1.4直接更新至5.0&#xff1b;②平台更名为JavaSE、JavaEE、JavaMEJava 8…

复杂度的讲解

1.算法效率 如何衡量一个算法的好坏&#xff1f;从两个维度&#xff0c;时间和空间&#xff08;算法运行的快慢&#xff0c;消耗的空间大不大&#xff09;。因为计算机硬件领域的高速发展&#xff0c;如今计算机的存储量已经达到了一个很高的程度&#xff0c;所以现在我们一般…

代码随想录算法训练营DAY15|C++二叉树Part.2|102.二叉树的层序遍历、226.翻转二叉树、101. 对称二叉树

文章目录 102.二叉树的层序遍历思路伪代码迭代法递归法 CPP代码拓展题 226.翻转二叉树思路CPP代码 101. 对称二叉树伪代码CPP代码 102.二叉树的层序遍历 力扣题目链接 文章讲解&#xff1a;102.二叉树的层序遍历 视频讲解&#xff1a;讲透二叉树的层序遍历 | 广度优先搜索 | Le…

微信公众号如何开通留言功能?

首先&#xff0c;我们需要了解为什么现在注册的公众号没有留言功能。这是因为所有在2018年之后注册的微信公众号都无法再自带留言功能。这一变化是根据微信的通知而实施的。自2018年2月12日起&#xff0c;微信对新注册的公众号进行了调整&#xff0c;取消了留言功能。这一决策主…

MySQL - 基础二

6、表的增删改查 CRUD : Create(创建), Retrieve(读取)&#xff0c;Update(更新)&#xff0c;Delete&#xff08;删除&#xff09; 6.1、Create 语法&#xff1a; INSERT [INTO] table_name[(column [, column] ...)]VALUES (value_list) [, (value_list)] ...value_list: v…

static关键字总结

static关键字的使用1. static: 静态的2. static 用来修饰的结构&#xff1a;属性、方法; 代码块、内部类&#xff1b;3. static修饰属性3.1 复习&#xff1a;变量的分类方式1&#xff1a;按照数据类型&#xff1a;基本数据类型、引用数据类型方式2&#xff1a;按照类中声明的位…

第十四届省赛大学B组(C/C++)子串简写

原题链接&#xff1a;子串简写 程序猿圈子里正在流行一种很新的简写方法&#xff1a; 对于一个字符串&#xff0c;只保留首尾字符&#xff0c;将首尾字符之间的所有字符用这部分的长度代替。 例如 internationalization 简写成 i18n&#xff0c;Kubernetes 简写成 K8s&#…

Java基础知识总结(37)

JUC容器 JUC基于非阻塞算法&#xff08;Lock Free 无锁编程&#xff09;提供了一组高并发的List、Set、Queue、Map容器。 JUC高并发容器是基于非阻塞算法实现的容器类&#xff0c;无锁编程算法主要通过CAS&#xff08;Compare And Swap&#xff09;volatile的组合实现&#x…

【SaaS,PaaS? XaaS -微参考】

介绍 以下是关于各种云服务模式的简要介绍&#xff0c;包括全称、定义、典型场景和应用&#xff1a; 缩写全称定义关键词典型场景和应用SaaSSoftware as a Service将软件以服务的形式交付给用户&#xff0c;用户通过互联网访问软件。提供软件电子邮件、在线办公套件&#xff…

JavaAPI操作HBase-Day2

Java代码操作HBase pom依赖,依赖版本要和软件一致 <dependencies><dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-client</artifactId><version>2.5.5</version></dependency><dependency>…

android 14 apexd分析(1)apexd bootstrap

Apex的由来&#xff0c;我们都知道普通的apk我们可以通过应用商店playstore等进行更新&#xff0c;apex的引入是google希望也能通过playstore更新bin文件.so etc配置文件等类型文件. 这些文件的安装实际通过apexd来进行&#xff0c;现在我们来解析一下apexd&#xff0c; apexd的…

JAVAEE——文件IO之文件操作

文章目录 文件的创建和销毁File概述构造方法常用的方法getAbsolutePath()exists()isDirectory()isFile()createNewFile()delete()deleteOnExit()list()listFiles()mkdir() 文件的创建和销毁 上面我们介绍了文件的读写操作那么文件的创建等的操作如何进行呢&#xff1f;这个操作…

.NET 设计模式—简单工厂(Simple Factory Pattern)

简介 简单工厂模式&#xff08;Simple Factory Pattern&#xff09;属于类的创建型模式&#xff0c;又叫静态工厂方法模式&#xff08;Static FactoryMethod Pattern&#xff09;,是通过一个工厂类来创建对象&#xff0c;根据不同的参数或条件返回相应的对象实例。这种模式隐藏…

前视声呐目标识别定位(四)-代码解析之启动识别模块

前视声呐目标识别定位&#xff08;一&#xff09;-基础知识 前视声呐目标识别定位&#xff08;二&#xff09;-目标识别定位模块 前视声呐目标识别定位&#xff08;三&#xff09;-部署至机器人 前视声呐目标识别定位&#xff08;四&#xff09;-代码解析之启动识别模块 …

C语言之分支语句和循环语句

前言 一、什么是语句&#xff1f; 二、分支语句&#xff08;选择结构&#xff09; 2.1 if语句 2.2 switch语句 三、循环语句 3.1 while循环 3.2 break与continue语句 3.3 getchar()与putchar() 3.3.1 缓冲区 3.4 for循环 3.4.1 一些for循环的变种 3.5 do...while循…