vue

简短介绍

Vue.js 是一个渐进式 JavaScript 框架,主要用于构建用户界面。它的设计哲学是“自底向上渐进式”,这意味着开发者可以根据项目需求,从简单的页面增强到复杂的单页面应用(SPA)。Vue.js 既轻量易用,又功能强大,吸收了 AngularReact 的优点。
学习是一项长期的任务,让我来一起成长吧!


基础

vue和react有什么不同

  1. 设计哲学
    Vue.js
  • 渐进式框架:Vue 是一个渐进式框架,意味着你可以从简单的项目开始,并逐步引入更多功能和工具,如 Vue Router(路由)和 Pinia/Vuex(状态管理),从而使框架适应项目的复杂性。
    双向数据绑定:Vue 提供了内置的双向数据绑定,使得开发表单或用户输入等场景更加简便。
    React.js

UI 库React 更像是一个 UI 库,只关注视图层。它的设计是“一个函数输入状态,返回一个 UI”,强调函数式编程思想。开发者需要使用其他库来完成路由、状态管理等任务。
单向数据流React 强调单向数据流(Unidirectional Data Flow),数据只能从父组件传递到子组件。状态管理通常通过 Redux 或其他库实现。

  1. 模板语法 vs JSX
    Vue.js
    模板语法:Vue 使用了模板和指令(例如 v-if、v-for)来定义 UI。它的模板语法类似于标准的 HTML,开发者可以使用简单的 HTML 结构来声明组件的视图逻辑。
    单文件组件(SFC):Vue 支持在 .vue 文件中写组件,文件包含 <template>、<script><style>,使得结构清晰且便于管理。

React.js
JSX:React 使用 JSX(JavaScript XML),它允许在 JavaScript 代码中直接编写类似 HTML 的结构。JSX 本质上是语法糖,开发者需要掌握 JavaScriptReact 的概念来有效使用 JSX。
全部 JavaScript:React 的开发风格更贴近纯 JavaScript,所有的逻辑和模板都混合在 JavaScript 中。这给开发者提供了极大的灵活性和控制力。

  1. 数据流和状态管理
    Vue.js
    双向数据绑定Vue 使用双向数据绑定机制,可以轻松处理表单元素的状态同步,尤其在小型项目中非常方便。
    Vuex/Pinia状态管理:对于大型项目,Vue 提供了 VuexPinia 作为集中式的状态管理工具,可以与 Vue 的响应式系统无缝集成。

React.js
单向数据流:React 强调单向数据流,组件之间的数据传递只能从父到子,状态的更新必须通过传递函数实现。
外部状态管理库(如 Redux、Recoil 等):React 没有内置的全局状态管理工具,通常依赖第三方库来管理复杂的状态(如 Redux、Recoil 或 Context API)。

  1. 虚拟 DOM
    Vue.js
    Vue 也使用了虚拟 DOM 来优化性能。但 Vue 的模板语法抽象了底层的虚拟 DOM 实现,开发者无需直接操作虚拟 DOM。

React.js
React 是虚拟 DOM 的发明者,JSX 最终被编译成虚拟 DOM 的结构。React 的开发者可以直接操作虚拟 DOM,虽然这不常见,但它的使用灵活性很高。

  1. 性能和优化
  • Vue.js

Vue 的响应式系统在精确追踪组件的依赖关系方面表现出色,只会重新渲染需要更新的组件,减少了不必要的性能消耗。
Vue 内置了更多优化措施,尤其在 Vue 3 中,借助 Proxy 实现了更精细的响应追踪,提升了性能。

React.js
React 的性能优化主要依赖虚拟 DOMshouldComponentUpdateReact.memo 等手动控制更新的机制。React 鼓励开发者在必要时进行性能优化,但需要更多手动干预。
React 在大型应用中的性能优化依赖开发者对组件的渲染流程有更多控制权。

  1. 学习曲线
    Vue.js
    Vue 的学习曲线较平滑,开发者可以使用简单的模板语法和指令开始构建应用。其清晰的文档和一致的 API 使得新手容易上手。
    Vue 的渐进式特性允许开发者在项目中逐步引入更多复杂的功能,而不必一开始就掌握整个框架。

