目录一、VUE2与VUE3的核心区别1.全局状态管理2.指令a). v-model3.组件引用4.API调用方式二、VUE31.全局状态管理2.指令a). v-model3.父子组件传值a).defineProps父传子参数b).defineEmits子传父事件4.ref、reactive、watchref作用reactive作用watch作用5.APIa).h()渲染函数一、VUE2与VUE3的核心区别1.全局状态管理state全局变量数据actions全局方法函数→全局方法就写这里Piniagetters全局计算属性特性Vue2 Vue.prototypePinia actions全局调用this.$xxxstore.xxx()响应式需手动赋值 nextTick自动响应一改全更新维护性分散、混乱集中在 store清晰异步麻烦原生支持 async/await2.指令a). v-modelVue 2 vs Vue 3 的区别特性Vue 2Vue 3默认 prop 名valuemodelValue默认事件名input/changeupdate:modelValue多个 v-model❌ 不支持✅ 支持自定义修饰符⚠️ 有限支持✅ 完整支持3.组件引用注册方式Vue2 (选项式)Vue3 (组合式 / script setup)全局注册Vue.component()app.component()局部注册components: { 子组件 }无需注册直接导入即用自动导入需插件 / 手动支持unplugin-auto-import自动导入组件入口文件main.js 用new Vue()main.js 用createApp()单文件组件必须写components选项直接导入就可以用最简洁4.API调用方式选项式 APIVue2 默认按功能类型拆分代码data、methods、computed...组合式 APIVue3 默认按业务逻辑拆分代码把相关的变量、方法放一起选项式 API(VUE2)组合式 API(VUE3script setup)上手难度简单适合新手稍难但更强大代码结构分散逻辑跳来跳去聚合清晰整洁复用逻辑mixin有缺陷自定义 hook优秀大型项目维护困难维护轻松TS 支持差极好代码体积较大更小利于 TreeShaking二、VUE31.全局状态管理在 Pinia 里全局方法就是写在actions里的函数所有组件都能调用而且可以改 state、可以异步、可以互相调用Pinia相比vue2更加的清晰功能上也更加全面。state全局变量数据actions全局方法函数→你要的全局方法就写这里Piniagetters全局计算属性示例import { defineStore } from pinia export const useSysStore defineStore(sys, { // 全局变量 state: () ({ sysname: 银行对账系统, }), // 全局方法写在这里 actions: { // 同步全局方法 setSysName(model) { }, // 异步全局方法例如请求后端再改名字 async fetchSysName() { const res await fetch(/api/sysname) const data await res.json() this.sysname data.name }, // 方法里调用另一个方法 resetAndSet(model) { this.$reset() // 重置state this.setSysName(model) } } })2.指令a). v-modelVue 3 允许通过参数绑定多个 v-model内置修饰符修饰符作用适用场景.lazy改为change事件触发减少频繁更新.number自动转为数字数字输入.trim去除首尾空格文本输入自定义修饰符Vue 3父组件使用template MyComponent v-model.capitalizemessage / /template子组件接收修饰符script setup langts interface Props { modelValue: string modelModifiers?: { capitalize?: boolean } } const props definePropsProps() const emit defineEmits{ (e: update:modelValue, value: string): void }() watchEffect(() { if (props.modelModifiers?.capitalize) { emit(update:modelValue, props.modelValue.toUpperCase()) } }) /script3.父子组件传值a).defineProps父传子参数Vue 组件是独立封闭的。子组件不能直接用父组件里的变量。想让子组件拿到父组件的数据必须通过 props 传递相当于父传子的数据通道。核心规则父 → 子 单向传递子不能改 props子组件用 defineProps 接收接收后可以直接在模板 / JS 里使用父组件数据变了子组件会自动更新响应式b).defineEmits子传父事件子组件不能直接改父组件的数据必须发一个事件让父组件接收。// 子组件 script setup // 1. 定义要发送的事件名 const emit defineEmits([sendMsg]) function sendToParent() { // 2. 发送事件 数据 emit(sendMsg, 我是子组件发来的消息) } /script template button clicksendToParent点我发给父组件/button /template父组件监听子组件发出的事件就能拿到值。script setup function getMsg(data) { console.log(收到子组件消息, data) } /script template !-- 监听子组件的 sendMsg 事件 -- Child sendMsggetMsg / /template4.ref、reactive、watchref用来定义简单类型数据数字、字符串、布尔reactive用来定义复杂类型数据对象、数组ref作用监听简单数据类型的响应式数字、字符串、布尔值script setup import { ref } from vue // 定义响应式变量 const count ref(0) const name ref(张三) const isShow ref(true) /script使用规则模板里不用 .valueJS 里必须用 .valuetemplate div{{ count }}/div !-- 不用 .value -- /template script setup console.log(count.value) // JS 里必须 .value count.value 100 /scriptreactive作用监听复杂数据类型的响应式对象、数组script setup import { reactive } from vue // 对象 const user reactive({ name: 李四, age: 20 }) // 数组 const list reactive([1,2,3]) /script使用规则永远不用 .value直接用属性即可template div{{ user.name }}/div /template script setup user.name 王五 /script常见问题reactive 不能直接重新赋值const user reactive({ name: 张三 }) // ❌ 错误会丢失响应式 user { name: 李四 } ✅ 正确 // 改属性 user.name 李四 // 或用 Object.assign Object.assign(user, { name: 李四 })对比表特性refreactive支持类型简单类型 对象 / 数组只能 对象 / 数组JS 访问必须 .value不用 .value模板访问不用 .value不用 .value重新赋值可以不推荐直接赋值使用场景单个变量对象、数组5.APIa).h()渲染函数创建虚拟 DOM 节点 (vnode)。详细信息第一个参数既可以是一个字符串 (用于原生元素) 也可以是一个 Vue 组件定义。第二个参数是要传递的 prop第三个参数是子节点。当创建一个组件的 vnode 时子节点必须以插槽函数进行传递。如果组件只有默认槽可以使用单个插槽函数进行传递。否则必须以插槽函数的对象形式来传递。为了方便阅读当子节点不是插槽对象时可以省略 prop 参数。