Vue3 中const的指南在 Vue 3 中const是 JavaScript 的关键字但在 Vue 的响应式系统中它有着特殊的使用方式和意义。下面我将详细解释const在 Vue 3 中的各种用法。一、const基础概念1.const的基本定义定义const是 JavaScript 中用于声明常量的关键字表示这个标识符不能被重新赋值。与let的区别const声明常量不可重新赋值let声明变量可以重新赋值// 使用 constconstPI3.14159// PI 3.14 // ❌ 错误不能重新赋值// 使用 letletcount0count1// ✅ 正确可以重新赋值2.const在 Vue 3 中的重要性Vue 3 的 Composition API 鼓励使用const来声明响应式数据因为提高代码可读性防止意外重新赋值配合响应式系统更安全二、const在 Vue 3 中的 6 种用法1.声明响应式数据ref/reactive定义使用const声明通过ref()或reactive()创建的响应式数据。3个示例示例1使用const声明 refscript setup import { ref } from vue // 基本类型使用 ref const count ref(0) // count 是常量但 count.value 可以修改 const message ref(Hello Vue 3) // 修改值 const increment () { count.value // ✅ 正确修改 .value // count ref(1) // ❌ 错误不能重新赋值 } console.log(count.value) // 访问 .value /script示例2使用const声明 reactivescript setup import { reactive } from vue // 对象类型使用 reactive const user reactive({ name: 张三, age: 25, email: zhangsanexample.com }) // 修改属性 const updateUser () { user.name 李四 // ✅ 正确可以修改属性 user.age 30 // user reactive({}) // ❌ 错误不能重新赋值 } /script示例3混合使用script setup import { ref, reactive } from vue // 混合声明 const isLoading ref(false) // 布尔值 const userInfo reactive({ // 对象 name: 张三, scores: [90, 85, 88] }) const apiUrl https://api.example.com // 真正的常量 // 使用方法 const fetchData async () { isLoading.value true try { const response await fetch(apiUrl) const data await response.json() Object.assign(userInfo, data) } finally { isLoading.value false } } /script2.声明计算属性定义使用const声明计算属性这些属性会根据依赖的响应式数据自动更新。3个示例示例1基本计算属性script setup import { ref, computed } from vue const price ref(100) const quantity ref(2) // 计算总价 const totalPrice computed(() { return price.value * quantity.value }) // 计算带税价格 const priceWithTax computed(() { return totalPrice.value * 1.1 }) console.log(totalPrice.value) // 200 /script示例2带 getter 和 setter 的计算属性script setup import { ref, computed } from vue const firstName ref(张) const lastName ref(三) // 可写的计算属性 const fullName computed({ // getter get() { return ${firstName.value} ${lastName.value} }, // setter set(newValue) { const [first, last] newValue.split( ) firstName.value first || lastName.value last || } }) // 使用 fullName.value 李 四 // 会调用 setter console.log(firstName.value) // 李 console.log(lastName.value) // 四 /script示例3基于对象属性的计算script setup import { reactive, computed } from vue const user reactive({ profile: { basicInfo: { age: 25, height: 175 }, education: { degree: 本科, school: 清华大学 } } }) // 计算是否成年 const isAdult computed(() { return user.profile.basicInfo.age 18 }) // 计算用户简介 const userDescription computed(() { return ${user.profile.education.degree}${user.profile.education.school} }) /script3.声明方法/函数定义使用const声明组件中的方法这些方法不会被重新赋值。3个示例示例1普通方法script setup import { ref } from vue const count ref(0) // 使用 const 声明方法 const increment () { count.value } const decrement () { if (count.value 0) { count.value-- } } const reset () { count.value 0 } /script示例2异步方法script setup import { ref } from vue const data ref(null) const loading ref(false) const error ref(null) // 异步方法 const fetchData async (url) { loading.value true error.value null try { const response await fetch(url) if (!response.ok) { throw new Error(HTTP错误: ${response.status}) } data.value await response.json() } catch (err) { error.value err.message } finally { loading.value false } } // 使用方法 const loadUserData () { fetchData(https://api.example.com/users) } /script示例3带参数的方法script setup import { reactive } from vue const formData reactive({ username: , password: , rememberMe: false }) // 表单处理方法 const handleSubmit (event) { event.preventDefault() console.log(提交数据:, formData) // 这里可以调用API } const handleReset () { formData.username formData.password formData.rememberMe false } // 带默认参数的方法 const showMessage (message 默认消息, type info) { console.log([${type}] ${message}) } /script4.声明组件引用ref/template ref定义使用const声明模板引用用于直接访问DOM元素或组件实例。3个示例示例1DOM元素引用template div input refinputRef typetext / button clickfocusInput聚焦输入框/button /div /template script setup import { ref, onMounted } from vue // 声明模板引用 const inputRef ref(null) const focusInput () { if (inputRef.value) { inputRef.value.focus() } } onMounted(() { // 组件挂载后自动聚焦 inputRef.value?.focus() }) /script示例2组件实例引用!-- ParentComponent.vue -- template div ChildComponent refchildRef / button clickcallChildMethod调用子组件方法/button /div /template script setup import { ref } from vue import ChildComponent from ./ChildComponent.vue // 引用子组件实例 const childRef ref(null) const callChildMethod () { if (childRef.value) { childRef.value.sayHello() // 调用子组件方法 } } /script!-- ChildComponent.vue -- script setup // 子组件暴露方法 const sayHello () { console.log(Hello from child component!) } // 使用 defineExpose 暴露方法 defineExpose({ sayHello }) /script示例3多个元素引用template div input refinputs[0] typetext / input refinputs[1] typetext / input refinputs[2] typetext / button clickfocusNext聚焦下一个输入框/button /div /template script setup import { ref } from vue // 使用数组存储多个引用 const inputs ref([]) let currentIndex 0 const focusNext () { if (inputs.value[currentIndex]) { inputs.value[currentIndex].blur() } currentIndex (currentIndex 1) % inputs.value.length if (inputs.value[currentIndex]) { inputs.value[currentIndex].focus() } } /script5.声明组件属性props定义在script setup中使用const声明 props通过defineProps定义。3个示例示例1基本属性定义!-- UserCard.vue -- template div classuser-card h3{{ name }}/h3 p年龄: {{ age }}/p p v-ifisAdmin管理员/p /div /template script setup // 使用 const 声明 props const props defineProps({ name: { type: String, required: true }, age: { type: Number, default: 18 }, isAdmin: { type: Boolean, default: false } }) // 在逻辑中使用 props const canEdit props.isAdmin || props.age 18 /script示例2使用 TypeScript 的类型标注script setup langts interface Props { title: string count?: number items: string[] onConfirm?: () void } // 使用 TypeScript const props definePropsProps() // 默认值 const { title 默认标题, count 0 } props /script示例3解构 propsscript setup // 解构 props const { name, age 20, // 提供默认值 isAdmin false } defineProps({ name: String, age: Number, isAdmin: Boolean }) // 直接使用解构后的变量 const userType isAdmin ? 管理员 : 普通用户 /script6.声明上下文emit/attrs/slots定义使用const声明组件的上下文如 emit、attrs、slots。3个示例示例1使用 emit!-- Counter.vue -- template div p计数: {{ count }}/p button clickincrement增加/button button clickdecrement减少/button button clickreset重置/button /div /template script setup import { ref } from vue // 定义 emit const emit defineEmits([increment, decrement, reset]) const count ref(0) // 触发事件 const increment () { count.value emit(increment, count.value) } const decrement () { if (count.value 0) { count.value-- emit(decrement, count.value) } } const reset () { count.value 0 emit(reset) } /script示例2使用 attrs 和 slots!-- CustomButton.vue -- template button v-bindattrs :classbuttonClass slot默认按钮/slot /button /template script setup import { computed, useAttrs, useSlots } from vue // 获取 attrs 和 slots const attrs useAttrs() const slots useSlots() // 根据是否有插槽添加样式 const buttonClass computed(() { return { has-icon: slots.icon, has-text: slots.default } }) /script style scoped .has-icon { display: flex; align-items: center; gap: 8px; } /style示例3完整的上下文使用!-- Modal.vue -- template div v-ifisVisible classmodal div classmodal-header slot nameheader h2{{ title }}/h2 /slot button clickclose×/button /div div classmodal-body slot/slot /div div classmodal-footer slot namefooter button clickconfirm确认/button button clickcancel取消/button /slot /div /div /template script setup import { ref, useAttrs, useSlots } from vue // 定义 props const props defineProps({ title: { type: String, default: 提示 }, visible: { type: Boolean, default: false } }) // 定义 emit const emit defineEmits([update:visible, confirm, cancel]) // 获取 attrs 和 slots const attrs useAttrs() const slots useSlots() // 内部状态 const isVisible ref(props.visible) // 方法 const close () { isVisible.value false emit(update:visible, false) } const confirm () { emit(confirm) close() } const cancel () { emit(cancel) close() } /script三、const的最佳实践1.何时使用const✅应该使用const的情况响应式数据ref()、reactive()计算属性computed()方法/函数组件引用导入的模块配置对象不会重新赋值的变量✅应该使用let的情况循环计数器需要重新赋值的变量条件语句中的临时变量2.代码示例对比好的实践script setup import { ref, computed } from vue // ✅ 使用 const const count ref(0) const doubleCount computed(() count.value * 2) const increment () { count.value } // ✅ 使用 let let timer null const startTimer () { timer setInterval(() { count.value }, 1000) } /script不好的实践script setup import { ref } from vue // ❌ 错误的用法 let count ref(0) // 可能被意外重新赋值 let increment () { // 方法不应该用 let count.value } /script3.常见误区误区1const声明的对象不能修改// ✅ 可以修改对象属性constuser{name:张三}user.name李四// 正确// user {} // 错误// ✅ 可以修改数组元素constnumbers[1,2,3]numbers.push(4)// 正确numbers[0]0// 正确// numbers [] // 错误误区2const声明的 ref 值不能修改script setup import { ref } from vue const count ref(0) count.value 1 // ✅ 正确修改 .value // count ref(1) // ❌ 错误重新赋值 /script四、高级技巧1.动态组件名template component :iscurrentComponent / /template script setup import { ref, shallowRef } from vue import ComponentA from ./ComponentA.vue import ComponentB from ./ComponentB.vue // 使用 shallowRef 避免不必要的深度响应 const currentComponent shallowRef(ComponentA) const switchComponent () { currentComponent.value currentComponent.value ComponentA ? ComponentB : ComponentA } /script2.组合式函数// useCounter.jsimport{ref,computed}fromvueexportfunctionuseCounter(initialValue0){constcountref(initialValue)constincrement(){count.value}constdecrement(){count.value--}constreset(){count.valueinitialValue}constdoublecomputed(()count.value*2)return{count,increment,decrement,reset,double}}script setup import { useCounter } from ./useCounter // 使用组合式函数 const { count, increment, double } useCounter(10) /script3.TypeScript 中的const断言script setup langts // 使用 as const 确保类型安全 const user { name: 张三, age: 25 } as const // 所有属性都是只读的 // user.name 李四 // ❌ 错误不能修改 // 路由配置示例 const routes [ { path: /, name: Home }, { path: /about, name: About } ] as const /script五、总结在 Vue 3 中const的使用建议总是使用const声明响应式数据除非真的需要重新赋值使用const声明方法和计算属性在script setup中优先使用const理解const只是防止重新赋值不防止修改对象属性速记口诀Vue3 开发用 const 响应数据不放过。 ref reactive computed 函数方法也适合。 组件引用模板用 属性定义不错过。 只有需要重赋值 let 才能来替换。通过合理使用const可以让你的 Vue 3 代码更加安全、可读和可维护。