解密Vue 3:透过原理看框架,揭开它的神秘面纱

news2024/11/24 14:09:27

在这里插入图片描述

文章目录

    • 1. 响应式系统
    • 2. 组件化
    • 3. 虚拟 DOM
    • 4. 编译器
    • 5. 插件系统
    • 附录:前后端实战项目(简历必备) 推荐:★★★★★

Vue 3 是一种用于构建用户界面的现代 JavaScript 框架。它基于响应式编程虚拟 DOM 技术,并通过组件化的方式来实现可重用的 UI 组件。

下面是 Vue 3 的主要原理:

1. 响应式系统

Vue 3 的核心是其响应式系统,它用于追踪数据变化并使其自动更新。Vue 3 使用 ES6 的 Proxy 对象来实现监听属性的变化,并触发相应的更新。当被监听的数据发生改变时,会自动重新渲染相关的组件。

当使用 Vue 3 的响应式系统时,可以使用 reactive 函数将一个普通对象转换为响应式对象。下面是一个简单的代码示例:

import { reactive } from 'vue';

// 创建一个普通对象
const data = {
  count: 0,
};

// 将对象转换为响应式对象
const reactiveData = reactive(data);

console.log(reactiveData.count); // 输出: 0

// 修改响应式对象的属性
reactiveData.count++;

console.log(reactiveData.count); // 输出: 1

在上面的示例中,我们首先使用 reactive 函数将 data 对象转换为响应式对象 reactiveData。然后,我们可以通过访问 reactiveData 的属性来获取或修改其值。

此外,Vue 3 的响应式系统还提供了 ref 函数,用于创建单个可变的响应式值。下面是一个使用 ref 的代码示例:

import { ref } from 'vue';

// 创建一个响应式的计数器变量
const count = ref(0);

console.log(count.value); // 输出: 0

// 修改计数器变量的值
count.value++;

console.log(count.value); // 输出: 1

在这个示例中,我们使用 ref 函数创建了一个名为 count 的响应式变量。要访问该变量的值,我们需要通过 count.value 来获取或修改它。

无论是使用 reactive 还是 ref,Vue 3 的响应式系统都会自动追踪数据的变化,并在需要时更新相关的组件。这样,当修改响应式对象或变量时,与之相关联的视图将自动更新以反映最新的值。

2. 组件化

Vue 3 提供了一种以组件为单位进行开发的方式。每个组件都可以包含自己的状态、模板和样式,并且可以复用和组合其他组件。组件之间通过 props 属性传递数据,并通过事件进行通信。

在 Vue 3 中,组件化是一种重要的开发模式。

下面是一个简单的 Vue 3 组件化的代码示例:

<template>
  <div>
    <h1>{{ message }}</h1>
    <button @click="increaseCount">点击增加计数</button>
  </div>
</template>

<script>
import { ref } from 'vue';

export default {
  name: 'HelloWorld',
  setup() {
    const message = ref('Hello, World!');
    const count = ref(0);

    const increaseCount = () => {
      count.value++;
    };

    return {
      message,
      count,
      increaseCount,
    };
  },
};
</script>

<style scoped>
h1 {
  color: blue;
}
button {
  background-color: gray;
  color: white;
  padding: 10px 20px;
}
</style>

在上面的代码示例中,我们创建了一个名为 HelloWorld 的 Vue 3 组件。在模板中,我们使用双花括号 {{ }} 语法来绑定变量 message 的值,并显示在 <h1> 标签中。还定义了一个按钮,当点击按钮时,会调用 increaseCount 方法来增加 count 变量的值。

在组件的 <script> 部分,我们使用 setup 函数来设置组件的逻辑。在 setup 函数内部,我们使用 ref 函数创建了响应式的 messagecount 变量。然后,我们定义了 increaseCount 方法,在方法内部通过修改 count.value 来增加计数。

最后,我们使用 return 语句将需要在模板中使用的变量和方法返回。这样,它们就可以在模板中通过相应的名称进行访问和使用。

此外,在 <style> 部分,我们使用 scoped 属性来使样式只对当前组件有效。

通过组件化,我们可以将界面拆分为独立的、可复用的组件,每个组件都有自己的状态和方法,并可以通过 props 和事件进行数据传递和通信。这样可以提高代码的可维护性和重用性。

3. 虚拟 DOM

Vue 3 使用虚拟 DOM 技术来高效地更新页面。在修改数据时,Vue 3 会先将变化应用到虚拟 DOM 中,然后比较与之前的虚拟 DOM 的差异,最后只对有变化的部分进行实际的 DOM 更新。这样可以减少操作真实 DOM 的次数,提高性能。

