马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
一、Vue3新变革
Vue 3 相比于 Vue 2 做了许多改进,不仅提升了性能,还引入了一些新的功能,使得开辟更加高效、灵活。
1. 性能提升
Vue 3 在性能方面做了大量的优化,尤其是在渲染和更新方面,主要通过以下几个方式提升:
- 更快的虚拟 DOM:Vue 3 的虚拟 DOM 实现进行了优化,减少了不必要的渲染和更新,提高了性能。
- Tree Shaking:Vue 3 在构建时支持更好的 Tree Shaking(摇树优化),即只打包你使用的代码,未使用的代码不会打包进最终文件,从而减小了体积。
- 更小的包体积:由于 Vue 3 引入了许多新特性并优化了内部代码,使得其团体包体积比 Vue 2 更小。
- 响应式系统优化:Vue 3 使用了 Proxy 代替了 Vue 2 的 Object.defineProperty 作为响应式系统的核心,使得 Vue 3 的响应式系统更加高效,并且支持更多的功能。
2. Composition API(组合式 API)
这是 Vue 3 最紧张的特性之一。组合式 API 为 Vue 提供了更加灵活和清楚的代码结构。它引入了一些新的 API,如 ref、reactive、computed、watch 等,可以让开辟者在组件中更加方便地构造和复用逻辑。
比方:
- import { ref, reactive, onMounted } from 'vue';
- export default {
- setup() {
- const count = ref(0); // 响应式数据
- const state = reactive({ name: 'Vue 3' });
- onMounted(() => {
- console.log('组件已挂载');
- });
- return {
- count,
- state
- };
- }
- };
复制代码
- ref 用来创建基础数据类型的响应式数据;
- reactive 用来创建对象或数组的响应式数据;
- onMounted 等生命周期钩子函数则让你在组合式 API 中使用组件生命周期。
组合式 API 的优势:
- 逻辑复用:相比于 Vue 2 的选项式 API,组合式 API 使得在组件中复用逻辑变得更加方便。你可以将多个逻辑片断封装成函数,进行跨组件的共享。
- 更好的 TypeScript 支持:组合式 API 可以更自然地和 TypeScript 共同使用,类型推导更加准确。
3. 新生命周期钩子
在 Vue 3 中,组合式 API 的引入使得生命周期钩子的定名有所变革。Vue 2 的生命周期钩子是如 beforeCreate、created、mounted 等,它们是基于选项式 API 的。Vue 3 修改了一些生命周期钩子的名称,去除了 Vue 2 中的 beforeDestroy 和 destroyed,用 beforeUnmount 和 unmounted 代替。类似地,created 被替换成了 setup,以适应 Composition API。
Vue 3 引入了生命周期钩子的组合式 API 版本,它们可以在 setup 函数中使用,如 onMounted、onUpdated、onUnmounted 等。比方:
- beforeMount → onBeforeMount
- mounted → onMounted
- beforeUpdate → onBeforeUpdate
- updated → onUpdated
这些新钩子函数是用于在 setup 函数中使用的。
4. Teleport(传送门)
Vue 3 引入了 Teleport 组件,答应你将 DOM 元素从一个地方传送到另一个地方。比方,你可以将模态框、关照等组件的内容从当前组件的 DOM 树中移到根节点或 body 中,而不必改变组件的层级结构。
- <template>
- <Teleport to="body">
- <div class="modal">This is a modal!</div>
- </Teleport>
- </template>
复制代码 5. Fragments(片断)
Vue 3 支持 Fragments,即一个组件可以返回多个根节点元素,而不再需要一个单独的根元素来包裹组件。这对于优化组件结构、减少无意义的 DOM 元素非常有效。
- <template>
- <div>Part 1</div>
- <div>Part 2</div>
- </template>
复制代码 在 Vue 2 中,每个组件必须有且只有一个根节点,而 Vue 3 答应组件返回多个元素。
6. Suspense(延迟加载)
Vue 3 引入了 Suspense 组件,用于处理异步组件的加载。它答应你在等待某个组件加载时展示一个加载指示器。
- <template>
- <Suspense>
- <template #default>
- <AsyncComponent />
- </template>
- <template #fallback>
- <div>Loading...</div>
- </template>
- </Suspense>
- </template>
复制代码 7. 自界说事件(v-model)语法改进
在 Vue 3 中,组件可以同时接受多个 v-model,而不仅仅是 value。这意味着你可以为多个 prop 和事件使用差别的 v-model,而不需要再依赖默认的 value 和 input 事件。这对于那些需要多个双向绑定的组件非常有效。
1. 支持多个 v-model
在 Vue 3 中,组件可以同时接受多个 v-model,而不仅仅是 value。这意味着你可以为多个 prop 和事件使用差别的 v-model,而不需要再依赖默认的 value 和 input 事件。这对于那些需要多个双向绑定的组件非常有效。
比方,假设有一个组件需要吸收两个数据:name 和 age,你可以为它们分别使用差别的 v-model:
- <template>
- <MyForm v-model:name="name" v-model:age="age" />
- </template>
- <script>
- export default {
- data() {
- return {
- name: 'John',
- age: 30,
- };
- },
- };
- </script>
- <!-- MyForm.vue -->
- <template>
- <input :value="name" @input="$emit('update:name', $event)" />
- <input :value="age" @input="$emit('update:age', $event)" />
- </template>
- <script>
- export default {
- props: {
- name: String,
- age: Number,
- },
- };
- </script>
复制代码 在这个例子中,name 和 age 分别使用了两个 v-model,并且使用了 update:name 和 update:age 事件来进行更新。
2. 自界说 prop 和事件名
Vue 3 引入了自界说 v-model 的能力,答应开辟者指定自己的 prop 名和事件名,而不必固定为 value 和 input。这使得自界说组件的设计更加灵活。
在 Vue 2 中,v-model 默认绑定的是组件的 value prop,并监听 input 事件,但在 Vue 3 中,你可以通过自界说 prop 和事件名来界说差别的举动。
比方:
- <template>
- <MyInput v-model="text" />
- </template>
- <script>
- export default {
- components: {
- MyInput: {
- props: {
- modelValue: String, // 注意这里使用 modelValue 作为 prop
- },
- emits: ['update:modelValue'], // 自定义事件名
- template: '<input :value="modelValue" @input="$emit(\'update:modelValue\', $event)" />',
- },
- },
- data() {
- return {
- text: 'Hello Vue 3!',
- };
- },
- };
- </script>
复制代码 在这个例子中,MyInput 组件使用了 modelValue 作为 prop,update:modelValue 作为事件名。这让你可以灵活地定名 prop 和事件,而不仅仅范围于 value 和 input。
3. 简化的语法
Vue 3 还简化了 v-model 的使用方式。你可以使用类似于原生 HTML 的简洁语法,不需要额外指定事件或 prop。
比方,在 Vue 3 中,你可以直接如许写:
- <MyInput v-model="message" />
复制代码 这里 Vue 会主动将 v-model 绑定到 modelValue,并且主动处理 update:modelValue 事件,避免了冗余的配置。
4. 支持修改事件名
在 Vue 3 中,如果你需要使用差别的事件名称来代替默认的 update:modelValue,你可以通过 model 选项来进行配置。这在需要更改事件名称的情况下非常有效。
比方,假设你想将事件名改为 changed,你可以在组件的 model 选项中进行配置:
- <template>
- <MyInput v-model="text" />
- </template>
- <script>
- export default {
- components: {
- MyInput: {
- props: {
- modelValue: String,
- },
- emits: ['changed'],
- model: {
- prop: 'modelValue',
- event: 'changed',
- },
- template: '<input :value="modelValue" @input="$emit(\'changed\', $event)" />',
- },
- },
- data() {
- return {
- text: 'Hello Vue 3!',
- };
- },
- };
- </script>
复制代码 在这个例子中,modelValue 仍旧是传入的 prop,但事件名称变成了 changed,你可以灵活控制事件名。
8. Custom Renderer(自界说渲染器)
Vue 3 加强了对自界说渲染器的支持,这意味着你可以用 Vue 来渲染非 DOM 的目标,好比通过 WebGL、Canvas、SVG 或其他渲染系统进行渲染。答应开辟者为 Vue 的虚拟 DOM 创建自界说的渲染过程。通过自界说渲染器,开辟者可以将 Vue 组件的渲染输出到任何类型的目标(好比原生 DOM、Canvas、WebGL 大概其他平台)上。
createRenderer 是 Vue 3 中的核心 API,用于创建一个自界说的渲染器。它答应你提供自界说的节点操作函数,来替换默认的 DOM 操作。
- import { createRenderer } from 'vue';
- // 定义一个自定义渲染器
- const renderer = createRenderer({
- createElement(type) {
- // 自定义创建元素的方法
- return new MyCustomElement(type); // 创建自定义元素
- },
- insert(child, parent) {
- // 自定义插入元素的方法
- parent.appendChild(child);
- },
- patchProp(el, key, prevValue, nextValue) {
- // 自定义属性更新的方法
- el.setAttribute(key, nextValue);
- },
- // 还可以定义更多的渲染逻辑
- });
- // 使用自定义渲染器来渲染 Vue 组件
- const app = createApp(MyComponent);
- renderer.render(app, document.getElementById('root')); // 这里的 root 可以是其他非 DOM 的目标
复制代码 二、使用
1.选项式API
Options API:Vue2使用的API风格,它通过在组件中界说差别的 选项(options)来声明组件的举动,包括数据、方法、生命周期钩子等。
选项式 API 的核心是将一个 Vue 组件的功能分为几个独立的“选项”,这些选项分别代表了组件的差别部门,好比 data、methods、computed、watch 等。
一个典型的 Vue 组件使用选项式 API 的示比方下:
- <template>
- <div>
- <p>{{ message }}</p>
- <button @click="increment">Increment</button>
- </div>
- </template>
- <script>
- export default {
- // 1. data 选项:用于声明组件的响应式数据
- data() {
- return {
- message: 'Hello, Vue 2!',
- count: 0,
- };
- },
- // 2. methods 选项:声明组件中的方法
- methods: {
- increment() {
- this.count++;
- },
- },
- // 3. computed 选项:声明计算属性
- computed: {
- doubledCount() {
- return this.count * 2;
- },
- },
- // 4. 生命周期钩子:Vue 提供的一些生命周期回调
- mounted() {
- console.log('组件已挂载');
- },
- watch: {
- // 5. watch 选项:观察某些数据变化并作出反应
- count(newVal, oldVal) {
- console.log(`count 改变了:${oldVal} -> ${newVal}`);
- },
- },
- };
- </script>
复制代码 选项式 API 的几个关键部门
- data:声明组件的响应式数据,返回一个对象,包罗组件的状态和数据。
- methods:界说组件中的方法,这些方法可以在模板中调用,也可以在生命周期钩子中使用。
- computed:盘算属性,它是根据数据盘算得出的值,具有缓存功能。当依赖的数据发生变革时,盘算属性会主动更新。
- watch:观察属性的变革,可以监听组件数据的变革,并在数据变革时执行某些操作。与盘算属性差别,watch 用于处理异步或开销较大的操作。
- 生命周期钩子:Vue 提供了多个生命周期钩子来让开辟者在组件的差别生命周期阶段执行代码。常见的钩子包括 mounted、created、beforeDestroy 等。
- props:界说组件的外部输入(即父组件通报给子组件的数据)。通过 props,你可以在子组件中访问父组件的数据。
- emits(Vue 3 引入):用于声明组件能够触发的自界说事件,通常用于子组件向父组件通报数据。
长处:
- 易于理解和使用:选项式 API 非常直观,结构清楚。每个选项都有固定的作用,使得开辟者能够轻松理解和使用。
- 适合小型组件:对于简朴的组件,选项式 API 非常合适,由于它把所有的逻辑构造在差别的选项中,使得代码易于理解和维护。
- 结构化的代码:各个部门(如 data、methods、computed 等)都有清楚的分隔,有助于代码的构造。
缺点:
- 逻辑复用困难:选项式 API 构造的逻辑比较散乱。如果多个组件有类似的逻辑,需要通过 mixin 大概其他方式来复用逻辑,但这也大概导致代码耦合。
- 大型组件难以维护:随着组件变得越来越复杂,data、methods、computed 等大概会变得非常巨大,使得代码难以维护和扩展。
固然 Vue 3 引入了 Composition API,但 Vue 3 依然支持选项式 API,开辟者可以根据项目的需要选择使用哪种方式。这两者并不是互斥的,开辟者可以在同一个项目中混合使用它们。
2.组合式API
Composition API:它通过将组件逻辑拆分成函数(而不是像选项式 API 那样按照 data、methods、computed 等进行构造)来提升代码的灵活性、复用性和可维护性。组合式 API 的核心头脑是将相关的业务逻辑封装成函数,并在组件中按需引入和使用。这与选项式 API 中将差别功能(如数据、方法、盘算属性等)分开构造的方式差别。通过组合式 API,你可以更加自由地管理和复用组件的逻辑。
Vue 3 引入的 组合式 API(Composition API)是一个全新的方式来编写 Vue 组件,它通过将组件逻辑拆分成函数(而不是像选项式 API 那样按照 data、methods、computed 等进行构造)来提升代码的灵活性、复用性和可维护性。与选项式 API 相比,组合式 API 提供了一种更加灵活、模块化的方式来构造代码,特别实用于复杂组件的开辟。
组合式 API 的常用功能
- setup 函数
组合式 API 的入口函数是 setup。它是 Vue 3 组件中必不可少的部门,所有的响应式数据、盘算属性、方法、生命周期钩子等都可以在 setup 中界说。
- setup 函数在组件创建之前执行,返回的对象(或函数)会袒露给模板,作为组件的响应式数据和方法。
- import { ref, reactive } from 'vue';
- export default {
- setup() {
- // 响应式数据
- const count = ref(0); // ref 用于基本类型数据
- const state = reactive({ name: 'Vue 3' }); // reactive 用于对象或数组
- // 计算属性
- const doubledCount = computed(() => count.value * 2);
- // 方法
- const increment = () => {
- count.value++;
- };
- // 返回值暴露给模板
- return {
- count,
- doubledCount,
- increment,
- state
- };
- }
- };
复制代码
- setup 函数中的返回值会主动袒露给组件的模板,模板中可以直接访问返回的值。
- setup 中的代码是在 Vue 组件的实例化之前运行的,以是你无法在 setup 中访问 this。
- 响应式数据(ref 和 reactive)
- ref 用于创建基本数据类型的响应式数据。ref 返回一个包罗 .value 属性的对象,只有通过 .value 来访问和修改它的值。
- const count = ref(0); // count 是一个响应式数据
- count.value++; // 修改时需要使用 .value
复制代码 - reactive 用于创建对象或数组的响应式数据,它会使对象内部的所有属性变成响应式。
- const state = reactive({ name: 'Vue 3', age: 3 });
- state.name = 'Vue 4'; // state 里的属性是响应式的
复制代码 - ref 和 reactive 是 Vue 3 响应式系统的基础。reactive 更适适用于对象、数组等复杂数据类型,而 ref 更实用于基本数据类型(如 number、string、boolean)。
- computed 和 watch
- computed 用于界说盘算属性,它会根据依赖的响应式数据主动更新。
- const count = ref(0);
- const doubledCount = computed(() => count.value * 2);
复制代码 - watch 用于监听响应式数据的变革,实用于需要执行副作用操作(如异步操作或外部 API 调用)的场景。
- watch(count, (newVal, oldVal) => {
- console.log(`count changed from ${oldVal} to ${newVal}`);
- });
复制代码 - watch 可以监听单个数据源,也可以监听对象的多个属性。
- 生命周期钩子
在组合式 API 中,生命周期钩子通过类似于 onMounted、onCreated 等函数来使用。这些函数可以在 setup 中导入使用。
- import { onMounted, onUpdated, onUnmounted } from 'vue';
- export default {
- setup() {
- onMounted(() => {
- console.log('组件已挂载');
- });
- onUpdated(() => {
- console.log('组件更新');
- });
- onUnmounted(() => {
- console.log('组件已销毁');
- });
- }
- };
复制代码 这些生命周期钩子函数在 setup 中使用,可以更加灵活地构造代码。
- provide 和 inject
Vue 3 中的 provide 和 inject 机制可以资助你在组件树的差别层级之间共享数据。provide 在父组件中提供数据,而 inject 让子组件获取这些数据。
- provide:父组件中提供数据。
- import { provide } from 'vue';
- export default {
- setup() {
- const sharedData = ref('Hello from parent');
- provide('sharedData', sharedData);
- }
- };
复制代码 - inject:子组件中获取父组件提供的数据。
- import { inject } from 'vue';
- export default {
- setup() {
- const sharedData = inject('sharedData');
- console.log(sharedData); // 'Hello from parent'
- }
- };
复制代码
优势
- 逻辑复用:
- 组合式 API 使得组件中的逻辑可以更加灵活地被复用。你可以将相关的逻辑封装成函数,然后在多个组件中引入,避免了选项式 API 中的代码耦合问题。
- 更好的类型推导:
- 组合式 API 与 TypeScript 更加兼容,TypeScript 可以更好地推导类型。你可以在 setup 函数中显式地声明变量的类型,避免一些隐式类型问题。
- 更好的构造和维护:
- 组件中的逻辑和状态可以按功能拆分,避免了选项式 API 中差别功能的稠浊,使得代码更加易于构造、理解和维护。
- 更清楚的上下文管理:
- 由于 setup 函数是 Vue 组件的入口,你可以清楚地界说组件的状态和举动,而不会受到其他选项(如 data、methods)的干扰。
缺点
- 学习曲线较陡:
- 组合式 API 在刚接触时大概需要一定的学习本钱,尤其是对于风俗了选项式 API 的开辟者来说,初期的上手大概稍微有些困难。
- 代码结构大概不清楚:
- 对于小型组件来说,选项式 API 的结构非常清楚,而组合式 API 大概会将组件的差别功能分散到多个地方,导致代码难以追踪和理解。
- 模板和 JavaScript 逻辑的分离较弱:
- 在组合式 API 中,组件的 JavaScript 逻辑通过 setup 函数袒露给模板,大概导致一些模板和逻辑的界限变得含糊,特别是在大组件中,大概会导致组件难以维护。
实用场景:
- 复杂组件:当组件的逻辑越来越复杂时,组合式 API 可以资助你将逻辑按功能进行拆分,避免代码冗长和难以管理。
- 逻辑复用:如果你需要在多个组件中复用相同的逻辑,组合式 API 提供了更好的机制,可以通过将逻辑封装成函数来复用。
- TypeScript 项目:组合式 API 与 TypeScript 的兼容性非常好,能够提供更好的类型推导和静态查抄,适合类型安全要求较高的项目。
3.响应式API
Vue 3 中的响应式系统引入了 reactive 和 ref:
- reactive 用于将对象变为响应式。
- ref 用于将基本数据类型(如字符串、数字、布尔值等)变为响应式。
在 Vue 2 中,响应式对象是通过 Object.defineProperty 实现的,而 Vue 3 使用 Proxy 提供了更高效、更灵活的响应式处理。
当你将一个响应式对象的属性赋值或解构到一个本地变量时,访问或赋值该变量是非响应式的,由于它将不再触发源对象上的 get / set 代理。注意这种“断开”只影响变量绑定——如果变量指向一个对象之类的非原始值,那么对该对象的修改仍旧是响应式的。从 reactive() 返回的代理尽管举动上表现得像原始对象,但我们通过使用 === 运算符照旧能够比较出它们的差别。
ref:
ref 返回的是一个包罗 value 属性的对象,你需要通过 .value 来访问或修改它的值。在模板中,Vue 会主动解包 ref,以是你不需要写 .value。ref 内部是通过 reactive 来实现的。当你调用 ref 时,Vue 会创建一个包罗 value 属性的对象,并将这个对象通报给 reactive,使其变成响应式的。
reactive:
reactive 用于创建一个响应式的对象或数组。与 ref 差别,reactive 直接作用于对象或数组,而不需要 .value 来访问或修改。reactive 使用了 Proxy 来实现响应式。Proxy 可以拦截对象的读取、赋值等操作,从而在数据变革时触发视图更新。
4.服务端渲染SSR
与客户端的单页应用 (SPA) 相比,SSR 的优势主要在于:
- 更快的首屏加载:这一点在慢网速大概运行缓慢的装备上尤为紧张。服务端渲染的 HTML 无需等到所有的 JavaScript 都下载并执行完成之后才表现,以是你的用户将会更快地看到完整渲染的页面。除此之外,数据获取过程在初次访问时在服务端完成,相比于从客户端获取,大概有更快的数据库连接。这通常可以带来更高的核心 Web 指标评分、更好的用户体验,而对于那些“首屏加载速度与转化率直接相关”的应用来说,这点大概至关紧张。
- 统一的心智模子:你可以使用相同的语言以及相同的声明式、面向组件的心智模子来开辟整个应用,而不需要在后端模板系统和前端框架之间来回切换。
- 更好的 SEO:搜索引擎爬虫可以直接看到完全渲染的页面。
SSR (Server-Side Rendering) 和 SPA (Single-Page Application) 是两种差别的网页渲染方式。它们的根本区别在于页面内容是在哪一端天生的:是在服务器端照旧客户端。下面详细表明这两者的概念、优缺点以及它们之间的区别。
什么是 SSR (Server-Side Rendering)?
SSR(服务器端渲染)是指将应用程序的 HTML 内容在服务器端天生后发送到客户端浏览器。也就是说,当用户哀求一个页面时,服务器会根据当前路由渲染完整的 HTML 页面并返回给浏览器,浏览器加载和渲染这个 HTML 页面,然后在客户端进行后续的交互。
SSR 的工作流程:
- 用户哀求某个页面。
- 服务器吸收到哀求后,执行应用程序,天生完整的 HTML 页面。
- 服务器将天生的 HTML 页面返回给客户端。
- 客户端加载 HTML 页面,用户可以看到页面内容。
- 客户端接受后,Vue、React 或其他前端框架初始化,后续交互由客户端处理。
SSR 的特点:
- 页面内容在服务器端渲染,以是首屏加载速度较快,能更快展示页面内容。
- 适合 SEO,由于搜索引擎能够直接抓取到渲染好的 HTML 内容。
- 初次加载页面需要等待服务器的响应,大概导致较高的服务器负担,尤其是流量大时。
- 在客户端接受后,应用就变成了通例的 SPA 进行交互。
什么是 SPA (Single-Page Application)?
SPA(单页面应用)是一种通过客户端的 JavaScript 来动态渲染页面的应用。在这种模式下,用户加载页面后,所有的交互、路由跳转、内容更新都通过 JavaScript 来实现,而无需重新加载整个页面。常见的 SPA 框架有 React、Vue、Angular 等。
SPA 的工作流程:
- 用户哀求某个页面,浏览器加载一次 HTML 页面,通常包罗基本的框架、CSS、JavaScript 等资源。
- 一旦页面加载完成,JavaScript 会控制后续的页面渲染,所有的页面内容都通过前端路由来加载和渲染,而不需要革新整个页面。
- 用户点击链接或触发操作时,前端路由会根据哀求的 URL 来加载相应的组件并更新页面。
SPA 的特点:
- 初次加载页面时,整个应用会加载所有资源(HTML、JS、CSS 等),因此初次加载时间大概较长。
- 一旦页面加载完成,后续的页面交互不会引发完整的页面革新,体验更为流畅。
- 适合动态交互丰富的应用。
- SEO 对比 SSR 要弱,搜索引擎爬虫无法直接抓取 SPA 页面中动态加载的内容,通常需要额外配置如 SSR 或 Pre-rendering 来解决 SEO 问题。
特性SSR (服务器端渲染)SPA (单页面应用)渲染位置页面内容在服务器端渲染后发送到客户端页面内容由客户端通过 JavaScript 动态渲染首屏加载速度首屏加载较快,直接获取完整的 HTML 页面初次加载时较慢,需加载 JavaScript、CSS 和资源交互体验首屏加载后,交互由客户端接受,通常体验流畅不需要重新加载页面,用户交互体验更加流畅SEO 优化由于页面内容在服务器端渲染,搜索引擎可以直接抓取内容由于页面是通过 JavaScript 渲染的,SEO 需要额外配置服务器负担服务器需要每次哀求都渲染页面,负担较重服务器仅需提供静态资源,前端通过路由渲染内容,负担较轻客户端路由客户端路由仅在页面加载后激活,通常会有客户端 JavaScript 初始化客户端路由在页面加载后就开始工作,页面内容动态更新复杂度相对复杂,涉及服务器渲染、数据获取、页面更新等多个方面相对简朴,前端控制整个应用,逻辑和状态在客户端处理 SSR:
- SEO 优化:由于页面是服务器端渲染的,搜索引擎能够直接抓取到完整的 HTML 内容,因此对 SEO 有较大资助。
- 更好的首屏加载体验:由于首屏已经是渲染好的 HTML,用户可以较快地看到内容,特别是对内容麋集型应用(如博客、消息网站等)非常有资助。
- 适合内容为主的应用:如博客、消息、广告等需要频繁更新且需要被搜索引擎抓取的应用。
- 服务器负担重:每次页面哀求时,服务器都需要天生完整的 HTML,大概导致服务器负担较重,尤其在高并发情况下。
- 开辟复杂度高:需要处理服务器端渲染和客户端交互的协调问题,配置和开辟过程相对 SPA 更为复杂。
SPA:
- 流畅的用户体验:用户在页面加载后,可以实现无革新操作,页面之间切换非常流畅,适合动态交互丰富的应用。
- 较低的服务器负担:服务器只需要提供静态资源,所有的交互都由前端处理,服务器负担较轻。
- 开辟体验好:开辟过程中,前后端开辟可以独立进行,前端完全控制应用逻辑和状态。
- SEO 挑战:由于内容是通过 JavaScript 渲染的,搜索引擎无法直接抓取到页面内容,需要额外配置(比方 SSR、Prerendering)来优化 SEO。
- 初次加载时间较长:由于需要加载 JavaScript 代码,初次加载页面的时间大概较长,用户看到的内容大概有延迟。
- 浏览器性能要求高:由于大部门逻辑都在客户端运行,浏览器性能不佳时大概导致应用运行缓慢。
- SSR 实用于需要较好 SEO 和更快首屏加载的应用,但其服务器负担较重,开辟相对复杂。
- SPA 更适合需要动态交互和快速响应的应用,但初次加载较慢,SEO 大概存在问题。
**SEO(Search Engine Optimization,搜索引擎优化)**是一种通过优化网站或网页内容,使其在搜索引擎中获得更高排名的技能和计谋。SEO 的目标是提高网站在搜索引擎结果页(SERP)中的可见性,从而吸引更多的自然流量。
静态站点天生 (Static-Site Generation,缩写为 SSG),也被称为预渲染,是另一种流行的构建快速网站的技能。如果用服务端渲染一个页面所需的数据对每个用户来说都是相同的,那么我们可以只渲染一次,提前在构建过程中完成,而不是每次哀求进来都重新渲染页面。预渲染的页面天生后作为静态 HTML 文件被服务器托管。
5.内置组件
1.KeepAlive组件
<KeepAlive> 是 Vue 提供的一个内置组件,用于 缓存组件的状态,避免组件在切换过程中重新渲染。它能够在组件切换时,保留组件的状态(包括 DOM 结构、数据等),使得在再次表现该组件时无需重新加载,保持前次的状态,从而提升用户体验和性能。<KeepAlive> 主要用于包裹动态组件(如v-if ,v-for,Tab 页切换和Vue路由 控制的组件)
作用:
缓存组件:通过 <KeepAlive>,可以缓存已经渲染过的组件,避免每次切换时重新渲染组件,减少不必要的盘算和 DOM 操作。
提高性能:当你有多个页面或多个视图组件时,用户在切换视图时不需要重新渲染整个页面,如许能显著减少性能开销。
保持组件状态:缓存组件的状态,比方输入框的内容、滚动位置、组件内部的动画状态等,这些都能保持在组件重新表现时,避免丢失。
KeepAlive 的主要特性
缓存多个组件: <KeepAlive> 答应多个组件同时被缓存,只要它们在 <KeepAlive> 中渲染过一次,就会保持在内存中。
条件缓存: <KeepAlive> 可以通过 include 和 exclude 属性,指定哪些组件需要缓存,哪些不需要缓存。
include:一个字符串或正则表达式,用于指定哪些组件应该被缓存。
exclude:一个字符串或正则表达式,用于指定哪些组件不应该被缓存。
- <template>
- <keep-alive :include="['ComponentA']" :exclude="['ComponentB']">
- <component :is="currentComponent"></component>
- </keep-alive>
- </template>
复制代码 生命周期钩子: 使用 <KeepAlive> 时,组件的生命周期会有一些差别之处,详细是 activated 和 deactivated 钩子:使用 <KeepAlive> 缓存的组件不会触发 created 或 mounted 等生命周期钩子,而会触发 activated 和 deactivated
- activated:当组件被缓存并恢复时(即被重新激活时)触发。
- deactivated:当组件被缓存并且失活时(即被切换出视图时)触发。
这两个生命周期钩子专门用于处理缓存组件的逻辑。可以在 activated 中启动某些操作,在 deactivated 中暂停或整理操作。
2.Teleport组件
<Teleport> 是 Vue 3 中引入的一个内置组件,用于 将组件的渲染输出传送到 DOM 树的其他位置。它可以将一个组件的内容渲染到 DOM 中指定的任何位置,而不是在当前组件树中渲染。它主要用于一些场景,好比模态框、弹出层、关照等,需要在文档的差别位置表现,但又需要保持在 Vue 组件的上下文中。确保它们的表现层级不会被父级组件的样式或结构影响。<Teleport> 就是为了解决这个问题,它答应你将组件的 DOM 输出传送到一个完全差别的位置,同时依然保持它在 Vue 的组件树中的状态和逻辑。
<Teleport> 组件有两个主要的属性:
- to:指定渲染目标的 DOM 元素。可以是一个选择器(如 #app)大概是一个 DOM 元素自己。
- v-if / v-show:可以控制何时渲染内容。
- <template>
- <div>
- <button @click="showModal = true">打开模态框</button>
- <Teleport to="body">
- <div v-if="showModal" class="modal">
- <div class="modal-content">
- <span @click="showModal = false" class="close">×</span>
- <p>这是一个模态框!</p>
- </div>
- </div>
- </Teleport>
- </div>
- </template>
- <script>
- export default {
- data() {
- return {
- showModal: false,
- };
- },
- };
- </script>
- <style>
- .modal {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: rgba(0, 0, 0, 0.5);
- display: flex;
- justify-content: center;
- align-items: center;
- }
- .modal-content {
- background: white;
- padding: 20px;
- border-radius: 5px;
- text-align: center;
- }
- .close {
- position: absolute;
- top: 10px;
- right: 10px;
- font-size: 20px;
- cursor: pointer;
- }
- </style>
复制代码 在这个例子中,模态框被渲染到 body 元素中,而不是本来父组件的位置。点击按钮会表现模态框,而模态框的 DOM 元素会直接插入到 body 中,而不是嵌套在组件的 DOM 树内。
- <template>
- <div>
- <button @click="toggleMessage">切换消息显示</button>
- <Teleport to="#notification-area">
- <div v-if="showMessage" class="notification">
- 这是一个通知消息!
- </div>
- </Teleport>
- <!-- 这个区域用于显示通知消息 -->
- <div id="notification-area"></div>
- </div>
- </template>
- <script>
- export default {
- data() {
- return {
- showMessage: false,
- };
- },
- methods: {
- toggleMessage() {
- this.showMessage = !this.showMessage;
- }
- }
- };
- </script>
- <style>
- .notification {
- background-color: #f0ad4e;
- color: white;
- padding: 10px;
- border-radius: 5px;
- margin-top: 10px;
- }
- </style>
复制代码 在这个例子中,关照消息会被传送到页面上一个名为 #notification-area 的地区,而不是放在当前组件的位置。每次点击按钮会在该地区表现或隐蔽关照。
<Teleport> 的工作原理
- 渲染目标:
<Teleport> 会通过其 to 属性指定一个 DOM 目标位置,组件的渲染内容会被插入到这个目标位置中。比方,可以是 body、#id 大概传入的 DOM 元素。
- 保持响应式:
尽管组件的 DOM 被移动到了文档的其他位置,但它仍旧保留 Vue 的响应式机制,保持组件的状态、事件处理、绑定等特性。以是,不管这个内容被渲染到哪里,数据和事件仍旧按照组件的逻辑工作。
- 生命周期:
通过 <Teleport> 渲染的内容依旧保持本来组件的生命周期钩子。比方,它的 mounted、updated、destroyed 等生命周期钩子会在其正常生命周期中触发。
- v-if 与 Teleport:
如果你使用 v-if 控制 <Teleport> 渲染的内容,当该内容被移除时,它会被从目标 DOM 移除,并且销毁相应的 Vue 组件实例。
- 保持 Vue 响应式:尽管组件的 DOM 被移动到了其他地方,Vue 仍旧会保持其响应式特性,数据、事件等都能正常工作。
- Vue 生命周期钩子:由于组件的 DOM 被插入到差别的地方,mounted 钩子会在目标位置的插入时触发,而 destroyed 会在移除时触发。
- CSS 样式:由于被传送到页面其他地方,某些组件的样式大概会受到影响。确保组件自己的样式可以独立或外部样式不会干扰其表现。
6.Proxy
在 Vue 3 中,Proxy 是核心特性之一,用于实现 响应式数据(reactivity)系统。Vue 3 使用 JavaScript 的 Proxy API 来替换 Vue 2 中的 Object.defineProperty 来进行数据代理。这使得 Vue 3 在响应式性能和易用性上都有了显著的提升。
Proxy 是 JavaScript 的一种新特性(在 ES6 中引入),它可以用来界说一个对象的代理。通过 Proxy,你可以拦截对对象的操作(如属性访问、修改、删除等),并界说自界说的举动。Proxy 的语法如下:
- let proxy = new Proxy(target, handler);
复制代码
- target:需要被代理的目标对象。
- handler:一个对象,用于界说拦截操作(比方 get、set、deleteProperty 等)。
在 Vue 3 中,响应式系统就是基于 Proxy 实现的。Vue 会通过 Proxy 来代理数据对象,捕获对数据的各种操作(如读取、修改、删除、赋值等),并主动更新视图。当数据发生变革时,Vue 会触发视图的更新,从而实现响应式。
Vue 3 Proxy 的主要功能
- 拦截属性访问(get):
当访问某个属性时,Proxy 会捕获到这个操作,并执行 get 钩子。Vue 会记录依赖(即哪些组件或盘算属性依赖于这个属性)。
- 拦截属性赋值(set):
当修改对象的某个属性时,Proxy 会捕获这个赋值操作,并执行 set 钩子。Vue 会在 set 钩子中触发视图更新。
- 拦截属性删除(deleteProperty):
当删除某个属性时,Proxy 会捕获这个操作,Vue 会处理相关的依赖更新。
- 拦截对象的其他操作:
好比操作对象的长度、遍历对象(for...in)等,Vue 会通过 Proxy 捕获并处理。
Vue 3 Proxy 工作原理
- 代理数据对象:
Vue 3 在初始化数据时,会将数据对象通过 Proxy 进行代理。代理后的对象会拦截对数据对象的访问,监控每个属性的变革。
- 依赖收集:
当组件访问某个数据属性时,Vue 会记录这个访问举动,标记该属性为该组件的依赖。如许,当数据发生变革时,组件就会重新渲染。
- 触发视图更新:
当数据属性被修改时,set 操作会被触发,Vue 会通过 Proxy 捕获到这个变革,并关照视图更新。它会关照所有依赖于这个数据的组件或盘算属性,进行重新渲染。
Proxy 与 Vue 2 的响应式系统对比
在 Vue 2 中,响应式系统是通过 Object.defineProperty 实现的。Object.defineProperty 会为每个属性界说 getter 和 setter,从而拦截对该属性的访问和修改。这种方式的缺点包括:
- 无法处理动态添加或删除的属性。
- 对数组等特殊类型的支持有限。
- 性能较差,尤其在大规模数据更新时。
而 Vue 3 使用 Proxy 解决了这些问题,Proxy 具有以下优势:
- 支持代理整个对象:Proxy 可以直接代理整个对象或数组,不需要为每个属性单独界说 getter 和 setter。
- 支持动态属性添加和删除:通过 Proxy,你可以直接添加或删除属性,Vue 会主动处理这些操作。
- 性能提升:Proxy 的性能比 Object.defineProperty 更好,尤其在大量数据更新的情况下。
Vue 3 中 Proxy 代理的数据对象的特点
- 响应式对象:使用 reactive 函数将对象转换为响应式对象后,这个对象会被 Proxy 代理,所有对它的操作都会被拦截和处理。
- 引用通报:Proxy 是基于引用的,意味着通过代理对象修改数据会影响到原始对象。
- 嵌套对象:Proxy 支持深度嵌套。当你访问嵌套对象时,Vue 会为嵌套对象中的每个属性都创建一个 Proxy 代理。
- const state = reactive({
- user: {
- name: "John",
- age: 30
- }
- });
- // 修改嵌套对象属性
- state.user.name = "Jane"; // 会触发 Proxy 的 `set` 方法
复制代码 在这个例子中,state.user 也是一个 Proxy 代理的对象。因此,当你修改 state.user.name 时,它会触发嵌套的 Proxy 的 set 操作。
Vue 3 Proxy 的性能优化:
- 懒代理:Vue 3 会对访问的对象或属性进行懒代理,只有在访问该对象或属性时,才会创建相应的 Proxy 代理。如允许以避免不必要的代理操作。
- 优化依赖收集:Vue 3 的响应式系统会智能地进行依赖收集和更新,确保只有真正依赖于某个属性的组件或盘算属性才会被重新渲染。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |