Vue3超详细教学(傻瓜版)百万字超详细-基础知识

一、核心指令:Vue 的 "万能工具箱"

Vue 的指令就像给 HTML 加了 "魔法 buff",让静态页面瞬间变动态 —— 不用写复杂 JS 操作 DOM,一个指令就能实现绑定、循环、显示隐藏等功能。下面逐个拆解,用 "梗 + 专业" 双模式讲透!

二、数据绑定三剑客:v-model + 插值显示

2.1 代码展示

javascript
复制代码
<script setup> import {ref} from "vue"; let name = ref('') // 定义一个字符串变量 </script> <template> <input v-model="name" type="text"> // 将输入框的输入内容绑定到变量 name <div>{{ name }}</div> // 使用插值方法,显示变量的值 </template>

2.2 梗版拆解

这俩组合就是 "输入框的回声机"—— 你在输入框里敲啥,下面的 div 就重复啥!

  • let name = ref(''):给 "回声机" 装了个空的 "存储盒",专门存输入的内容;

  • v-model="name":给输入框绑了根 "数据线",输入的内容实时传到 "存储盒" 里;

  • {{ name }}:给 div 装了个 "显示器",实时显示 "存储盒" 里的内容。

    比如你输入 "张三",输入框传数据到name,div 马上显示 "张三",比回声还快!

2.3 专业版拆解

  • ref(''):Vue3 组合式 API 的响应式变量创建方法,ref包裹的变量会变成 "响应式对象"—— 值变化时,依赖它的 DOM 会自动更新(即 "响应式渲染");
  • v-model:双向数据绑定指令,本质是value属性绑定 +input事件监听的语法糖,等价于:
html
复制代码
<input :value="name" @input="name = $event.target.value">
  • 实现 "输入框值变→变量变→页面显示变" 的双向同步;
  • 插值显示{{ name }}:Mustache 语法,用于将响应式变量的值插入到 DOM 中,支持简单表达式(如{{ name + '你好' }}),但不支持复杂逻辑(如循环、条件判断)。

.4 实际用法扩展

  • 适用场景:表单输入(输入框、单选框、复选框)、实时预览(如评论输入框实时显示字数);
  • 注意:v-model在不同表单元素上的绑定逻辑不同 —— 输入框绑定value,复选框绑定checked,下拉框绑定selected,但 Vue 会自动适配,不用手动处理。

三、显示隐藏开关:v-show

3.1 核心逻辑

梗版拆解

v-show就是页面元素的 "电灯开关"—— 接个布尔值(true/false),开(true)就亮(显示),关(false)就灭(隐藏)。

比如给 div 加v-show="isShow"isShow为 true 时 div 正常显示,为 false 时 div 会被加style="display: none"(相当于关灯,元素还在 DOM 里,只是看不见)。

专业版拆解

  • 作用:根据布尔值控制元素的显示 / 隐藏,本质是通过修改元素的displayCSS 属性实现(truedisplay: block/inlinefalsedisplay: none);
  • 特点:元素始终存在于 DOM 中,切换时仅修改样式,适合频繁切换显示状态的场景(如 tabs 切换),性能开销小;
  • 对比后续v-ifv-show是 "隐藏",v-if是 "销毁 / 创建",频繁切换用v-show,偶尔切换用v-if

四、循环渲染神器:v-for

4.1 代码展示

javascript
复制代码
<script setup> import { ref } from 'vue' let list = ref(['苹果', '香蕉', '橙子']) </script> <template> <ul> <li v-for="(item, index) in list" :key="index"> <strong> {{ item }}</strong> <div> {{index}} </div> </li> </ul> </template>

4.2 梗版拆解