React.js
React 的学习曲线较陡峭,开发者需要学习 JSX、组件生命周期、函数式编程以及状态管理工具(如 Redux)才能更高效地使用 React。
虽然一开始可能复杂,但 React 提供了更高的灵活性和控制力,适合构建高度定制化的应用。

  1. 生态系统
    Vue.js
    Vue 的生态系统相对集中,官方工具如 Vue Router、Pinia(或 Vuex)等都是 Vue 核心团队维护的,集成非常紧密。
    Vue 在亚洲,尤其是在中国有非常广泛的使用和支持,社区非常活跃。

React.js
React 的生态系统庞大且分散。React 本身只专注于视图层,开发者需要依赖第三方库(如 Redux、React Router 等)来构建完整的应用。
React 在全球范围内,尤其是西方市场有广泛的支持,社区活跃度和招聘需求很高。

  1. 使用场景
    Vue.js
    适合小到中型的项目,或者需要快速开发、交付的项目。Vue 的渐进式架构也适合大型项目,但在非常复杂的应用中可能不如 React 灵活。

React.js
适合大型复杂的项目,尤其是需要高度定制和灵活控制的场景。React 的灵活性让它成为构建复杂应用的热门选择。

总结
Vue.js:更适合初学者,学习成本较低,适合快速开发和中小型项目。其组件化和双向数据绑定让开发变得简单高效,尤其适合需要快速上手并交付的项目。

React.js:适合有经验的开发者,学习曲线较陡,但提供了更大的灵活性和控制权,适合大型、复杂的项目。React 的强大生态系统和组件复用能力使其在大型企业应用中广泛使用。

两者都是非常优秀的前端框架,选择 Vue 还是 React 主要取决于项目需求、团队经验和个人喜好。


什么是虚拟dom

虚拟 DOM (Virtual DOM) 是一种在现代前端框架(如 Vue、React)中广泛使用的概念,它是对实际 DOM 的一种抽象表示,目的是提高网页的渲染性能。

  1. DOM 与性能瓶颈
    在传统的网页开发中,DOM(文档对象模型)是 HTML 页面的结构化表示,它允许 JavaScript 操作 HTML 元素。然而,操作 DOM 是昂贵的,因为每次更新 DOM 都会触发浏览器的重排/回流(reflow)重绘(repaint),尤其是当页面复杂或更新频繁时,性能开销非常大。

  2. 虚拟 DOM 的工作原理
    虚拟 DOM 是对真实 DOM的一种轻量级的表示,它是一个JavaScript 对象,保留了 DOM 的结构和属性。前端框架使用虚拟 DOM 来追踪界面的状态变化,并通过以下步骤高效更新真实 DOM

  • 创建虚拟 DOM:当组件状态或数据发生变化时,框架会首先在内存中创建一个虚拟 DOM 树,而不是立即更新真实 DOM。

  • 比较差异(Diffing):框架通过一种高效的diff 算法比较新旧虚拟 DOM 树,找到哪些节点发生了变化。

  • 最小化更新(Patch):根据 diff 算法的结果,框架只更新那些需要变动的真实 DOM 部分,而不是整个页面重新渲染。

  1. 优势
  • 减少直接 DOM 操作:通过 diff 算法减少不必要的 DOM 更新避免频繁的 reflow 和 repaint
  • 提升性能:由于大多数变化都可以在内存中处理,只有当必要时才操作真实 DOM,整体性能显著提升
  • 更流畅的用户体验:减少不必要的 DOM 操作能带来更流畅的用户交互体

删除数组用delete和Vue.delete有什么区别?

响应式支持:
delete:不会触发 Vue 响应式系统,因此不会自动更新视图
Vue.delete:会触发 Vue 响应式系统,视图自动更新

数组处理:
delete:删除后数组长度不变,留下 "empty slot"
Vue.delete:删除后数组长度变化,移除元素并调整数组

let arr = [1, 2, 3];
delete arr[1]; // 删除数组中的第二个元素
console.log(arr); // 输出: [1, empty, 3]

// Vue.delete
let vm = new Vue({
  data: {
    arr: [1, 2, 3]
  }
});
Vue.delete(vm.arr, 1); // 删除数组中的第二个元素
console.log(vm.arr); // 输出: [1, 3]

watch和computed的区别?

  1. computed(计算属性)
    computed 是基于依赖的 缓存 计算属性,通常用于依赖其他数据的值计算。它们在依赖的数据发生变化时才会重新计算,并且结果会被缓存,直到依赖的数据再次发生变化。
  1. watch(侦听器)
    watch 用于 观察 一个响应式数据的变化,并在数据变化时执行特定的回调函数。它可以执行异步操作和复杂的逻辑,特别适合需要在数据变化时进行 副作用操作 的场景,比如请求 API、手动执行某些逻辑等。