在 Vue 3 中,虚拟 DOM 仍然是核心的概念。虚拟 DOM 可以提高性能并使开发更加方便。下面是一个简单的 Vue 3 虚拟 DOM 的代码示例:

<template>
  <div>
    <h1>{{ message }}</h1>
    <button @click="updateMessage">更新消息</button>
  </div>
</template>

<script>
import { ref, h } from 'vue';

export default {
  name: 'HelloWorld',
  setup() {
    const message = ref('Hello, World!');

    const updateMessage = () => {
      message.value = 'Hello, Vue 3!';
    };

    return {
      message,
      updateMessage,
    };
  },
  render() {
    return h('div', [
      h('h1', this.message),
      h('button', { onClick: this.updateMessage }, '更新消息'),
    ]);
  },
};
</script>

<style scoped>
h1 {
  color: blue;
}
button {
  background-color: gray;
  color: white;
  padding: 10px 20px;
}
</style>

在上面的代码示例中,我们创建了一个名为 HelloWorld 的 Vue 3 组件。在模板中,我们使用双花括号 {{ }} 语法来绑定变量 message 的值,并显示在 <h1> 标签中。还定义了一个按钮,当点击按钮时,会调用 updateMessage 方法来更新 message 的值。

在组件的 <script> 部分,我们使用 ref 函数创建了响应式的 message 变量。然后,我们定义了 updateMessage 方法,在方法内部通过修改 message.value 来更新消息。

此外,我们使用 render 函数来手动创建虚拟 DOM。在 render 函数中,我们使用 h 函数来创建元素节点和事件处理程序。这里的 h 函数是 Vue 3 提供的用于创建虚拟节点的辅助函数。

最后,我们将虚拟 DOM 渲染到组件的根节点上,以实现组件的渲染和更新。

通过使用虚拟 DOM,Vue 3 可以更高效地更新只需要更新的部分,并将更改应用到实际的 DOM 上,从而提高性能并提供更好的用户体验。

4. 编译器

Vue 3 的编译器将模板转换为渲染函数。在编译过程中,模板中的指令、事件绑定等会被转换为相应的 JavaScript 代码。这种编译方式将模板的解析和代码生成分离,提高了运行时的性能。

Vue 3 的编译器是通过 @vue/compiler-sfc 包提供的,它可以将单文件组件(.vue 文件)编译为可在浏览器中运行的 JavaScript 代码。下面是一个简单的 Vue 3 编译器的代码示例:

const { compile } = require('@vue/compiler-sfc');

const template = `<template>
  <div>
    <h1>{{ message }}</h1>
    <button @click="updateMessage">更新消息</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello, World!'
    };
  },
  methods: {
    updateMessage() {
      this.message = 'Hello, Vue 3!';
    }
  }
};
</script>

<style scoped>
h1 {
  color: blue;
}
button {
  background-color: gray;
  color: white;
  padding: 10px 20px;
}
</style>`;

const { descriptor } = compile(template);

console.log(descriptor.script.content); // 输出编译后的 JavaScript 代码

在上面的代码示例中,我们首先引入了 @vue/compiler-sfc 包,并使用其中的 compile 函数进行编译。然后,我们定义了一个包含了模板代码的 template 字符串。

接下来,我们调用 compile 函数并传入 template 字符串。它会返回一个 descriptor 对象,其中包含了编译后的模板数据。

最后,我们可以通过访问 descriptor.script.content 属性来获取编译后的 JavaScript 代码,并将其输出到控制台。

通过使用 Vue 3 的编译器,我们可以将单文件组件编译为运行在浏览器中的 JavaScript 代码,从而实现了在浏览器端的模板编译和渲染。这样可以提高开发效率并使代码更具可维护性。

5. 插件系统

Vue 3 提供了插件系统,允许开发者扩展框架的功能。插件可以添加全局的方法、指令、过滤器等,并且可以访问框架的内部 API。

Vue 3 的插件系统是通过 app.use() 方法来实现的。

下面是一个简单的 Vue 3 插件的代码示例:

// 定义一个插件
const MyPlugin = {
  install(app) {
    // 添加全局方法或属性
    app.config.globalProperties.$myMethod = () => {
      console.log('This is my plugin method');
    };

    // 添加全局指令
    app.directive('myDirective', {
      mounted(el, binding) {
        el.textContent = binding.value;
      },
    });

    // 添加全局组件
    app.component('my-component', {
      template: `<div>This is my component</div>`,
    });
  },
};

// 创建一个 Vue 应用
const app = Vue.createApp({});

// 使用插件
app.use(MyPlugin);

// 挂载应用到 DOM 元素
app.mount('#app');

在上面的代码示例中,我们首先定义了一个名为 MyPlugin 的插件对象。该插件对象中的 install 方法会在调用 app.use() 时被执行。