v-for就是 Vue 的 "自动生产线",把列表里的每个元素做成一个相同的 "零件"(li):

  • (item, index) in list:生产线的 "原料配方"——item是每个元素(比如 "苹果"),index是元素的 "编号"(0、1、2);
  • :key="index":给每个零件贴个 "身份证号",Vue 靠这个识别元素,避免重复或错乱(比如删除一个元素时,Vue 知道该删哪个);
  • 最终生产线会造出 3 个 li,分别显示 "苹果(0)"、"香蕉(1)"、"橙子(2)"。

4.3 专业版拆解

  • 语法格式v-for="(item, index) in 可迭代对象",可迭代对象包括数组、对象、字符串、数字;
  • itemindexitem是迭代的当前元素,index是可选参数(当前元素的索引,从 0 开始);
  • :key的作用:Vue 的虚拟 DOM Diff 算法依赖key识别元素的唯一性,避免 "就地复用" 导致的渲染错误,推荐用唯一标识(如接口返回的id)作为key,而非indexindex会随列表操作变化,可能引发问题);
  • 迭代对象扩展
    • 迭代对象:v-for="(value, key) in user"user是对象,key是属性名,value是属性值);
    • 迭代数字:v-for="n in 5"(生成 5 个元素,n 从 1 到 5)。

4.4 练习题

题目:用 v-for 循环渲染一个对象user = ref({name: '张三', age: 18, gender: '男'}),显示属性名和对应值。

答案:

javascript
复制代码
<script setup> import { ref } from 'vue' let user = ref({name: '张三', age: 18, gender: '男'}) </script> <template> <div v-for="(value, key) in user" :key="key"> {{ key }}: {{ value }} </div> </template>

显示效果:

name: 张三

age: 18

gender: 男

五、动态操作双雄:v-bind + v-on(@click)

5.1 代码展示

javascript
复制代码
import { ref } from 'vue' let imageUrl = ref('https://shadow.elemecdn.com/app/element/hamburger.9cf7b091-55e9-11e9-a976-7f4d0b07eef6.png') let count = ref(0) const handleClick = () => { count.value++ } </script> <template> <img :src="imageUrl" alt="p"> <button @click="handleClick">点击 {{ count }}</button> </template>

5.2 梗版拆解

这俩是 Vue 的 "动态操作组合拳"—— 一个管 "属性动态变",一个管 "事件动态触发":

  • :src="imageUrl"(v-bind 简写):给图片的 "地址属性" 绑了个 "遥控器",只要改imageUrl的值,图片就会自动换(比如把地址改成小猫图片,页面马上显示小猫);
  • @click="handleClick"(v-on 简写):给按钮装了个 "触发开关",点击一次就执行handleClick函数 —— 这里的函数是 "计数器加 1",所以点一次,count就从 0 变成 1、2、3...,按钮上的数字也跟着更。

5.3 专业版拆解

