1.介绍
Vue 是一套用来动态构建用户界面的渐进式JavaScript框架
- 构建用户界面:把数据通过某种办法变成用户界面
- 渐进式:Vue可以自底向上逐层的应用,简单应用只需要一个轻量小巧的核心库,复杂应用可以引入各式各样的Vue插件
- 遵循MVVM模式
- 编码简洁,体积小,运行效率高,适合移动/PC端开发
- 它本身只关注 UI,可以引入其它第三方库开发项目
- 采用组件化模式,提高代码复用率、且让代码更好维护
- 声明式编码,让编码人员无需直接操作DOM,提高开发效率
- 使用虚拟DOM 和 Diff算法,尽量复用DOM节点
MVVM:Model(模型)、View(视图)和ViewModel(视图模型)。MVVM的主要目标是将应用程序的UI与其底层数据模型分离,通过数据绑定实现数据和UI的自动同步,从而降低代码的耦合度,提高应用程序的可维护性和可测试性。
Model:Model表示应用程序的数据模型或业务逻辑,负责处理数据的存取、处理和操作。它通常包含数据结构、数据库操作、网络请求等。Model并不直接与UI层交互,它只暴露一些接口供ViewModel层调用,使得ViewModel可以获取所需的数据。
View:View是用户界面的可视化部分,负责展示数据并与用户进行交互。View通常由XML、HTML、XAML等描述,这取决于具体的开发平台。
ViewModel:ViewModel是Model和View之间的桥梁,负责将数据从Model中取出并转换成View可用的形式。ViewModel不直接操作View,而是通过数据绑定机制将数据与View进行绑定,使得数据的变化可以自动反映在View上,实现了数据的双向绑定。ViewModel通常也包含用户交互的逻辑,例如处理用户输入、按钮点击等。
1.如何理解Vue的MVVM?
MVVM模型
- M:模型 Model,data中的数据
- V:视图 View,模板代码
- VM:视图模型 ViewModel,Vue实例
2.虚拟DOM:
虚拟DOM(Virtual DOM)是现代前端框架(如 React、Vue 等)中用于优化页面渲染性能的技术。它是一种通过 JavaScript 对象描述页面结构的方式,而不是直接操作浏览器的 DOM。通过这种方式,可以在内存中进行更高效的 DOM 操作,减少不必要的页面重新渲染,从而提高应用的性能和响应速度。
虚拟 DOM 是一个 JavaScript 对象,它模拟了真实 DOM 结构。真实 DOM 是浏览器中直接操作的文档对象模型,而虚拟 DOM 则是存在于内存中的一个轻量级对象。虚拟 DOM 的设计理念是:
- 描述而非直接操作:虚拟 DOM 描述了页面的 UI 结构,它与实际的浏览器 DOM 对应,但是它并不直接操作页面。它只是用来优化 UI 更新。
- 效率提升:当组件状态发生变化时,Vue 并不会直接对浏览器的 DOM 进行修改,而是先在虚拟 DOM 中进行更新,然后通过一种高效的算法(Diff 算法)来计算虚拟 DOM 与旧虚拟 DOM 的差异,并将需要更新的部分批量应用到真实 DOM 上。
虚拟 DOM 本质上是一个 JavaScript 对象,通常每个 Vue 组件的渲染结果都会生成一个虚拟 DOM 树。这个树的每个节点都是一个虚拟 DOM 节点,它包含了组件的结构和它的所有属性。Vue 的虚拟 DOM 节点通常由 VNode(虚拟节点)表示。一个 VNode 对象包含的信息通常包括:
- 类型:节点的类型,例如元素类型(div、span、h1等)或组件类型。
- 数据:该节点的属性、事件、样式等。
- 子节点:节点的子节点,通常是嵌套的虚拟 DOM 节点或文本节点。
- 文本内容:如果是文本节点,它会包含文本内容。
- 标识:虚拟节点的唯一标识
好处:
- 减少不必要的重绘和回流:
传统的 DOM 操作可能会导致浏览器多次重新绘制和回流,尤其是对于频繁更新的组件,性能开销非常大。而 Vue 的虚拟 DOM 会尽量减少这些操作,仅更新发生变化的部分。 - 批量 DOM 更新:
Vue 在进行渲染更新时,不会每次变化都去直接修改 DOM,而是等到需要的更新都准备好之后再一起应用,从而减少了 DOM 操作的次数。 - 高效的 Diff 算法:
Vue 使用高效的算法来比较新旧虚拟 DOM 的差异,并且采用了深度比较、节点类型比较等优化措施,使得 Diff 的性能足够优秀
3.Diff算法:
Diff 算法是虚拟 DOM 渲染过程中比较新旧树差异的算法,它的基本思路是通过对比旧的虚拟 DOM 树和新的虚拟 DOM 树,找到两者之间的差异,然后只更新发生变化的部分。这种方法能够避免不必要的重新渲染和性能开销。 O(n) 的时间复杂度。
它是通过同层的树节点进行比较的高效算法。比较只会在同层级进行, 不会跨层级比较;在diff比较的过程中,循环从两边向中间比较。也就是对于同一层,对于新旧层,每次都从两边往中间去,一次比对好最旁边的一个节点,然后把开始的指针往里去一个,再遍历比较。
Vue2需要下载Node.js和npm,还要vue-cli脚手架。
新建自己的项目:
vue init webpack yourProject
运行:
npm run dev
4.数据代理
2.基础
突然不知道该怎么下手学Vue了,我想先从特性来吧。
0.项目解析
别人解析的:
my-vue-project/
├── node_modules/ # 项目依赖
├── public/ # 静态资源文件夹
│ └── index.html # 项目的入口 HTML 文件
├── src/ # 源代码文件夹
│ ├── assets/ # 存放静态资源(如图片、样式等)
│ ├── components/ # 存放 Vue 组件
│ ├── views/ # 页面视图组件(如 Home.vue, About.vue)
│ ├── store/ # Vuex 状态管理
│ ├── router/ # Vue Router 路由配置
│ ├── App.vue # 根组件
│ ├── main.js # 项目入口文件
├── .gitignore # Git 忽略文件
├── babel.config.js # Babel 配置
├── package.json # 项目信息及依赖管理
└── vue.config.js # Vue CLI 配置(可选)
1.学习路径
-
Vue 入门
- Vue 实例:理解 Vue 是如何通过实例化一个 Vue 对象来挂载和管理应用的。
- 模板语法:学习 Vue 的模板语法,包括插值表达式(
{{}}
)、指令(如v-if
,v-for
),事件处理(如v-on
),双向绑定(如v-model
)。 - 计算属性与侦听器:掌握计算属性(
computed
)和侦听器(watch
),它们在处理动态数据时非常有用。 - 数据绑定与 DOM 更新机制:了解 Vue 如何响应式地更新 DOM,以及它背后的数据绑定原理。
-
Vue 组件
- 组件化开发:理解 Vue 中组件的概念,掌握如何定义和使用组件。学习如何将应用拆分为多个小的、独立的组件,以增强可维护性和可复用性。
- Props 和 Events:学习如何通过
props
向子组件传递数据,并通过$emit
触发事件向父组件发送消息。 - 插槽(Slots):理解 Vue 插槽的概念,学习如何使用具名插槽、作用域插槽来实现更灵活的组件间传递和渲染内容。
-
Vue Router
- 路由基础:了解 Vue Router 如何帮助你在单页应用(SPA)中进行页面间的导航。学习如何配置路由,使用
router-link
和router-view
。 - 动态路由和嵌套路由:学习如何设置动态路由,嵌套路由的配置,以及如何通过路由传递参数。
- 导航守卫:掌握如何使用路由的导航守卫(如
beforeEach
、beforeResolve
)进行权限控制、数据预加载等。
- 路由基础:了解 Vue Router 如何帮助你在单页应用(SPA)中进行页面间的导航。学习如何配置路由,使用
-
Vuex(状态管理)
- Vuex 概述:理解 Vuex 是什么,为什么它是必不可少的,尤其是当应用变得复杂时,它如何帮助管理全局状态。
- Vuex 核心概念:学习 Vuex 的核心概念,如
state
、mutations
、actions
、getters
和modules
。掌握如何通过 Vuex 在多个组件之间共享数据。 - 调试工具:了解如何使用 Vue Devtools 来调试 Vuex 状态管理。
-
Vue 的生命周期钩子
- 学习 Vue 组件的生命周期钩子,如
created
、mounted
、updated
和destroyed
,并理解它们在组件不同生命周期阶段的作用。
- 学习 Vue 组件的生命周期钩子,如
-
Vue 的响应式原理
- 深入理解 Vue 的响应式系统,了解 Vue 如何使用
Object.defineProperty
或Proxy
实现数据绑定和 DOM 更新机制。
- 深入理解 Vue 的响应式系统,了解 Vue 如何使用
-
Vue 组件的高级特性
- 异步组件:学习如何懒加载组件,优化大规模应用的性能。
- 动态组件:掌握如何使用
v-bind:is
动态切换组件。 - Mixins 和自定义指令:了解 Vue 中的 Mixins 机制以及如何创建和使用自定义指令。
-
Vue 的性能优化
- 虚拟 DOM:了解 Vue 的虚拟 DOM 渲染机制,如何减少不必要的 DOM 更新。
- 异步更新队列:学习 Vue 如何批量更新 DOM,提高性能。
- 组件懒加载:学习如何使用 Vue Router 的路由懒加载和异步组件来减少首次加载的时间。
- 性能调优工具:掌握如何使用 Vue Devtools 进行性能分析,检测性能瓶颈。
-
测试
- 学习如何为 Vue 组件编写单元测试。你可以使用工具如 Jest 或 Mocha 来进行测试。
- 了解如何使用 Vue Test Utils 进行组件测试,掌握模拟事件、测试组件的渲染和行为等。
2. Vue实例
每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的:
var vm = new Vue({// 选项
})
new Vue({el: '#app', // 指定挂载点data: {// 定义响应式数据message: 'Hello Vue!'},methods: {// 定义方法reverseMessage() {return this.message.split('').reverse().join('');}},// 其他选项...
});
上面的el
属性指定了Vue实例应该挂载到的DOM元素,data
属性定义了响应式数据,methods
属性定义了组件的方法。
在Vue实例创建后,你可以通过this关键字在组件的方法、计算属性和生命周期钩子中访问该实例。
每个Vue实例在其创建过程中都会经历几个关键的生命周期阶段:
- 创建(Creation):实例被创建,此时可以设置数据和方法。
- 挂载(Mounting):实例被挂载到DOM上,此时可以访问DOM元素。
- 更新(Updating):数据变化导致DOM更新。
- 渲染(Rendering):Vue生成新虚拟DOM树并进行对比,然后进行实际的DOM更新。
- 销毁(Destruction):实例被销毁,清理事件监听器和子组件。
el有2种写法
- 创建Vue实例对象的时候配置el属性
- 先创建Vue实例,随后再通过
vm.$mount('#root')
指定el
的值
data有2种写法
- 对象式:
data: { }
- 函数式:
data() { return { } }
用到组件时,data必须使用函数形式,否则会报错。
由Vue管理的函数,一定不要写箭头函数,否则 this 就不再是Vue实例了。
3. 模板语法
Vue 的模板语法是 Vue 中非常核心的部分,它是 Vue 用来将数据绑定到 DOM 的方式。通过模板语法,Vue 使得开发者能够在 HTML 模板中直接操作数据和展示视图,极大地简化了前端开发。Vue 模板目前只允许一个根元素–一个元素需要包裹模板内的所有内容(Vue 3 发布后会改变这种情况)。模板语法分两类:文本插值语法与指令语法。
插值表达式:插值表达式是 Vue 模板中最常用的一种数据绑定方式,{{ x }}
是一个插值表达式,它会被 Vue 渲染成 x 数据属性的值。Vue 会自动跟踪 x 数据属性的变化,并更新 DOM 中的内容。
通过 {{}}
插入 JavaScript 表达式,表达式中的数据会实时反映在 DOM 中。
支持简单表达式:如字符串、数字、布尔值、数组等。不能包含语句。
<div>{{ x }}</div>
<!--x 是 js 表达式,可以直接读取到 data 中的所有区域 --!>
指令语法:用于解析标签(包括:标签属性、标签体内容、绑定事件…)。Vue 的指令是带有前缀 v- 的特殊属性,指令提供了对 DOM 的动态控制,它们通常用于绑定数据、控制渲染、处理事件等。
v-html
:插入为html;<span v-html="xxx"></span>
v-bind
用于将元素的属性绑定到 Vue 实例中的数据。单向数据绑定,数据只能从data流向页面。可以使用v-bind:href/src/style/class
,也可以使用:href/src/style/class
简写。
<!-- 使用 v-bind 指令 -->
<img v-bind:src="imageUrl" alt="User avatar">
<!-- 使用 : 缩写 -->
<img :src="imageUrl" alt="User avatar">
v-model
用于在表单控件(如<input>
、<textarea>
、<select>
等)和 Vue 数据之间创建双向绑定。数据不仅能从data流向页面,也能从页面流向data;把v-model:value
简写为v-model
。<input v-model="message">
v-if / v-else / v-else-if
:条件渲染,只有条件为 true 时才渲染该元素。如果条件为 false,Vue 会从 DOM 中移除该元素。v-show
用于根据条件显示或隐藏元素,但与v-if
不同,v-show 仅仅是通过 display 样式来控制元素的显示和隐藏。性能:v-if
会完全销毁和重建元素,而v-show
只是简单地切换元素的显示状态。因此,如果切换频繁,v-show 性能更好。v-for
用于基于数组或对象渲染一个列表。可以通过 v-for 来循环渲染 DOM 元素。<li v-for="(item, index) of items" :key="index">
,这里key可以是index,更好的是遍历对象的唯一标识v-on
:监听DOM事件并在事件触发时执行方法,缩写为@ 字符。可以监听多种事件,如 click、input、keyup 等,可以绑定到方法、内联事件处理函数等。
<a v-on:click="doSomething"> ... </a>
<!-- 简写 -->
<a @click="doSomething"> ... </a>
v-text指令:向其所在的节点中渲染文本内容,v-text会替换掉节点中的内容;
v-html指令:向指定节点中渲染包含html结构的内容 ,v-html会替换掉节点中所有的内容,v-html可以识别html结构;
v-cloak指令(没有值):本质是一个特殊属性,配合css,暂时隐藏 Vue 模板中的未编译内容,直到 Vue 实例完成编译和渲染;
v-once 指令:v-once所在节点在初次动态渲染后,就视为静态内容了,以后数据的改变不会引起v-once所在结构的更新;
v-pre指令:跳过v-pre所在节点的编译过程,可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。
在Vue.js中,事件修饰符(Event Modifiers)是特殊的后缀,可以被添加到 v-on
指令的参数中,用来指定如何处理事件。
-
.stop:阻止事件冒泡。
<template><div @click="handle('parent')"> <!-- 点击父元素 --><button @click.stop="handle('child')"> <!-- 点击子元素,.stop 阻止事件冒泡到父元素 -->Click me</button></div> </template>
-
.prevent:阻止默认事件(如表单提交)。
<template><form @submit.prevent="onSubmit"><button type="submit">Submit</button></form> </template>
-
.capture:使用事件捕获模式监听事件。通常事件会从父元素流向目标元素,捕获则是反过来。
<template><div @click.capture="handle">Click me</div> </template>
-
.self:只当事件是在该元素本身触发时才会触发回调。
<template><div @click.self="handle"><button>Click me</button><button>Click me too</button></div> </template>
-
.once:事件将只会被触发一次,之后监听器会被移除。
<template><button @click.once="handle">Do this once</button> </template>
-
.passive:告诉浏览器你不想阻止事件的默认行为,常用于提升滚动性能。
<template><div @scroll.passive="handleScroll">Scroll me</div> </template>
-
.native:监听组件根元素的原生事件。
<template><my-component @click.native="handleClick" /> </template>
-
.sync(Vue 2.3.0+):用于
v-model
,在自定义组件上实现双向数据绑定。<template><child-component :value.sync="parentValue" /> </template>
-
.exact(Vue 2.5.0+):当使用多个修饰符时,
.exact
修饰符可以确保除了指定的事件外,其他事件监听器不会被触发。<template><div @click.exact="handle">Click me</div> </template>
这些修饰符可以组合使用,例如 @click.stop.prevent
可以同时阻止事件冒泡和默认行为。
Key的作用:
- 在v-for中需要key,因为如果不用key就采用就地更新原则(一个挨一个改),当数据项的顺序改变时,Vue 不会随之移动 DOM 元素的顺序,而是就地更新每个元素,确保它们在原本指定的索引位置上渲染。
- key是虚拟DOM的唯一标识。
4. 计算属性
属性是指data里的数据,前者为属性名,后者为属性值。如果需要的属性(数据)不存在,就需要计算得到。计算属性是基于它们的依赖进行缓存的,只有当依赖发生变化时,它们才会重新计算。
底层借助了Objcet.defineproperty()方法提供的getter和setter。getter在初次读值和依赖的数据改变时会调用。setter在该属性被修改时会调用。
与methods实现相比,内部有缓存机制(复用),效率更高,调试方便 。一个计算属性仅会在其响应式依赖更新时才重新计算。否则立即返回先前的计算结果,而不用重复执行 getter 函数。方法调用总是会在重渲染发生时再次执行函数。
计算属性最终会出现在vm上,直接读取使用即可;如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变;如果计算属性确定不考虑修改,可以使用计算属性的简写形式。
语法:
computed{计算属性名:{ get(){},set(){}}}
new Vue({el:'#root',data:{n:12},computed: {//完整写法fun: {get(){return n++;},set(value){this.n=value}// 简写fun2() {return this.n++}}
})
5. 监视属性(侦听器)
侦听器允许你“监听”一个数据属性(或计算属性)的变化。当这个数据属性发生变化时,Vue 会自动触发相应的回调函数。watch 选项 当需要在数据变化时执行异步或开销较大的操作时,用侦听器来响应数据变化。
watch: {message(newVal, oldVal) {console.log(`message changed: ${oldVal} -> ${newVal}`);}
}
watch监视属性
- 当被监视的属性变化时,回调函数handler自动调用,进行相关操作
- 监视的属性必须存在,才能进行监视,既可以监视data,也可以监视计算属性
- 配置项属性默认为immediate:false,改为 true,则初始化时调用一次 handler(newValue,oldValue)
Vue侦听器可以接受更多的选项来控制其行为:
- deep:如果需要侦听一个对象内部属性的变化,可以设置
deep: true
。 - immediate:如果需要在侦听器定义后立即以当前的值触发它,可以设置
immediate: true
。 - handler:一个函数或方法名,当被侦听的属性变化时调用。
在 Vue 中,当数据变动时,侦听器会在当前的同步代码执行完后立即执行。
侦听器会将回调放入 微任务队列,这意味着它们会在当前同步代码执行完成后,立刻执行,但在其他事件(如 setTimeout、UI 渲染等宏任务)之前执行。
会将数据变动队列推入一个 异步队列 中,并在下一个事件循环(微任务队列(microtask queue))中执行这些任务。
6.Vue生命周期
生命周期:又名生命周期回调函数、生命周期函数、生命周期钩子;Vue在关键时刻帮我们调用的一些特殊名称的函数;生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的;生命周期函数中的 this 指向是vm或组件实例对象。
。。。。
7.组件化编程
Vue 的 组件化编程 是 通过将应用程序分解成一个个独立的、可复用的组件来构建用户界面。每个组件代表应用的一个独立部分,拥有自己的数据、模板、样式和逻辑。这种方式不仅可以提高代码的可维护性和可重用性,还能帮助开发者更好地组织大型应用程序。
在 Vue 中,组件 是 Vue 实例的扩展。每个组件都是一个包含有模板、逻辑和样式的独立单元,可以像 HTML 标签一样使用。一个 Vue 应用通常是由多个组件嵌套和组合而成的。
模板:定义组件的结构,通常是 HTML 标记。<template>
脚本:包含组件的业务逻辑,如数据、方法、生命周期钩子等。script>
样式:为组件设置样式,确保其在局部范围内生效。<style scoped>
全局组件:在整个 Vue 实例中都可以访问的组件,通常在入口文件(如 main.js)中注册。
局部组件:只在父组件中注册和使用的组件。
8.父子组件通信
目的是:让父组件控制子组件的行为,或让子组件通知父组件发生了某些事件。
-
props
:用于从父组件向子组件传递数据,子组件可以通过 props 接收到父组件传递的值。
使用方式:- 父组件传递数据:父组件通过
v-bind
或简写:
将数据传递给子组件(父组件中使用子组件,在子组件上使用)。 - 子组件接收数据:子组件通过
props
来接收这些数据。
- 父组件传递数据:父组件通过
-
$emit
:用于子组件向父组件发送事件。当子组件的某个行为发生时(如按钮点击),子组件可以触发事件,并将数据传递给父组件,父组件可以通过事件处理来响应这些变化。
使用方式:- 子组件触发事件:通过
$emit
在子组件内部触发事件。 - 父组件监听事件:父组件通过
v-on
(或简写@
)来监听子组件的事件(父组件中使用子组件,在子组件上使用)。
- 子组件触发事件:通过
-
ref
允许父组件直接访问子组件的实例(即 Vue 实例本身)。通过ref
,父组件可以调用子组件的公开方法或访问子组件的属性。
使用方式:- 父组件使用 ref:在子组件的标签上使用 ref 属性来标记子组件。
- 父组件访问子组件实例:通过 this.$refs 获取子组件实例,进而调用子组件的方法或访问子组件的属性。
-
provide
和inject
是一种更加灵活的跨级组件通信方式。通过这两个 API,父组件(或祖先组件)可以向子组件(或后代组件)提供数据,而不需要通过逐层的 props 传递。- provide:祖先组件提供数据给后代组件。
- inject:后代组件接收祖先组件通过 provide 提供的数据。
这种方式适用于需要在多个层级的组件之间共享数据的情况。
9.插槽(Slots)
插槽是 Vue 提供的一种让父组件将内容插入到子组件模板中的机制。插槽(Slot)允许父组件将一些内容插入到子组件的模板中,从而实现更灵活的组件设计。通过插槽,子组件的结构可以在不改变子组件代码的情况下由父组件来决定,增强了组件的可复用性和灵活性。
- 默认插槽是最常用的一种插槽,父组件可以在子组件的标签内传递一些内容,子组件通过
<slot></slot>
来渲染这些内容。 - 具名插槽允许父组件向子组件传递多个插槽内容,并且每个插槽都可以有一个名字。通过指定 name 属性,可以区分不同的插槽内容。使用方式:
在子组件中定义多个带name
属性的插槽;在父组件中通过v-slot
或slot
绑定特定名称的内容。(子组件使用带name属性的插槽时可以提供默认内容,类似于默认参数) - 作用域插槽是一种特殊的插槽,它允许子组件向父组件传递数据。父组件通过作用域插槽可以访问子组件提供的数据,并渲染自定义的内容。使用方式:
子组件通过slot-scope
或v-slot
向父组件传递数据。父组件通过作用域插槽接收并使用这些数据。
v-slot
是用于定义和绑定插槽内容的标准语法。它可以用于默认插槽、具名插槽和作用域插槽。
<template v-slot:default><p>This is the default slot content</p>
</template><template v-slot:header><h1>This is the header slot</h1>
</template><template v-slot:default="slotProps"><p>{{ slotProps.message }}</p>
</template>
10.mixins 和 extends(代码复用)
mixins:Mixins 是一种灵活的代码复用机制,可以将组件的选项(如 data、methods、computed 等)提取到一个独立的文件中,然后通过 mixins 将这些选项混入到多个组件中。通过这种方式,可以让不同的组件共享相同的功能,而不需要重复编写相同的代码。
Mixins 本质上是一个包含组件配置对象的 JavaScript 对象。可以创建一个 Mixin 文件(js),定义一些通用的方法、数据;然后在组件中,你可以通过 mixins 选项来引入 Mixin:export default {mixins: [myMixin]}
,如果父组件和 Mixin 中都定义了同样的钩子(如 created),它们都会按顺序执行(先mixin再父组件)。
当多个 Mixins 中有相同的选项(如 data、methods、computed 等),Vue 会合并它们。如果是对象类型,Vue 会进行递归合并。如果是数组,Vue 会进行拼接(如果多个 Mixins 中定义了相同的 data,Vue 会合并它们,而不是覆盖。如果你需要多个 Mixin 中的 data 合并在一起,可以通过返回函数的方式实现);如果是函数,会依照覆盖策略(后面的 Mixin 会覆盖前面的 Mixin 中相同的方法)。生命周期钩子的话是mixin先于父组件。
在 Vue 3 中,推荐使用 Composition API 代替 Mixins。降低耦合性。
extends:类似于 mixins,但是通过 extends 继承组件的选项,可以在子组件中继承父组件的行为。extends 主要是将目标组件的选项合并到当前组件中。这意味着,如果你在目标组件中定义了某些选项(如 data、methods 等),它们会被自动合并到当前组件中。如果当前组件中有相同的选项,它们会覆盖目标组件中的选项。
在使用 extends 时,Vue 会按以下规则来合并选项:
- data:如果基类和子类都有 data 选项,Vue 会合并它们。如果子类中的 data 返回的是一个对象,它会覆盖基类中的同名属性。如果返回的是一个函数,Vue 会根据返回的函数来合并数据。
- methods、computed、watchers:如果基类和子类中有相同的方法或计算属性,子类中的方法会覆盖基类中的方法。
- 生命周期钩子:如果基类和子类都定义了同一个生命周期钩子(如 created),它们会按照引入顺序执行:先执行基类的钩子,再执行子类的钩子。
11. 异步组件
异步组件(Asynchronous Components)是一种延迟加载组件的机制,允许你将组件的加载延迟到它真正需要渲染的时候。这有助于提高应用的性能,尤其是在大型应用中,通过按需加载(懒加载)组件,减少初始加载的资源和时间。
使用Vue.component()定义全局异步组件:
Vue.component('async-example-name', () => import('./AsyncComponent.vue'));
components定义异步组件:
<script>
export default {components: {'async-example': () => import('./components/AsyncComponent.vue') }
};
</script>
可以设置loading
、error
和 delay
选项:
const AsyncComponent = () => ({// 需要加载的组件 (异步组件)component: import('./components/AsyncComponent.vue'),// 加载时显示的组件loading: require('./components/LoadingComponent.vue'),// 加载失败时显示的组件error: require('./components/ErrorComponent.vue'),// 最长等待时间delay: 200, // 等待200ms后显示 loading 组件// 超过这个时间认为加载失败,显示 error 组件timeout: 3000 // 超过3秒认为加载失败
});
12. 动态组件
动态组件(Dynamic Components)允许在运行时根据不同的条件渲染不同的组件。这使得你能够灵活地在同一位置加载不同的组件,而无需显式地写出多个 <component>
标签。
在 Vue 中,动态组件的核心思想是通过 v-bind:is
动态地指定渲染的组件。v-bind:is
可以绑定到一个动态值,这个值可以是组件的名称、对象或函数。动态组件允许在同一个 DOM 元素中切换不同的组件。可以通过 is 属性指定当前展示的组件:
<component :is="currentComponent"></component>
有时你希望每次渲染时都重新创建组件实例,可以使用 key
属性来强制 Vue 销毁并重建组件。
参考
[1] 深入理解MVVM架构模式
[2] vue的diff算法详解(看完谁问都不慌了)
[3] vue-cli ,vue2项目的完整搭建,新建,配置,路由配置,API封装,到打包上线