install 方法中,我们可以通过 app 对象来添加全局方法、全局指令和全局组件。在这个例子中,我们在 appconfig.globalProperties 上挂载了一个新的方法 $myMethod,并在全局范围内可用。

我们还使用 app.directive 添加了一个全局指令 myDirective,在该指令的 mounted 钩子函数中,我们将绑定的值赋给元素的文本内容。

最后,我们使用 app.component 添加了一个全局组件 my-component,它的模板内容是一个简单的 <div> 元素。

创建完插件后,我们通过调用 app.use() 方法来使用插件。最后,我们使用 app.mount() 将应用挂载到指定的 DOM 元素上。

通过使用 Vue 3 的插件系统,我们可以将功能封装到插件中,并在需要的时候轻松地在 Vue 应用中使用。这样可以提高代码的可维护性和复用性。

总的来说,Vue 3 的原理包括响应式系统、组件化、虚拟 DOM、编译器和插件系统。它们共同协作,使得开发者可以快速构建高效、可维护的用户界面。

附录:前后端实战项目(简历必备) 推荐:★★★★★

Vue.js 和 Egg.js 开发企业级健康管理项目
带你从入门到实战全面掌握 uni-app

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

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

相关文章

postgresql(一):使用psql导入数据库

使用psql导入数据库 1、概述2、具体问题3、总结 1、概述 大家好&#xff0c;我是欧阳方超。 听说postgresql越来越流行了&#xff1f;psql是一个功能强大的命令行工具&#xff0c;用于管理和操作PostgreSQL数据库。它提供了一个交互式环境&#xff0c;允许用户执行SQL查询、创…

MISA代码配置运行

MISA源码github链接&#xff1a;click here IDE: Pycharm专业版2022.2.2 python3.8 一、创建虚拟环境&#xff1a; 尝试 源码中给了environment.yml,可以用以下命令创建&#xff0c;但可能是由于某些库的版本问题&#xff0c;尝试失败。 conda env create -f environment.…

协议分层与OSI参考模型【图解TCP/IP(笔记三)】

文章目录 协议分层与OSI参考模型协议的分层理解协议的分层OSI参考模型OSI参考模型中各个分层的作用 协议分层与OSI参考模型 协议的分层 OSI参考模型将通信协议中必要的功能分成了7层。通过这些分层&#xff0c;使得那些比较复杂的网络协议更加简单化。 在这一模型中&#xf…

Python_字典包含关系判定方法

Python中的字典是一种无序的数据结构&#xff0c;它由键和对应的值组成 在实际编程中我们经常需要判断一个字典是否包含另一个字典的所有键值对 本文将介绍一种种简单而有效的方法来判定字典之间的包含关系。 a {"a": 1, "b": 2, "c": 3, &q…

zabbix 应用(贼详细!)

目录 一&#xff1a;添加 zabbix 客户端主机 1、关闭防火墙&#xff0c;修改主机名 2、服务端和客户端都配置时间同步 ​3、服务端和客户端都设置 hosts 解析 4、设置 zabbix 的下载源&#xff0c;安装 zabbix-agent2 5、修改 agent2 配置文件 6、启动 zabbix-agent2 7、 在…

OpenCV读取一张8位无符号单通道图像并显示

#include <iostream> #include <opencv2/imgcodecs.hpp> #include <opencv2/opencv.hpp> #include

XXX汽车SAP ERP系统接口提速,助力生产物流业务数据快速处理(投稿数字化月报一)

XXX汽车ERP系统中数据量第一大接口-生产订单下达接口&#xff0c;一直是ESB总线重点关注的重要接口。从2019年项目初发给MOM生产、LES物流系统到现在&#xff0c;下游接收系统已经增加到15个之多。针对该接口下达数据缓慢的情况&#xff0c;SAP项目开发团队攻坚克难&#xff0c…

购买上帝的男孩——好文分享

购买上帝的男孩——好文分享 一个小男孩捏着1美元硬币&#xff0c;沿街一家一家商店地询问&#xff1a;“请问您这儿有上帝卖吗&#xff1f;”店主要么说没有&#xff0c;要么嫌他在捣乱&#xff0c;不由分说就把他撵出了店门。 天快黑时&#xff0c;第二十九家商店的店主热情…

QtMqtt —— 3、搭建Mqtt服务,修改QMqtt源码进行消息订阅测试(附源码)

效果 搭建EMQX即Mqtt服务 为了调试程序,我们需要一台MQTT服务器。EMQ公司官方提供了测试的MQTT服务器,但由于连接数众多,不太稳定,我们需要自己搭建一台MQTT服务器。 官网下载EMQX 启动:      1. 下载 emqx-5.1.1-windows-amd64.zip ,解压      2. 命令行下进入…