v-for没有key回发生什么?

  • 没有 key 可能会导致 数据渲染错误组件状态混乱,尤其是在列表数据发生变动时。
  • 缺少 key 还会导致 Vue 的 diff 算法性能下降,因为 Vue 无法有效地追踪和复用 DOM 元素
  • 应该始终为 v-for 列表中的每个项提供一个唯一的 key 属性,确保 Vue 能够正确地管理 DOM 更新。

vue的双向绑定原理

Vue 的双向绑定是通过以下几部分组成的:

  1. 数据劫持(Data Observer):
    Vue 利用 Object.defineProperty() (Vue 2)Proxy (Vue 3) 劫持对象的属性,监听对属性的读写操作。通过这种方式,Vue 能够在数据被访问或修改时触发相关的逻辑。
    // Vue 2.x 响应式数据劫持
    Object.defineProperty(obj, 'message', {
    get() {
     // 依赖收集
     return value;
    },
    set(newValue) {
     // 通知更新
     value = newValue;
    }
    });
    
    

// Vue 3.x 响应式数据劫持
const observed = new Proxy(obj, {
get(target, key) {
// 依赖收集
return Reflect.get(target, key);
},
set(target, key, value) {
// 通知更新
return Reflect.set(target, key, value);
}
});



2. **发布-订阅模式:**
Vue 内部实现了一个 `发布-订阅模式`,每个数据都有一个对应的 `依赖收集器(Dep`)。当数据发生变化时,Dep 会通知所有依赖于它的`订阅者(通常是渲染函数或组件)`,触发视图更新。

3. **模板编译:**
Vue 会在编译模板时生成渲染函数,这个渲染函数会被绑定到相应的数据上。当数据变化时,渲染函数重新执行,从而更新视图。

4. **Watcher 监听器:**
`Watcher` 是 Vue 中负责侦听数据变化的部分。每一个组件实例都会创建与之相关的 Watcher 实例,它会观察某个数据或表达式,一旦数据发生变化,`Watcher` 会收到通知并触发视图更新或用户定义的回调函数。

---

## Vue3.0里为什么要用Proxy代替defineProperty?
1. **监听数组和对象新增、删除属性的能力**
在 `Vue 2.x` 中,`Object.defineProperty()` 只能劫持已经存在的属性,无法监听对象新增或删除的属性。为了解决这个问题,Vue 2.x 需要使用 `Vue.set `和 `Vue.delete` 来手动添加或删除响应式属性。这在开发中既繁琐又容易出错。

而 `Proxy` 可以直接拦截`对象的任意操作`,`包括新增和删除属性`。因此在 Vue 3 中,代理对象不再需要特殊的 `Vue.set` 或 `Vue.delete` 方法来处理新增或删除属性。

