? Vue3.x 全面教程指南:组合式 API 实践与 SSR 优化技巧解析
? 组合式 API 基础:从选项式到组合式的思维转变
1. 响应式数据:ref 与 reactive 的使用场景
- ref:用来创建单个响应式数据,不管是基本类型还是对象类型都能用。比如定义一个计数器:javascript
import { ref } from 'vue'; const count = ref(); function increment() { count.value++; }
注意这儿得通过.value来访问和修改值,在模板里直接用{{ count }}就行,不用额外处理。 - reactive:更适合处理对象类型的响应式数据,会深度响应式化对象的属性。像这样定义用户信息:javascript
import { reactive } from 'vue'; const user = reactive({ name: '张三', age: });
修改的时候直接user.name = '李四'就成,模板里也是直接用{{ user.name }}。
2. 计算属性与监听器:computed 和 watch 的新写法
computed 和 watch 和选项式里的功能一样,但写法更灵活。计算属性返回的是一个 ref 对象,监听器可以监听单个值或者多个值的变化。比如计算全名字段:
const fullName = computed(() => user.name + ' ' + user.lastName);
watch(
() => user.age,
(newAge, oldAge) => {
console.log(`年龄从 ${oldAge} 变成了 ${newAge}`);
}
);
3. 生命周期钩子:在 setup 中正确使用
vue 中导入,而且名称有变化,比如 mounted 变成了 onMounted。每个钩子函数在 setup 里直接调用就行,注意顺序和选项式里的生命周期顺序是一致的。import { onMounted, onUnmounted } from 'vue';
onMounted(() => {
console.log('组件挂载完成');
// 在这里做一些初始化操作
});
onUnmounted(() => {
console.log('组件卸载');
// 清理定时器、事件监听等
});
? 组合式 API 进阶:逻辑复用与代码组织技巧
1. 自定义组合函数:抽离可复用逻辑
// useUser.js
import { ref, onMounted } from 'vue';
export function useUser(userId) {
const userData = ref(null);
const error = ref(null);
onMounted(async () => {
try {
const response = await fetch(`/api/users/${userId}`);
userData.value = await response.json();
} catch (e) {
error.value = '获取用户数据失败';
}
});
return { userData, error };
}
import { useUser } from './useUser.js';
const { userData, error } = useUser();
2. 响应式依赖:理解 effect 的作用
effect 可以自动收集依赖,实现副作用的响应式执行。比如当响应式数据变化时,自动执行某些操作,像更新 DOM、记录日志等。import { effect, ref } from 'vue';
const count = ref();
effect(() => {
console.log(`count 的值是 ${count.value}`);
});
count.value = ; // 这时候控制台会输出新的值
3. 处理 props 和 emit:更清晰的参数传递
props,第二个是 context,里面包含 emit 方法。props 是响应式的,可以直接用 watch 监听变化,emit 事件时和选项式一样调用函数就行。export default {
props: { title: String },
setup(props, { emit }) {
const clickHandler = () => {
emit('custom-event', '传递的数据');
};
return { clickHandler };
}
};
? SSR 基础:为什么需要服务端渲染
1. SSR 的基本原理
2. 常用的 SSR 解决方案
- Nuxt.js:Vue 官方推荐的 SSR 框架,基于 Vue 开发,封装了很多 SSR 相关的配置和功能,比如路由处理、数据获取、静态资源管理等,使用起来比较简单,适合快速搭建 SSR 项目。
- Vue SSR 官方库:如果想自己配置 SSR 环境,可以用 Vue 提供的官方库
@vue/server-renderer,不过需要自己处理很多细节,比如服务器端的路由匹配、数据预取、错误处理等,适合有一定经验的开发者。
? 使用 Nuxt3 快速搭建 SSR 项目
1. 初始化项目
npx nuxi init my-ssr-project
cd my-ssr-project
npm install
pages 目录,里面的文件会自动生成路由,components 目录放组件,assets 放静态资源。2. 编写第一个 SSR 页面
pages/index.vue 里,咱们可以直接用组合式 API 编写组件。Nuxt3 支持在页面组件中使用 definePageMeta 定义页面元数据,比如标题、描述等,方便 SEO。<template>
<div>
<h1>欢迎来到我的 SSR 项目</h1>
<p>当前时间:{{ currentTime }}</p>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
const currentTime = ref('');
// 在服务器端渲染时,onMounted 不会执行,所以数据获取需要用 useAsyncData 或 useFetch
onMounted(() => {
updateTime();
setInterval(updateTime, );
});
const updateTime = () => {
currentTime.value = new Date().toLocaleTimeString();
};
</script>
onMounted,但在 SSR 场景下,这个钩子只在客户端执行,服务器端渲染时不会运行。所以如果需要在服务器端获取数据,得用 Nuxt3 提供的 useAsyncData 或 useFetch 函数。3. 在服务器端获取数据
useAsyncData 可以在服务器端和客户端都执行数据获取,并且会缓存结果。修改页面代码:<script setup>
import { ref } from 'vue';
const { data: currentTime } = useAsyncData('time', () => {
return new Date().toLocaleTimeString();
});
</script>
useAsyncData 第一个参数是键名,用于缓存数据,第二个参数是异步函数,返回数据。这样在服务器端渲染时,就会先获取数据,再生成 HTML,保证页面上显示的数据是服务器端获取的。?️ SSR 优化技巧:提升性能和用户体验
1. 数据预取与缓存
- 页面级数据预取:在进入页面之前,提前在客户端预加载数据。Nuxt3 提供了
useAsyncData的ssr选项,可以控制数据是否在服务器端获取。对于一些非必要在服务器端获取的数据,可以在客户端导航时预取。 - 缓存策略:对频繁访问但不经常变化的数据进行缓存,比如商品列表、文章内容等。可以用 Redis 等缓存工具,减少数据库查询次数,降低服务器压力。
2. 静态资源优化
- 压缩文件:对 CSS、JS、图片等静态资源进行压缩,减小文件体积。可以用
compression-webpack-plugin对打包后的文件进行压缩,图片可以用image-webpack-loader进行优化。 - CDN 加速:将静态资源部署到 CDN 上,利用 CDN 的分布式节点,加快用户访问速度。Nuxt3 可以通过配置
publicPath来指定静态资源的 CDN 地址。
3. 代码拆分与懒加载
- 路由级代码拆分:Nuxt3 会自动根据路由进行代码拆分,每个页面只加载对应的 JS 和 CSS 文件。但对于一些较大的组件,比如富文本编辑器、图表库等,可以使用
defineAsyncComponent进行懒加载,只有在组件使用时才加载对应的代码。
import { defineAsyncComponent } from 'vue';
const RichTextEditor = defineAsyncComponent(() => import('./RichTextEditor.vue'));
- 异步组件加载:对于不影响首屏显示的组件,比如弹窗里的内容、下拉菜单的选项等,都可以采用异步加载的方式,减少首屏加载的文件体积。
4. 服务器性能优化
- 负载均衡:当项目访问量较大时,单台服务器可能无法承受压力,这时候需要使用负载均衡技术,将请求分发到多个服务器上,提高系统的可用性和稳定性。
- 合理配置服务器:根据项目的实际需求,选择合适的服务器配置,比如 CPU、内存、硬盘等。同时,优化服务器的软件配置,比如 Nginx 的缓存策略、Node.js 的进程管理等。
? 常见问题解决:组合式 API 和 SSR 中的坑
1. 组合式 API 中组件实例的访问问题
this 指向组件实例,那怎么访问组件的属性和方法呢?其实可以通过 getCurrentInstance 函数获取当前组件实例,但要注意这只能在同步代码中使用,而且在 SSR 场景下要谨慎使用,避免出现服务端和客户端不一致的问题。import { getCurrentInstance } from 'vue';
const instance = getCurrentInstance();
console.log(instance.props); // 访问组件的 props
2. SSR 中的浏览器特定 API 问题
window 和 document 对象,如果代码中直接使用了这些 API,会导致服务器端报错。解决办法是在使用这些 API 之前,先判断是否在客户端环境。if (typeof window !== 'undefined') {
// 在这里使用浏览器特定的 API
const scrollPosition = window.scrollY;
}
3. 组合式 API 中响应式数据丢失问题
ref 还是 reactive 创建的响应式数据,直接返回就行,不要解包成普通值。比如上面的 useUser 函数,返回 { userData, error } 是正确的,如果返回 { userData: userData.value, error: error.value } 就会失去响应式。