UE4 实现控制场景中所有物体透明度功能

本文会讲解如何利用材质参数集简单的实现修改场景中所有物体透明度的功能&#xff0c;讲解地图为第三人称地图 1.创建材质变量集&#xff0c;这里面新建的变量可以在蓝图中控制&#xff0c;这样就能很方便的修改透明度 因为透明度是只有一个值的参数所以创建scalar参数&#x…

Kafka入门,分区的分配再平衡(二十)

分区的分配以及再平衡 1、kafka有四种主流的分区策略&#xff1a;Range,RoundRobin,Sticky,CooperativeSticky。可以通过配置参数partition.assignment.strategy,修改分区的分配策略。默认策略是RanageCooperativeSticky。Kafka可以同事使用多个分区分配策略。 参数描述heartb…

【组合数学 or 枚举】逆序对

C-逆序对_Wannafly挑战赛6 (nowcoder.com) 题意&#xff1a; 思路&#xff1a; 组合数学&#xff0c;无非两种做法&#xff0c;一种是计数DP&#xff0c;另一种是组合数 DP显然不可能&#xff0c;那就组合数 考虑组合数的时候可以把这道题变成一个枚举题 我们去枚举位&…

Android shader编译原理

作者&#xff1a;tmaczhang 1. 什么是着色器编译卡顿&#xff1f; 着色器是在 GPU&#xff08;图形处理单元&#xff09;上运行的代码。当 Flutter 渲染的 Skia 图形后端首次看到新的绘制命令序列时&#xff0c;它有时会生成和编译一个自定义的 GPU 着色器用于该命令序列。使得…

JAVA对象转xml(支持递归生成复杂数据类型)

前言 调用一些soap协议的项目你或许使用的到&#xff0c;也许我是在造轮子&#xff0c;但是我没在网上找到合适的轮子&#xff0c;就根据现有的项目自己造了一个&#xff0c;废话不说&#xff0c;说思路 使用反射获取对象的属性&#xff0c;根据属性的类型做出相应的处理&…

计算机体系结构基础知识介绍之缓存性能的十大进阶优化之编译器控制的预取和利用HBM扩展内存层次(七)

优化九&#xff1a;编译器控制的预取以减少丢失惩罚或丢失率 硬件预取的替代方案是编译器在处理器需要数据之前插入预取指令来请求数据。 预取有两种类型&#xff1a; ■ 寄存器预取将值加载到寄存器中。 ■ 高速缓存预取仅将数据加载到高速缓存。 这两种类型都可以分为有错…

k8s对象操作的了解

一&#xff1a;什么是Kubernetes对象 Kubernetes对象指的是Kubernetes系统的持久化实体&#xff0c;所有这些对象合起来&#xff0c;代表了你集群的实际情况。常规的应用里&#xff0c;我们把应用程序的数据存储在数据库中&#xff0c;Kubernetes将其数据以Kubernetes对象的形…

unity+pico neo3入门教程

安装unity&#xff0c;教程如下&#xff1a;unity2021安装教程 安装pico的SDK:: https://developer-cn.pico-interactive.com/ 有入门教程&#xff1a;导入 SDK - PICO 开发者平台 注册后组织&#xff0c;创建应用learntest&#xff0c;如下 下载SDK。下载最新版&#xff…

旧固态硬盘复制到新固态硬盘多出一个分区怎么办?

朋友电脑只有512G而且只有一个硬盘口&#xff0c;然后就买了一款1T硬盘&#xff0c;去店里回来之后发现多出一个分区&#xff0c;无法直接在系统里合并 这时候我们就需要下载第三方软件&#xff0c;删除多余分区&#xff0c;扩展C盘 软件下载链接&#xff1a; DiskGenius.rar…

Stable Diffusion 用插件管理NNN个模型

当初步涉足 Stable Diffusion&#xff0c;可能会被各种新概念和模型搞得头大。好比我们作为新晋的魔法师&#xff0c;需要理解如何巧妙使用各种法师装备——也就是这些模型&#xff0c;以更好地应对问题&#xff0c;发挥出最大效果。 要了解一个被称为 safetensors 的概念。这…

TRACE请求造成XSS

漏洞描述 远端WWW服务支持TRACE请求。RFC 2616介绍了TRACE请求&#xff0c;该请求典型地用于测试HTTP协议实现。 漏洞危害 攻击者利用TRACE请求&#xff0c;结合其它浏览器端漏洞&#xff0c;有可能进行跨站脚本攻击&#xff0c;获取敏感信息&#xff0c;比如cookie中的认证信…