vue3超详细教学(傻瓜版)百万字超详细-脚本语法
一、组合式 API:从 "东拼西凑" 到 "整装待发"
代码展示(两种写法对比)
▼javascript复制代码// 写法1:标准setup选项式 <script> import { ref } from "vue"; export default { setup() { const message = ref('Hello'); const sayHi = () => { console.log(message.value); }; return { message, sayHi }; } }; </script> // 写法2:<script setup>语法糖(推荐) <script setup> import { ref } from "vue"; const message = ref('Hello'); const sayHi = () => { console.log(message.value); }; </script>
容讲解
1. 导入语句 import { ref } from "vue";
- 梗版:这就像炒菜前先从冰箱拿鸡蛋 ——
ref是 Vue 牌 "响应式鸡蛋",你不把它拿出来(import),就做不了 "响应式番茄炒蛋",总不能用石头炒菜吧? - 专业版:从 Vue 核心库中导入
ref函数,ref是创建响应式数据的基础工具,所有需要使用响应式变量的组件都必须先导入它。
2. 数据定义 const message = ref('Hello');
- 梗版:
ref('Hello')相当于给 "message" 这个盒子贴了 "自动更新" 标签 —— 你往盒子里塞纸条(改值),客厅的公告栏(页面)会自动同步内容,不用你跑过去重贴,比小区物业勤快多了。 - 专业版:使用
ref函数创建响应式字符串变量,初始值为 'Hello'。ref会将基本类型数据包装成包含value属性的响应式对象,确保数据变化时触发视图自动更新。
3. 函数定义 const sayHi = () => { console.log(message.value); };
- 梗版:这是个 "说话机器人" 的说明书 —— 你按一下按钮(调用函数),机器人就会打开盒子(.value)拿出纸条(message),把内容念出来(console.log)。记住一定要让机器人打开盒子,不然它念的是盒子本身,谁听得懂啊?
- 专业版:定义箭头函数
sayHi,函数内部通过message.value访问ref变量的实际值(脚本环境中必须通过.value访问ref包装的数据),并将其打印到控制台。
4. return 语句(仅写法 1 需要)
- 梗版:写法 1 就像寄快递 —— 你得把盒子和机器人(变量和函数)装进快递盒(return),填好单(export default),前台(模板)才能收到;写法 2 是 "京东到家" 服务,直接送货上门,不用你动手打包。
- 专业版:
setup函数返回的对象会将变量和函数暴露给模板,模板中可直接使用这些成员。<script setup>语法糖会自动暴露所有顶层声明的变量和函数,无需手动 return,大幅简化代码。
为什么这么写?
- 梗版:写法 2 就像用智能手机 —— 不用按一堆复杂按键(export default、return),点一下就搞定;写法 1 像老式诺基亚,功能一样但步骤多,现在谁还愿意用啊?
- 专业版:
<script setup>是 Vue3 为优化组合式 API 推出的语法糖,通过编译时转换自动处理变量暴露、导入导出等逻辑,减少模板代码,提升开发效率,同时保持响应式特性不变,是官方推荐的首选写法。
练习题
题目:用<script setup>写一个计数器,点击按钮数字加 1,显示在页面上。
答案:
▼javascript复制代码<script setup> import { ref } from "vue"; // 定义计数器变量,初始值0 const count = ref(0); // 定义加1函数 const addCount = () => { count.value++; // 脚本中必须加.value才能修改 }; </script> <template> <div>{{ count }}</div> <!-- 模板中直接用变量名 --> <button @click="addCount">点我加1</button> </template>
二、响应式语法:ref 和 reactive 的 "魔法盒子"
代码展示
▼javascript复制代码<script setup> import { ref, reactive } from "vue"; // ref示例(任意类型) const age = ref(18); // 数字 const name = ref('张三'); // 字符串 const user = ref({ height: 180 }); // 对象 const hobbies = ref(['打游戏', '睡觉']); // 数组 // reactive示例(仅对象/数组) const student = reactive({ id: 1, score: 90 }); const classList = reactive([ { name: '小明' }, { name: '小红' } ]); </script>
内容讲解
1. const age = ref(18);
- 梗版:这是个 "数字魔法盒"—— 你偷偷把 18 改成 19(age.value = 19),盒子会自动群发消息 "我现在 19 啦",所有用到它的地方(页面)都会收到通知更新,比小区广场舞喇叭还灵。
- 专业版:
ref函数创建响应式数字变量,初始值为 18。ref内部会创建一个包含value属性的代理对象,通过.value访问和修改原始值,当值变化时自动触发依赖更新。
2. const user = ref({ height: 180 });
- 梗版:这是个 "对象魔法盒",里面装着 "身高 180" 的小纸条 —— 想改身高得先打开盒子(user.value),再找到身高纸条(.height)改成 185,改完盒子会自动广播新身高,楼下广告牌(页面)马上更新。
- 专业版:
ref也可包装对象类型数据,修改对象属性时需通过user.value.height访问,Vue 会深度监听对象内部属性变化,确保响应式生效。
3. const student = reactive({ id: 1, score: 90 });
- 梗版:这是个 "对象专用保险柜"—— 只能存对象(存单个数字会报错,就像用冰箱装一头大象,门都关不上)。改成绩直接拧开锁(student.score = 95),不用先拆包装(.value),比
ref少一步。 - 专业版:
reactive函数专门用于创建对象 / 数组类型的响应式数据,返回原始对象的 Proxy 代理,直接修改属性即可触发响应,无需通过.value访问,语法更简洁。
为什么这么写?
- 梗版:
ref是 "万能保鲜盒"(装啥都行),reactive是 "便当盒"(只装套餐)。平时带饭(开发)优先用万能盒,啥都能装还方便;知道肯定带套餐(对象)才用便当盒。 - 专业版:
ref适用范围更广(支持所有数据类型),且支持整体替换值(age.value = 20);reactive对对象操作更简洁,但无法直接替换整个对象(会丢失响应性),推荐优先使用ref。
练习题
题目:用 ref 定义一个数组fruits,初始值为 “苹果 ', ' 香蕉 '],写一个函数添加 ' 橙子 ' 到数组,在页面显示数组。
答案:
▼javascript复制代码<script setup> import { ref } from "vue"; const fruits = ref(['苹果', '香蕉']); const addFruit = () => { fruits.value.push('橙子'); // 数组操作需通过.value访问 }; </script> <template> <ul> <li v-for="fruit in fruits" :key="fruit">{{ fruit }}</li> </ul> <button @click="addFruit">加橙子</button> </template>
三、computed 计算属性:自动算账的 "小会计"
代码展示
▼javascript复制代码<script setup> import { ref, computed } from "vue"; const list = ref([1, 2, 3, 4, 5, 6]); // 计算偶数之和 const evenSum = computed(() => { return list.value.filter(n => n % 2 === 0).reduce((a, b) => a + b, 0); }); </script> <template> <div>原数组:{{ list }}</div> <div>偶数和:{{ evenSum }}</div> </template>
内容讲解
1. const evenSum = computed(() => { ... })
- 梗版:这是雇了个 "兼职会计"—— 你每天给他一张数字列表(list),他自动算出偶数的总和(evenSum)写在黑板上。如果列表加了个 8,他会立刻重算,不用你催,比楼下算账总出错的小卖部老板靠谱多了。
- 专业版:
computed函数接收一个计算函数作为参数,返回一个只读的响应式计算属性。当依赖的list变化时,evenSum会自动重新计算,且结果会被缓存(多次访问不会重复计算),提升性能。
2. 计算逻辑 list.value.filter(...)
- 梗版:会计先从盒子里拿出列表(list.value),挑出偶数(filter (n => n%2=0)),再把它们加起来(reduce),最后把结果写在黑板上(return)。整个过程全自动,你只管看结果就行。
- 专业版:通过
list.value访问响应式数组,使用filter方法筛选偶数,reduce方法计算总和,最终返回计算结果。由于依赖list这个响应式变量,其变化会触发evenSum重新计算。
为什么这么写?
- 梗版:如果不用 computed,你每次改完列表都得自己算一遍,就像买菜每次都手动算总价 —— 累不说,还容易算错(上次买 3 样东西算成 5 样的就是你吧?),交给会计(computed)省心又准确。
- 专业版:计算属性用于处理衍生数据,相比直接在模板中写复杂表达式,更易维护、可复用,且具备缓存机制(只有依赖变化时才重新计算),性能优于直接在模板中计算。
练习题
题目:用 computed 计算数组中大于 5 的数字的个数。
答案:
▼javascript复制代码<script setup> import { ref, computed } from "vue"; const numbers = ref([3, 7, 2, 8, 5, 10]); const countGreaterThan5 = computed(() => { return numbers.value.filter(n => n > 5).length; }); </script> <template> 大于5的数字有{{ countGreaterThan5 }}个 </template>
四、watch 监听器:数据变化的 "报警器"
代码展示
▼javascript复制代码<script setup> import { ref, watch } from "vue"; const count = ref(0); const name = ref('张三'); // 监听单个变量 watch(count, (newVal, oldVal) => { console.log(`count从${oldVal}变成了${newVal}`); }); // 监听多个变量 watch([count, name], ([newCount, newName], [oldCount, oldName]) => { console.log(`count变了:${oldCount}→${newCount}`); console.log(`name变了:${oldName}→${newName}`); }); </script>
内容讲解
1. 监听单个变量 watch(count, (newVal, oldVal) => { ... })
- 梗版:给 count 装了个 "智能报警器"—— 只要 count 变了(比如从 0 到 1),报警器就滴滴响(执行函数),还会语音播报 "之前是 0,现在是 1"(newVal 和 oldVal),比你家猫看到老鼠还敏感。
- 专业版:
watch函数第一个参数是要监听的响应式变量(count),第二个参数是回调函数,接收新值(newVal)和旧值(oldVal),当被监听变量变化时自动执行回调。
2. 监听多个变量 watch([count, name], ([newCount, newName], ...) => { ... })
- 梗版:这是 "联动报警器"—— 同时盯着 count 和 name,不管哪个变了都报警,还会按顺序报出每个变量的新旧值(就像快递到了,快递员会按顺序念每个包裹的信息),绝不漏报。
- 专业版:当第一个参数为数组时,
watch可同时监听多个响应式变量。回调函数的第一个参数是新值数组,第二个是旧值数组,其顺序与监听数组一致,任何一个变量变化都会触发回调。
为什么这么写?
- 梗版:就像家里的烟雾报警器 —— 平时安安静静,着火(数据变化)了才工作,总不能你每隔 5 分钟自己去闻闻有没有烟(手动检查数据)吧?那也太费人了。
- 专业版:
watch用于处理数据变化时的副作用(如日志记录、数据请求、DOM 操作等),适合需要在数据变化后执行异步或复杂逻辑的场景,弥补了计算属性无法处理副作用的不足。
练习题
题目:监听password变量,当长度小于 6 时,在控制台打印 "密码太短"。
答案:
▼javascript复制代码<script setup> import { ref, watch } from "vue"; const password = ref(''); watch(password, (newVal) => { if (newVal.length < 6) { console.log('密码太短'); } }); </script> <template> <input v-model="password" placeholder="输入密码"> </template>
总结:笑着学 Vue3
记住:学 Vue3 就像学骑自行车 —— 刚开始总摔(忘了加.value、没导入 ref),但摔几次就会了。这些响应式、计算属性、监听器看着复杂,其实就是帮你偷懒的工具 —— 让代码自己干活,你躺着喝咖啡就行。
下次我们继续拆解生命周期和组件通信,保证还是笑着学,绝不枯燥!
评论
问答助学
相关内容
0个评论
全部评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论

