文章目录
-
-
- [一、从 `vue` 核心库导入(最常用)](#一、从
vue
核心库导入(最常用)) - [二、从 `vue-router` 导入(路由相关)](#二、从
vue-router
导入(路由相关)) - [三、从 `pinia` 导入(状态管理相关)](#三、从
pinia
导入(状态管理相关)) - 四、其他常用导入场景
- 总结
- [一、从 `vue` 核心库导入(最常用)](#一、从
-
- 细节答疑
-
- ref
-
- [一、ref 的基本用法](#一、ref 的基本用法)
-
- [1. 导入 ref](#1. 导入 ref)
- [2. 创建响应式数据](#2. 创建响应式数据)
- [二、访问和修改 ref 数据](#二、访问和修改 ref 数据)
-
- [1. 在 `<script>` 中:必须加 `.value`](#1. 在
<script>
中:必须加.value
) - [2. 在 `<template>` 中:无需加 `.value`](#2. 在
<template>
中:无需加.value
)
- [1. 在 `<script>` 中:必须加 `.value`](#1. 在
- [三、ref 对引用类型的处理](#三、ref 对引用类型的处理)
- [四、ref 的核心特性](#四、ref 的核心特性)
- 五、常见使用场景
- 六、注意事项
- reactive
在 Vue3 开发中,基于组合式 API(尤其是 <script setup>
语法糖),有一些非常高频使用的 import
内容,主要来自 vue
核心库、vue-router
(路由)、pinia
(状态管理)等。以下是最常用的分类整理:
一、从 vue
核心库导入(最常用)
vue
库提供了 Vue3 的核心功能,几乎每个组件都会用到其中几个:
-
响应式相关
-
ref
:创建基本类型(数字、字符串、布尔等)的响应式数据(访问时需加.value
,模板中不用)。javascriptimport { ref } from 'vue' const count = ref(0) // 响应式数字
-
reactive
:创建对象/数组的响应式数据(直接修改属性即可)。javascriptimport { reactive } from 'vue' const user = reactive({ name: '张三' })
-
computed
:创建计算属性(依赖其他响应式数据,自动缓存结果)。javascriptimport { computed } from 'vue' const doubleCount = computed(() => count.value * 2)
-
toRefs
:将reactive
创建的响应式对象,转换为多个ref
(方便解构时保持响应式)。javascriptimport { reactive, toRefs } from 'vue' const user = reactive({ name: '张三', age: 18 }) const { name, age } = toRefs(user) // 解构后仍为响应式
-
-
生命周期钩子
组件不同阶段执行的函数,常用的有:
onMounted
:组件挂载到 DOM 后执行(类似 Vue2 的mounted
)。onUpdated
:组件更新后执行(类似 Vue2 的updated
)。onUnmounted
:组件卸载时执行(类似 Vue2 的beforeDestroy
+destroyed
)。
javascriptimport { onMounted, onUnmounted } from 'vue' onMounted(() => { console.log('组件挂载完成') }) onUnmounted(() => { console.log('组件卸载了') })
-
模板相关工具
-
watch
:监听响应式数据变化(类似 Vue2 的watch
)。javascriptimport { watch, ref } from 'vue' const count = ref(0) watch(count, (newVal, oldVal) => { console.log(`从 ${oldVal} 变成了 ${newVal}`) })
-
watchEffect
:自动追踪依赖,依赖变化时执行(更简洁的watch
)。javascriptimport { watchEffect, ref } from 'vue' const count = ref(0) watchEffect(() => { console.log(`count 变了:${count.value}`) // 自动监听 count })
-
defineProps
:子组件接收父组件传递的属性(无需导入,<script setup>
中直接可用,但 TypeScript 中可能需要配合withDefaults
)。 -
defineEmits
:子组件定义要触发的事件(同上,直接可用)。
-
二、从 vue-router
导入(路由相关)
当项目使用 Vue Router 管理页面跳转时,常用以下导入:
-
路由跳转与信息
-
useRouter
:获取路由实例,用于编程式导航(如跳转页面)。javascriptimport { useRouter } from 'vue-router' const router = useRouter() router.push('/about') // 跳转到 about 页面
-
useRoute
:获取当前路由信息(如路径、参数)。javascriptimport { useRoute } from 'vue-router' const route = useRoute() console.log(route.path) // 当前路径,如 /home console.log(route.params.id) // 路由参数,如 /user/:id 中的 id
-
-
路由组件
RouterLink
:声明式导航组件(替代<a>
标签,避免页面刷新)。RouterView
:路由出口(显示当前匹配的页面组件)。
vue<template> <RouterLink to="/home">首页</RouterLink> <RouterView /> <!-- 页面内容在这里显示 --> </template> <script setup> import { RouterLink, RouterView } from 'vue-router' </script>
三、从 pinia
导入(状态管理相关)
当项目用 Pinia 管理全局状态时,常用以下导入:
-
创建与使用 Store
-
defineStore
:定义一个 Store(全局状态容器)。javascript// src/stores/counter.js import { defineStore } from 'pinia' export const useCounterStore = defineStore('counter', { state: () => ({ count: 0 }), actions: { increment() { this.count++ } } })
-
在组件中导入并使用定义好的 Store:
javascriptimport { useCounterStore } from '@/stores/counter' // 路径根据实际情况调整 const counterStore = useCounterStore() counterStore.increment() // 调用 Store 中的方法
-
-
辅助函数
-
storeToRefs
:将 Store 中的状态转换为ref
(解构时保持响应式)。javascriptimport { storeToRefs } from 'pinia' const { count } = storeToRefs(counterStore) // 解构后 count 仍为响应式
-
四、其他常用导入场景
-
导入组件
在父组件中使用子组件时,需要先导入:
vue<template> <ChildComponent /> </template> <script setup> import ChildComponent from './ChildComponent.vue' // 从相对路径导入 </script>
-
导入工具函数/常量
项目中封装的工具类(如格式化时间、接口请求):
javascriptimport { formatTime } from '@/utils/date' // 从 utils 文件夹导入工具函数 import { API_BASE_URL } from '@/constants' // 导入常量
-
导入第三方库
如 axios(网络请求)、lodash(工具函数库)等:
javascriptimport axios from 'axios' // 导入 axios import { debounce } from 'lodash' // 从 lodash 导入防抖函数
总结
新手高频接触的导入主要集中在:
vue
核心:ref
、reactive
、computed
、onMounted
、watch
等(响应式与生命周期)。vue-router
:useRouter
、useRoute
、RouterLink
、RouterView
(路由相关)。pinia
:defineStore
、useXXXStore
(全局状态)。
这些是 Vue3 开发的"基础工具",用多了自然就熟悉了。记住:按需导入是核心思想,用到什么就导入什么,避免冗余。
细节答疑
ref
ref
是vue3
当中最常用的响应式API之一,用于创建基本类型(如数字、字符串、布尔值)或引用类型的响应式数据。
ref
是 Vue3 组合式 API 中最常用的响应式 API 之一,用于创建基本类型(如数字、字符串、布尔值等)或引用类型的响应式数据。它的核心作用是让数据"可响应"------当数据变化时,依赖该数据的视图会自动更新。
一、ref 的基本用法
1. 导入 ref
首先需要从 vue
中导入 ref
:
javascript
import { ref } from 'vue'
2. 创建响应式数据
用 ref()
包裹初始值,即可创建响应式数据:
javascript
// 基本类型(数字、字符串、布尔)
const count = ref(0) // 数字
const message = ref('Hello') // 字符串
const isActive = ref(false) // 布尔值
// 引用类型(对象、数组,虽然推荐用 reactive,但 ref 也支持)
const user = ref({ name: '张三' }) // 对象
const list = ref([1, 2, 3]) // 数组
二、访问和修改 ref 数据
1. 在 <script>
中:必须加 .value
ref
会将数据包装成一个带有 value
属性的对象 ,因此在脚本中访问或修改时,需要通过 .value
:
javascript
import { ref } from 'vue'
const count = ref(0)
// 访问值
console.log(count.value) // 输出:0
// 修改值(触发响应式更新)
count.value++ // 此时 count.value 变为 1,视图会自动更新
2. 在 <template>
中:无需加 .value
Vue 会自动解析 ref
的 value
属性,因此在模板中直接使用变量名即可:
vue
<template>
<div>
<p>当前计数:{{ count }}</p> <!-- 直接用 count,不用 .value -->
<button @click="count++">加 1</button> <!-- 修改也不用 .value -->
</div>
</template>
<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>
三、ref 对引用类型的处理
虽然 ref
主要用于基本类型,但也可以处理对象/数组等引用类型。此时:
ref
会自动将引用类型转换为reactive
响应式对象(内部调用reactive
)。- 访问/修改时,依然通过
.value
访问外层,但修改内部属性时不需要额外处理:
javascript
import { ref } from 'vue'
const user = ref({ name: '张三', age: 18 })
// 访问对象属性
console.log(user.value.name) // 输出:张三
// 修改对象属性(直接改,无需再 .value)
user.value.name = '李四' // 视图会更新
// 数组操作
const list = ref([1, 2, 3])
list.value.push(4) // 数组新增元素,视图更新
console.log(list.value) // 输出:[1,2,3,4]
四、ref 的核心特性
-
响应式触发 :当
ref.value
被修改时,所有依赖该数据的地方(模板、computed
、watch
等)都会自动更新。 -
自动解包:
-
在模板中自动解析
value
(无需.value
)。 -
在
reactive
对象中,如果属性是ref
,会自动解包(无需.value
):javascriptconst info = reactive({ count: ref(0) // ref 作为 reactive 的属性 }) console.log(info.count) // 直接访问,无需 .value,输出 0 info.count++ // 直接修改,触发响应式
-
-
与普通变量的区别:
- 普通变量:
let count = 0
,修改后视图不会更新。 - ref 变量:
const count = ref(0)
,修改count.value
后视图自动更新。
- 普通变量:
五、常见使用场景
-
存储基本类型数据:如计数器、表单输入值、开关状态等。
vue<template> <input v-model="username" placeholder="输入用户名"> <p>你输入的是:{{ username }}</p> </template> <script setup> import { ref } from 'vue' const username = ref('') // 初始为空字符串,v-model 双向绑定 </script>
-
临时存储引用类型 :虽然推荐用
reactive
处理对象/数组,但在某些场景下(如从接口获取数据后暂存),ref
更简洁:javascriptimport { ref, onMounted } from 'vue' import axios from 'axios' const userInfo = ref(null) // 初始为 null onMounted(async () => { const res = await axios.get('/api/user') userInfo.value = res.data // 接口数据赋值给 ref })
六、注意事项
-
不要解构
ref
变量 :直接解构会丢失响应式(如需解构,用toRefs
):javascriptconst count = ref(0) const { value: c } = count // 错误:c 是普通变量,修改后不触发更新
-
区分
ref
和reactive
:- 基本类型优先用
ref
(更直观)。 - 复杂对象/数组优先用
reactive
(无需.value
操作内部属性)。
- 基本类型优先用
总结:ref
是 Vue3 中创建响应式数据的"基础工具",核心是通过 .value
访问/修改(脚本中),模板中自动解包,适合处理基本类型和临时引用类型数据。多写几个小案例(如计数器、表单输入)就能快速掌握~
reactive
在 Vue3 中,reactive
是一个核心的响应式 API,用于将对象或数组转换为响应式数据。当响应式数据发生变化时,依赖该数据的组件会自动重新渲染,这是 Vue 响应式系统的重要组成部分。
核心作用
将普通对象/数组包装成"响应式代理对象",使得对象的属性读写、新增、删除,或数组的元素修改、方法调用(如 push
、splice
等)都能被 Vue 追踪,从而触发视图更新。
基本用法
javascript
import { reactive } from 'vue'
// 将普通对象转为响应式对象
const user = reactive({
name: '张三',
age: 20
})
// 将普通数组转为响应式数组
const list = reactive([1, 2, 3])
特点与注意事项
1. 只对对象/数组有效
reactive
只能处理对象或数组 (引用类型),如果传入基本类型(如字符串、数字、布尔值),会返回原数据且不具备响应性。
👉 基本类型需用 ref
处理(ref
内部会通过 reactive
包装基本类型为对象)。
2. 直接修改属性即可触发响应
无需像 Vue2 的 this.$set
那样手动触发更新,直接修改属性或调用数组方法即可:
javascript
// 修改对象属性
user.name = '李四' // 触发响应,视图更新
// 调用数组方法
list.push(4) // 触发响应,视图更新
// 直接修改数组元素
list[0] = 100 // 触发响应,视图更新
3. 响应式是"深层"的
reactive
会递归地将对象的所有嵌套属性都转为响应式,无论嵌套多深,修改内层属性都会触发更新:
javascript
const obj = reactive({
a: 1,
b: {
c: 2,
d: { e: 3 }
}
})
obj.b.d.e = 4 // 深层修改,依然触发响应
4. 不能直接替换整个对象
如果直接用一个新对象替换响应式对象,会丢失响应性(因为新对象没有被 reactive
包装):
javascript
let user = reactive({ name: '张三' })
user = { name: '李四' } // 错误!新对象不是响应式的,修改不会触发更新
👉 解决方案:在对象内部嵌套一层,修改内层属性:
javascript
const state = reactive({
user: { name: '张三' } // 嵌套对象
})
state.user = { name: '李四' } // 正确,修改的是响应式对象的属性
5. 解构会丢失响应性
直接解构响应式对象的属性,得到的值是普通值(非响应式):
javascript
const user = reactive({ name: '张三', age: 20 })
const { name } = user // name 是普通字符串,修改 name 不会触发更新
name = '李四' // 无效,视图不更新
👉 解决方案:用 toRefs
将响应式对象转为 ref
对象集合,再解构:
javascript
import { reactive, toRefs } from 'vue'
const user = reactive({ name: '张三', age: 20 })
const { name } = toRefs(user) // name 是 ref 对象
name.value = '李四' // 有效,触发视图更新
与 ref
的区别
特性 | reactive |
ref |
---|---|---|
处理类型 | 仅对象/数组(引用类型) | 基本类型 + 对象/数组 |
访问方式 | 直接访问属性(user.name ) |
通过 .value 访问(name.value ) |
解构特性 | 直接解构丢失响应性 | 用 toRefs 解构保持响应性 |
适用场景
- 当需要处理复杂对象或数组 (如表单数据、列表数据)时,优先使用
reactive
,结构更清晰。 - 配合
toRefs
可以在保持响应性的同时,方便地解构使用对象属性。
例如,管理一个表单的多字段数据:
javascript
const form = reactive({
username: '',
password: '',
remember: false
})
// 直接修改属性即可响应
form.username = 'admin'
总结:reactive
是 Vue3 中处理引用类型响应式数据的核心 API,通过代理对象实现数据变化的追踪,是构建响应式组件状态的重要工具。