```javascript
// Vue 3 中使用 Proxy 可以监听属性新增、删除
const obj = new Proxy({}, {
  get(target, key) {
    // 处理属性访问
    return target[key];
  },
  set(target, key, value) {
    // 处理属性设置
    target[key] = value;
    return true;
  },
  deleteProperty(target, key) {
    // 处理属性删除
    delete target[key];
    return true;
  }
});
  1. 性能优势
    由于 Proxy 不需要递归遍历对象的每一个属性,并且可以通过一次代理完成对整个对象的劫持,因此在处理大型对象时性能有明显提升。此外,Proxy 提供了更高效的方式来处理对象的新增、删除、数组操作等,使得响应式系统的性能更加稳定和高效。
  1. 代理更多的操作
    Object.defineProperty() 只能拦截属性的 getset 操作,而 Proxy 可以拦截更多种类的操作,如:
    has:检测属性是否存在,如 in 操作符。
    deleteProperty:拦截属性删除操作。
    ownKeys:拦截对象的属性枚举操作,如 Object.keys()
    defineProperty:拦截 Object.defineProperty() 调用。
    getOwnPropertyDescriptor:拦截 Object.getOwnPropertyDescriptor()
    通过 Proxy,Vue 3 可以更灵活、全面地监控和控制对象的操作,从而构建出更强大和高效的响应式系统。

Vue3.0编译做了哪些优化

  1. 编译器重写
    Vue 3.0的编译器经过了完全重写,采用了模块化的设计,允许编译器的不同部分能够单独使用或扩展。新的编译器生成的代码更加高效,占用更少的空间,从而提高了渲染性能。重写后的编译器具备了更好的可扩展性和维护性支持更复杂的模板语法和更强大的优化能力。

  2. 静态提升
    Vue 3.0 编译器会对模板中的静态内容进行“静态提升”,即将那些不会改变的静态节点提升到渲染函数的外部。这意味着这些静态节点只会被创建一次,而不会在每次渲染时重新创建,从而减少了虚拟 DOM 的创建和渲染开销

    // Vue 2.x 渲染函数
    return {
    tag: 'div',
    children: [
     { tag: 'span', children: 'Hello World' } // 每次渲染都会重新创建
    ]
    }
    

// Vue 3.0 渲染函数
const staticNode = { tag: ‘span’, children: ‘Hello World’ }; // 静态提升
return {
tag: ‘div’,
children: [staticNode] // 每次渲染只复用 staticNode
}

```

  1. 静态节点标记
    Vue 3.0中,编译器会为模板中的静态节点打上标记,告诉虚拟 DOM渲染引擎哪些节点是静态的,哪些是动态的。通过这种标记,Vue 可以在更新时跳过静态节点,从而减少不必要的更新操作。对于大多数不变的 DOM 结构,这大大提升了渲染效率。
  • Patch Flags:精准的 DOM 更新,提高运行时效率。
  • 响应式系统优化:基于 Proxy,性能更优,精确性更高。
  • 多根节点(Fragment)支持:减少 DOM 层级复杂度。
  • Slot 渲染优化:静态 Slot 缓存,动态 Slot 精准处理。
  • 事件处理优化: 缓存静态事件,减少重复绑定。
  • 更好的 TypeScript 支持:开发体验和代码质量提升。
  • 编译缓存:避免重复编译带来的性能开销。

Vue3新特性–Composition API与React Hooks的异同点

Vue 3 的 Composition API 和 React 的 Hooks 都是为了提高组件逻辑复用性、代码组织性以及灵活性而引入的特性,它们的核心思想类似,但在实现方式、使用场景和具体设计上也有一些不同。

共同点

  1. 逻辑复用与抽离
    Vue 3 的 Composition APIReact Hooks 都能将组件中的逻辑抽离出来,方便复用。通过这两者,开发者可以更好地组织和复用复杂的状态逻辑,而不是像传统方式一样将代码堆积在生命周期函数中
    两者都可以用于抽象组件的逻辑,将状态管理、事件处理、数据获取等功能拆分成更小的模块。

  2. 基于函数的 API:
    Composition APIHooks 都是基于函数的 API,通过调用函数来获取响应式状态、方法或者生命周期逻辑。
    两者的 API 都提倡用函数的方式来处理状态和副作用,而不是像传统 Vuedata、methods、computed 等选项式 API 或者React 类组件的 state 和 setState

  3. 轻松组合逻辑:
    Composition API 和 Hooks 都支持将不同功能的逻辑组合在一起,方便处理复杂的组件逻辑。你可以将多个功能模块化后,再在一个组件中组合它们,组件的可读性和可维护性也随之提升。

不同点:

  1. Vue 3 的 Composition API 拥有 Vue 内置的响应式系统,状态变更会自动触发更新;而 React Hooks 则依赖组件重新渲染来更新状态。
  2. Vue 的 Composition API 提供了更多内置功能,如 watch、computed、响应式系统等;React Hooks 则更加轻量,需要开发者用其他库或工具来实现类似的功能。

最后,如果项目和教程对你有所帮助或者你看见了还算比较喜欢,欢迎给我star,谢谢您!

持续更新中…,如果遇到问题欢迎联系我,在文章最后评论区【留言和讨论】,当然,欢迎点击文章最后的打赏按键,请博主一杯冰阔乐,笑~


  转载请注明: 秦东旭的博客 vue

 上一篇
博客开源 博客开源
倒腾了一两周总算把个人博客网站完善了,目前这个版本使用应该是够了,当然还有一些优化项和功能增加后续在慢慢更新,为了回馈开源,今天准备把我自己修改完善的`blog`网站源代码开源。这不是生成后的网页文件,是您可以直接使用的源码,您只需要把博客相关信息换成您自己的就可以部署了。
下一篇 
JavaScript JavaScript
记录自己学习JavaScript的过程,记录学习过程中的重点和难点,方便以后查阅
  目录