5.3.1 v-bind(简写:

  • 作用:动态绑定 HTML 元素的属性或 Vue 组件的 props,让属性值随变量变化;
  • 语法v-bind:属性名="变量" 或 :属性名="变量"
  • 常见场景:绑定图片src、链接href、样式class/style、组件 props 等,例如:
html
复制代码
<a :href="link">跳转</a> <div :class="{ active: isActive }"></div> <!-- 动态绑定类名 -->

5.3.2 v-on(简写@

  • 作用:绑定 DOM 事件或自定义事件,触发指定函数;
  • 语法v-on:事件名="函数" 或 @事件名="函数"
  • 事件对象:函数可接收$event参数获取事件对象,例如:
html
复制代码
<button @click="handleClick($event)">点击</button>
javascript
复制代码
const handleClick = (e) => { console.log(e.target) // 打印点击的按钮元素 }
  • 常见事件click(点击)、input(输入)、change(变化)、mouseenter(鼠标移入)等。
讲解一下handleClick函数
  • const handleClick:声明一个常量 handleClick,存储箭头函数。
  • (e):函数的参数 e 是事件对象(Event Object),当事件触发时(比如点击),浏览器会自动传递这个对象,包含了事件相关的信息(如触发事件的元素、事件类型等)。
  • 箭头函数 =>:ES6 语法,等价于传统的 function 定义(这里功能上等同于 function handleClick(e) { ... })。
箭头函数
场景传统 function 函数箭头函数说明
无参数function() { ... }() => { ... }箭头前用 () 表示无参数
单个参数function(a) { ... }a => { ... }单个参数可以省略 ()
多个参数function(a, b) { ... }(a, b) => { ... }多个参数必须用 () 包裹
函数体只有一行代码function(a) { return a + 1; }a => a + 1可省略 {} 和 return(自动返回结果)
函数体多行代码function(a) { let b = 2; return a + b; }a => { let b = 2; return a + b; }必须用 {} 包裹,且显式写 return

5.4 练习题

题目:用 v-bind 绑定一个按钮的 disabled 属性(当 count>=3 时禁用按钮),点击按钮 count 减 1。

javascript
复制代码
<script setup> import { ref } from 'vue' let count = ref(3) const handleMinus = () => { count.value-- } </script> <template> <button @click="handleMinus" :disabled="count >= 3">count: {{ count }}</button> </template>

六、条件渲染王者:v-if /v-else

6.1 代码展示

javascript
复制代码
<script setup> import { ref } from 'vue' let isVisible = ref(true) </script> <template> <button @click="isVisible = !isVisible">切换显示</button> <div v-if="isVisible">显示内容 AA</div> <h1 v-else>显示内容 BB</h1> </template>

6.2 梗版拆解

v-ifv-else是页面的 "二选一开关"—— 根据条件决定显示哪部分内容:

  • 初始isVisible是 true,显示 "AA",隐藏 "BB";
  • 点击按钮,isVisible变成 false,就隐藏 "AA",显示 "BB";
  • 注意:这俩必须是 "邻居",中间不能夹其他不带 v-if 的元素(比如把按钮放中间,Vue 就分不清谁和谁是一组,会报错)。

6.3 专业版拆解

  • 作用:根据布尔值条件渲染元素,条件为 true 时渲染v-if对应的元素,否则渲染v-else对应的元素;

  • 特点:元素不存在于 DOM 中(条件不满足时会被销毁),适合不频繁切换的场景(如登录 / 未登录状态显示不同内容);

  • 嵌套用法:支持v-ifv-else-ifv-else多条件判断,例如:

    html

    预览

    html
    复制代码
    <div v-if="score >= 90">优秀</div> <div v-else-if="score >= 60">及格</div> <div v-else>不及格</div>
  • 语法限制v-ifv-else-ifv-else必须连续相邻,中间不能插入其他 DOM 元素,否则 Vue 无法识别条件分组,导致渲染错误。

6.4 v-if 与 v-show 的核心区别

特性v-ifv-show
渲染方式条件满足则创建,否则销毁始终创建,通过 display 控制显示 / 隐藏
性能开销切换时开销大(DOM 操作)切换时开销小(样式操作)
适用场景不频繁切换(如登录状态)频繁切换(如 tabs 切换)
初始渲染开销条件不满足时开销小无论条件如何都有初始开销

七、HTML 渲染神器:v-html

7.1 代码展示

javascript
复制代码
<script setup> import { ref } from 'vue' let htmlContent = ref('<h1>这是一个HTML内容</h1>') </script> <template> <div v-html="htmlContent"></div> </template>

7.2 梗版拆解

v-html是 Vue 的 "HTML 翻译官"—— 把字符串里的 HTML 标签翻译成真实的页面元素:

  • 如果你直接用{{ htmlContent }},页面会显示<h1>这是一个HTML内容</h1>(把标签当普通文字);

  • 用了v-html,翻译官会识别<h1>标签,渲染成一个真正的大标题,显示效果就是 "这是一个 HTML 内容"(加粗放大)。

    就像你给机器输入 ",标题。你好",机器直接显示成标题样式,而不是原始文本。

7.3 专业版拆解

  • 作用:将字符串形式的 HTML 内容渲染为真实的 DOM 元素,替代插值语法(插值语法会转义 HTML 标签);
  • 适用场景:渲染富文本内容(如博客、评论、编辑器输出的 HTML 代码);
  • 安全风险:严禁用v-html渲染用户输入的内容(如用户评论),可能导致 XSS 攻击(恶意用户注入恶意 HTML/JS 代码,窃取信息或攻击网站);
  • 对比插值语法
    • 插值语法:{{ '<h1>你好</h1>' }} → 显示文本<h1>你好</h1>
    • v-html:<div v-html="'<h1>你好</h1>'"></div> → 显示 h1 标签的 "你好"。

八、组件通信利器:v-slot(插槽)

8.1 核心逻辑(简化版)

梗版拆解

v-slot是父子组件的 "快递代收点"—— 子组件留个 "收件箱"(<slot>标签),父组件把内容通过 "指定收件箱"(v-slot:name)寄过去,子组件就能显示父组件的内容:

  • 子组件(Child.vue):留个叫 "header" 的插槽(收件箱):
html
复制代码
<template> <div> <slot name="header"></slot> <!-- 收件箱:header --> <div>子组件默认内容</div> </div> </template>

父组件:给子组件的 "header" 插槽寄内容(放个标题)

html
复制代码
<template> <Child> <template v-slot:header> <h1>这是父组件的标题</h1> <!-- 要寄的内容 --> </template> </Child> </template>
  • 最终子组件会显示 "父组件的标题" + "子组件默认内容",实现父子组件内容灵活传递。

专业版拆解

  • 作用:实现父子组件间的内容分发,让父组件可以向子组件指定位置插入自定义内容;
  • 核心概念
    • 插槽(slot):子组件中用<slot>标签定义的 "占位符",父组件可在这些位置插入内容;
    • 具名插槽:带name属性的插槽(如slot name="header"),父组件用v-slot:name(简写#name)指定插入的插槽;
    • 默认插槽:无name属性的插槽,父组件未指定插槽的内容会插入默认插槽;
  • 简写语法v-slot:header可简写为#header,更简洁
html
复制代码
<template #header> <h1>父组件标题</h1> </template>

8.2 适用场景

  • 通用组件封装(如弹窗组件,父组件可自定义弹窗标题、内容、按钮);
  • 内容灵活替换(如卡片组件,不同页面使用时可插入不同的头部 / 底部内容)。

九、Vue 组件命名规范:避免踩坑的 "起名指南"

9.1 核心规范(梗版 + 专业版)

梗版

给组件起名就像给孩子起名 —— 要规范、好认、不撞名:

  • 不能叫 "div"、"button"(和 HTML 标签重名,Vue 会 confused);
  • 多单词要大写开头(比如UserLogin)或短横线连接(user-login),别瞎写userlogin(分不清是 "user login" 还是 "userlog in");
  • 文件名和组件名要一样(比如组件叫UserLogin,文件就叫UserLogin.vue),不然找组件时像找 "张小三" 却搜 "张三",找不到!

专业版

  1. 命名格式
    • 推荐使用PascalCase(大驼峰,如UserLogin):适用于单文件组件(.vue)、字符串模板、JSX;
    • 必须使用kebab-case(短横线,如user-login):适用于 DOM 模板(HTML 文件中的模板),因为 HTML 不区分大小写,UserLogin会被解析为userlogin,导致组件识别失败;
  2. 命名规则
    • 多单词命名:避免与 HTML 原生标签(如divspanbutton)冲突;
    • 语义化命名:根据组件功能命名(如UserLogin表示用户登录组件,GoodsCard表示商品卡片组件);
  3. 文件命名:组件文件名与组件名保持一致(如UserLogin.vue对应UserLogin组件),便于项目结构维护和查找。

9.2 错误示例 vs 正确示例

场景错误命名正确命名
单文件组件userlogin.vueUserLogin.vue
DOM 模板使用<UserLogin><user-login>
组件名ButtonMyButton(避免与原生<button>冲突)

十、关键避坑:为什么不建议 v-if 和 v-for 一起用?

10.1 梗版拆解

这俩一起用就像 "边炒菜边洗菜"—— 要么效率低,要么炒糊:

  • Vue2 里:v-for优先级高,先循环再判断,比如循环 100 个元素,每个都要判断一次 "显不显示",累死 Vue;
  • Vue3 里:v-if优先级高,先判断再循环,结果v-if里拿不到循环的变量(比如v-if="item.isShow",Vue3 会说 "item 是谁?我不认识"),直接报错;
  • 更坑的是:Vue2 和 Vue3 的优先级不一样,你在 Vue2 写的代码移到 Vue3,原本能跑,现在直接崩,找 bug 找半天!

10.2 专业版拆解

  1. Vue2 与 Vue3 的优先级差异
    • Vue2:v-for优先级 > v-if优先级,v-if会在每个循环迭代中执行,导致不必要的性能开销(如循环 100 个元素,每个都要执行一次v-if判断);
    • Vue3:v-if优先级 > v-for优先级,v-if无法访问v-for作用域内的变量(如itemindex),会抛出 "变量未定义" 的错误;
  2. 性能与兼容性问题
    • 性能:Vue2 中频繁循环 + 判断会消耗 DOM 渲染性能;
    • 兼容性:优先级差异导致代码在不同 Vue 版本中行为不一致,维护成本高;
  3. 解决方案
    • <template>包裹:将v-for放在<template>上,v-if放在子元素上(<template>不会渲染为真实 DOM);
html
复制代码
<template v-for="item in list" :key="item.id"> <div v-if="item.isVisible">{{ item.name }}</div> </template>

先过滤列表:在 JS 中用computed过滤出需要渲染的元素,再用v-for循环(推荐,性能最优)

javascript
复制代码
const filteredList = computed(() => list.value.filter(item => item.isVisible))

filteredList讲解

  • computed 是什么?

    computed 是 Vue 3 提供的计算属性 API,用于定义一个依赖响应式数据的计算值。它的特点是:

    • 当依赖的数据(这里是 list.value)发生变化时,会自动重新计算结果。
    • 结果会被缓存,只有依赖变化时才会重新计算,提升性能。
  • 箭头函数的作用

    • computed(() => { ... }) 中的箭头函数是计算属性的「 getter 」,定义了计算逻辑。
    • list.value.filter(item => item.isVisible) 是核心过滤逻辑:
      • list 是一个 Vue 响应式数据(通常由 ref 或 reactive 定义),list.value 是获取其原始值(数组)。
      • filter 是数组方法,用于过滤出符合条件的元素。这里的条件是 item.isVisible(即只保留 isVisible 为 true 的元素)。
      • 箭头函数 item => item.isVisible 等价于 function(item) { return item.isVisible; },简化了写法。
  • 最终效果

    filteredList 会实时返回 list 中所有 isVisible 为 true 的元素组成的新数组,且随 list 变化自动更新。

html
复制代码
<div v-for="item in filteredList" :key="item.id">{{ item.name }}</div>

十一、小结:Vue 指令 & 规范核心要点

  1. 核心指令
    • 数据绑定:v-model(双向)、{{ }}(插值);
    • 条件渲染:v-if(销毁 / 创建)、v-show(显示 / 隐藏);
    • 循环渲染:v-for(加:key);
    • 动态操作:v-bind(属性)、v-on(事件);
    • 特殊渲染:v-html(HTML 内容)、v-slot(插槽);
  2. 组件规范:多单词命名,大驼峰 / 短横线区分场景,文件名与组件名一致;
  3. 避坑重点:不混用v-ifv-for,优先用<template>computed替代。

掌握这些,你就能用 Vue 写出灵活、规范、高性能的动态页面啦!

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
下载 APP