本文内容的方法演示也都是通过一个html文件来演示的,旨在简易的了解Vue用法。
要学习Vue ,先安装好环境,试一下创建一个html文件,
安装扩展:
在vscode中安装Volar,Vue(Official),Live Server
Live Server :
这是一个轻量级的本地静态文件服务器插件。它的核心作用是实时预览。当你修改代码并保存时,它会自动刷新浏览器,让你立即看到更改效果。
重要提示:Live Server 仅适用于普通的 HTML/CSS/JS 静态页面。对于真正的 Vue 工程化项目(包含 .vue 单文件组件),Live Server 无法解析这些文件。Vue 项目必须通过终端运行 npm run dev 来启动开发服务器。
怎样创建并使用一个html文件:
new一个新文件,将后缀更改为html,内部写完需要的html代码后,右下角找到Go Live点击就会自动跳转到默认浏览器打开这个html文件,且在你修改代码保存后浏览器会自动刷新。

这里有个技巧是输入!按tab就会自动生成一个标准的HTML结构。

一、HTML模板
为了防止乱码、保证兼容性以及代码规范,建议在最前面写例如以下这段的模板代码。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Vue el 挂载点详解</title>
<!-- 引入 Vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<style>
/* 简单的样式,让界面更清晰 */
</style>
</head>
| 代码片段 | 所在位置 | 作用讲解 | 是否必须 |
|---|---|---|---|
<!DOCTYPE html> |
文件最顶部 | 文档类型声明。告诉浏览器这是一个 HTML5 文档,防止浏览器进入怪异模式(Quirks Mode)。 | 必须 (虽然浏览器能猜,但规范开发必须写) |
<html lang="zh-CN"> |
根标签 | 语言定义。lang="zh-CN" 告诉搜索引擎和辅助设备(如读屏软件)该网页主要使用简体中文。 |
建议写 (对 SEO 和无障碍访问很重要) |
<meta charset="UTF-8"> |
<head> 内 |
字符编码。指定文档使用 UTF-8 编码。作用:防止网页出现乱码(特别是中文)。 | 必须 (如果不写,中文会变成乱码) |
<title>Vue el 挂载点详解</title> |
<head> 内 |
页面标题。显示在浏览器的标签页上,也是搜索引擎抓取的重要信息。 | 建议写 (不写也没语法错误,但不专业) |
<script src="...vue.js"></script> |
<head> 内 |
引入 Vue 库。这是 Vue 框架的"引擎"。作用:让浏览器认识 new Vue() 这种语法。 |
必须 (没有它,Vue 代码全是报错) |
<style> ... </style> |
<head> 内 |
内部样式表。用于在 HTML 文档内部集中编写 CSS 样式代码(如字体、颜色、布局等),控制页面的外观表现。 | 非必须 (如果不需要任何自定义样式,可以不写;但如果要美化页面,则必须有它或外链CSS) |
二、Vue常用指令
学习Vue,先来学习一个Vue的常用指令,Vue指令是写在HTML标签内部的,它们以标签属性的形式存在。
1、数据绑定类型
v-bind(简写为:):
作用:
用于动态绑定一个或多个 HTML 属性、组件 prop 或样式类名。
简单来说就是告诉 Vue:"请把引号里的内容当成 JavaScript 变量(或表达式)去解析,而不是当成普通的纯文本字符串"。
举例解释:
1、绑定变量
<img :src="imageUrl">
:src="imageUrl"**作用:**它的核心作用是告诉 Vue 引擎:"不要把我后面的内容当成普通的字符串,而是去 JavaScript 的数据(如 data)中寻找对应的变量"。如果没有这个冒号,Vue 会认为你只是想把一张叫 imageUrl 的图片显示出来。
2、绑定表达式
html
<!-- 三元运算符判断 -->
<div :class="isActive ? 'active-class' : ''"></div>
<!--
如果Vue中的isActive为true,
渲染到浏览器上的真实 HTML 是
<div class="active-class"></div>
否则渲染到浏览器上的真实 HTML 是
<div></div>
-->
v-text:
作用:
更新元素的文本内容(相当于 {{ }} 插值),会覆盖元素原有内容。
与{{}}的区别:
1. 覆盖机制不同
v-text 会覆盖元素原有的默认内容。例如 <p v-text="gender">性别</p>,最终页面上只会显示变量 gender 的值,"性别"这两个字会被完全替换掉。
{{ }} 只是占位符。例如 <p>姓名: {{username}}</p>,它只会替换大括号的位置,保留"姓名: "等原有文本。
2. 防闪屏效果
在网络较慢、Vue 还未完成编译时,使用 {{message}} 可能会让用户短暂看到乱码一样的 {{message}(即闪屏现象)。而 v-text 直接绑定属性,在内容未渲染时该元素内部是空的,从而完美避开了这个问题。
v-html:
作用:
更新元素的 innerHTML,可以渲染真实的 HTML 标签。注意: 容易导致 XSS 攻击,仅对可信内容使用。
举例解释:
html
<div id="app">
<!-- 使用 v-html 渲染 -->
<div v-html="content"></div>
</div>
new Vue({
el: '#app',
data: {
content: '<h2 style="color: blue;">Vue渲染HTML</h2><p>这是一段富文本内容</p>'
}
})
<!--
页面上会直接显示出一个蓝色的二级标题和一段正文,而不是把 <h2> 这些标签当作普通文字显示出来。
--
防止XSS漏洞:
1、尽量避免使用。
2、前端二次防御
比如使用 DOMPurify:能自动过滤掉恶意的 <script> 标签、事件处理器(如 onerror)以及 javascript: 协议等高危内容。
3、后端净化
在后端接收到用户提交的内容并写入数据库之前,必须使用成熟的后端清洗库进行处理。
严格采用白名单机制,只允许安全的标签(如 <b>、<i>、<a>)和安全的属性(如限制 <a> 的 href 只能是 http/https 协议),坚决移除未在白名单内的任何内容。
2、双向绑定指令
v-model:
作用:
能在视图(页面输入框)和数据(JS变量)之间建立实时同步通道。
举例解释:
html
1. 基础文本输入
<!-- 单行文本 -->
<input type="text" v-model="username">
<p>你输入的是:{{ username }}</p>
<!-- 多行文本 -->
<textarea v-model="bio"></textarea>
2. 复选框 (checkbox)
<!--单个复选框(绑定布尔值):勾选为 true,取消勾选为 false。-->
<input type="checkbox" v-model="isAgree"> 同意协议
<!--多个复选框组(绑定数组):被勾选的选项的 value 会自动推入该数组,取消勾选则移除。-->
<input type="checkbox" v-model="hobbies" value="reading"> 阅读
<input type="checkbox" v-model="hobbies" value="coding"> 编程
3. 单选按钮 (radio)
<!--多个 radio 共享同一个 v-model 变量,当前选中项的 value 会被赋给该变量。-->
<input type="radio" v-model="gender" value="male"> 男
<input type="radio" v-model="gender" value="female"> 女
4. 下拉选择框 (select)
<!--v-model 绑定的是 <option> 标签的 value 属性,而不是显示的文本。-->
<select v-model="selectedCity">
<option disabled value="">请选择城市</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
</select>
提供修饰符:
.lazy:默认情况下,每次敲击键盘都会触发更新;加上 .lazy 后,只有在输入框"失去焦点"或按回车时才更新数据,非常适合搜索框防抖。
.number:自动将用户输入转换为数值类型,避免 "1" + "2" = "12" 这种字符串拼接问题。
html
<input v-model.number="age" type="number">
.trim:自动过滤用户输入的首尾空白字符。
3、条件与列表渲染指令
v-if / v-else-if / v-else:
作用:
根据表达式的真假来决定是否渲染元素。
条件为假时,会直接将元素从 DOM 树中彻底销毁(删除);条件为真时再重新创建。适用于切换不频繁的场景(如权限控制、用户登录状态)。
举例解释:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>v-if / v-else-if / v-else 演示 (Vue 2版)</title>
<!-- 引入 Vue 2 -->
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<style>
body { font-family: Arial, sans-serif; padding: 20px; line-height: 1.6; }
.box { margin-top: 15px; padding: 10px; border-radius: 4px; background-color: #f4f4f4; }
button { padding: 5px 10px; cursor: pointer; }
</style>
</head>
<body>
<div id="app">
<!-- 1. 基础多分支条件链 -->
<h2>学生成绩评级</h2>
<input type="number" v-model.number="score" placeholder="请输入分数(0-100)" />
<div class="box">
<p v-if="score >= 90">🏆 优秀!表现非常棒!</p>
<p v-else-if="score >= 60">✅ 及格,继续加油哦!</p>
<p v-else>❌ 不及格,需要复习啦。</p>
</div>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
score: 60 // 默认分数为 60
};
}
});
</script>
</body>
</html>
可以看到分数不一样走的if分支不一致。
v-show:
作用:
无论条件真假,元素都会被渲染,只是通过切换 CSS 的 display: none 来控制隐藏。初始渲染开销稍大,但频繁切换的性能更好(如弹窗、折叠面板)。
举例解释:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>v-show 控制显隐示例</title>
<!-- 引入 Vue 2 -->
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<style>
body { font-family: Arial, sans-serif; padding: 20px; line-height: 1.6; }
.box { margin-top: 15px; padding: 15px; border-radius: 4px; background-color: #f4f4f4; max-width: 400px;}
button { padding: 8px 15px; cursor: pointer; background-color: #42b983; color: white; border: none; border-radius: 4px;}
button:hover { background-color: #3aa773; }
</style>
</head>
<body>
<div id="app">
<!-- 1. 触发切换的按钮 -->
<button @click="toggleShow">点击切换文本显隐</button>
<!-- 2. 被 v-show 控制的元素 -->
<div class="box" v-show="isVisible">
👋 你好!我是被 v-show 控制的文本。<br>
当你点击上面的按钮时,我会瞬间消失或出现。
</div>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
// 定义响应式变量,初始值为 true(默认显示)
isVisible: true
};
},
methods: {
// 定义切换函数,反转 isVisible 的值
toggleShow() {
this.isVisible = !this.isVisible;
}
}
});
</script>
</body>
</html>
点击按钮后isVisible反转状态

v-for:
作用:
基于数组或对象循环渲染 DOM 列表。使用时强烈建议绑定唯一的 key 属性(如 :key="item.id"),这能帮助 Vue 高效追踪节点状态,避免列表排序或过滤时出现状态错乱。
核心规则(参数作用):
遍历数组时(最多2个参数):
第 1 个参数:固定代表当前项的值(数组元素)。
第 2 个参数(可选):固定代表索引(从0开始)。
遍历对象时(最多3个参数):
第 1 个参数:固定代表属性的值 (Value)。
第 2 个参数(可选):固定代表属性的键名 (Key)。
第 3 个参数(可选):固定代表遍历的索引 (Index)。
遍历整数或字符串时(最多2个参数):
第 1 个参数:固定代表当前的迭代值(数字从1递增,字符串为单个字符)。
第 2 个参数(可选):固定代表索引(从0开始)。
举例解释:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>v-for 列表渲染演示 (Vue 2)</title>
<!-- 引入 Vue 2 -->
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<style>
body { font-family: Arial, sans-serif; padding: 20px; line-height: 1.6; }
.box { margin-top: 15px; padding: 10px; border-radius: 4px; background-color: #f9f9f9; max-width: 400px;}
ul { list-style-type: none; padding: 0; }
li { padding: 5px 0; }
</style>
</head>
<body>
<div id="app">
<!-- 1. 遍历普通数组 -->
<h3>游戏列表</h3>
<div class="box">
<ul>
<!-- item 代表数组中的每一项,index 代表索引(从0开始) -->
<li v-for="(item, index) in games" :key="index">
{{ index + 1 }}. {{ item }}
</li>
</ul>
</div>
<!-- 2. 遍历对象数组 -->
<h3 style="margin-top: 20px;">人员信息</h3>
<div class="box">
<ul>
<li v-for="(p, index) in persons" :key="p.id">
<strong>{{ index + 1 }}. {{ p.name }}</strong> 的详细信息:<br>
<!--遍历对象
这里就是传入的前两个参数,还可以继续加一个index
-->
<span v-for="(val, key) in p" :key="key">
{{ key }}: {{ val }}
</span>
</li>
</ul>
</div>
<!-- 3. 迭代整数
当直接使用 v-for="n in 10" 这种形式时:
n:代表当前的迭代次数,它的值会从 1 开始递增,直到达到指定的整数上限(例如这里的 10)。
-->
<h3 style="margin-top: 20px;">数字生成</h3>
<div class="box">
<span v-for="count of 5" :key="count" style="margin-right: 10px;">
{{ count }}
</span>
</div>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
// 普通字符串数组
games: ['三角洲', '王者', '燕云'],
// 对象数组
persons: [
{ id: 1, name: '张三', age: 18 },
{ id: 2, name: '李四', age: 20 },
{ id: 3, name: '王五', age: 22 }
]
};
}
});
</script>
</body>
</html>
4、事件处理指令
v-on:
缩写:
完整语法:v-on:click="处理语句"
简写:@click="处理语句"
与v-bind区别:
v-bind是将当前属性绑定后面的script变量
v-on是当前方法触发后执行后面的script语句
作用:
监听 DOM 事件的核心指令,它的主要作用是实现用户与页面的交互。当指定的事件(如点击、输入等)被触发时,Vue 会执行相应的 JavaScript 代码。
修饰符:
.prevent:阻止默认行为。例如 <form @submit.prevent="onSubmit"> 可以阻止表单提交后页面刷新。
.stop:阻止事件冒泡。例如 <a @click.stop="doThis"> 点击时不会向外层父级元素传递点击事件。
.once:确保事件只触发一次。例如 <button @click.once="shout(1)">ok</button>。
举例解释:
html
<!--1、内联事件处理器(适合极简单的逻辑)
你可以直接在模板中编写简单的表达式。
-->
<button @click="count++">点击 +1</button>
<p>当前计数:{{ count }}</p>
<!--2、方法事件处理器
将事件绑定到在 methods 中定义的函数上。这样可以让模板保持整洁,且逻辑更易维护。
-->
<button @click="greet">打招呼</button>
methods: {
greet() {
alert('Hello Vue!');
}
}
<!--3、传递参数与获取原生事件对象 ( $ event)
有时候需要同时传递自定义参数和原生的 DOM 事件对象,这时可以使用特殊的 $event 变量:
-->
<button @click="warn('hello', $event)">点我警告</button>
methods: {
warn(message, event) {
console.log(message); // 输出: hello
console.log(event.target.tagName); // 输出: BUTTON (获取触发事件的DOM元素)
}
}
经常配合使用的处理语句($emit):
html
<button @click="$emit('add-cart',value)">做事情</button>
这里的 $emit('add-cart') 就像是子组件向外发射了一个名为 add-cart 的信号弹。
而在父组件里,@add-cart 就是专门用来捕捉这个信号弹的雷达。一旦子组件触发了这个事件,父组件就会立刻执行等号后面的方法。
html
<!--父组件中-->
@add-cart="method"
一旦子组件触发了这个事件,父组件就会立刻执行等号后面的method方法
methods:{
method(value){
console.log(`使用了{value}`);
};
}
5、辅助指令:
v-pre(跳过编译)
告诉 Vue 编译器"完全忽略这个区域"。它会跳过当前元素及其所有子节点的编译过程,Vue 不会解析其中的任何插值表达式(如 {``{ message }})、指令或组件语法,而是将其作为纯静态 HTML 原样输出。
适用场景:
展示原始代码:在编写技术文档或教程时,需要原样展示 {{ message }} 这样的文本,而不是让 Vue 去解析它。
纯静态内容:大段不需要 Vue 管理的说明文字、版权信息、法律条款等,使用它可以减少不必要的 AST 遍历与指令解析,降低首次挂载时的内存占用。
v-once(只渲染一次)
实现"单次渲染语义"。元素或组件在首次渲染后,就会被标记为静态节点。此后无论响应式数据如何变化,Vue 都会跳过该节点的后续更新和虚拟 DOM 差异对比(diff),视图永远保持第一次渲染的样子。
注意:如果你把本应随数据变化的区域加了 v-once,会导致界面"假死",用户看到旧数据而无法刷新。
v-cloak(防止页面闪烁)
解决页面初次加载时的"未编译模板闪现"问题。当网络较慢或 Vue 尚未完成挂载时,用户可能会短暂看到原始的 {{ message }} 标签。v-cloak 会保留在元素上,直到 Vue 实例挂载完成后才自动移除。需要配合CSS使用。
6、自定义指令:
1、注册方式:
全局注册:使用 Vue.directive('指令名称', { ... }) 方法,注册后可以在项目任意组件中使用。
局部注册:在组件的 directives 选项中定义,仅在当前组件内可用。
2、钩子函数与核心参数:
一个指令的定义对象可以提供多个可选的钩子函数,最常用的包括:
bind:指令第一次绑定到元素时调用(常用于初始化设置)。
inserted:被绑定的元素插入父节点时调用(常用于获取焦点等 DOM 操作)。
update:所在组件的 VNode 更新时调用。
unbind:指令与元素解绑时调用(常用于清理工作,如移除事件监听器)。
这些钩子函数会接收以下核心参数:
el:指令所绑定的真实 DOM 元素,可以直接对其进行样式或属性修改。
binding:一个包含指令信息的对象。最常用的是 binding.value(获取传递给指令的绑定值)、binding.arg(传给指令的参数)以及 binding.modifiers(修饰符对象)。
示例:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>v-color 自定义指令演示 (Vue 2)</title>
<!-- 引入 Vue 2 -->
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<style>
body { font-family: Arial, sans-serif; padding: 30px; line-height: 1.6; }
.demo-box { margin-top: 20px; padding: 15px; border-radius: 4px; background-color: #f9f9f9; max-width: 500px;}
button { padding: 6px 12px; margin-right: 8px; cursor: pointer; border-radius: 4px; border: 1px solid #ccc;}
p { font-size: 20px; font-weight: bold; margin: 10px 0;}
</style>
</head>
<body>
<div id="app">
<h2>🎨 v-color 自定义指令效果展示</h2>
<div class="demo-box">
<!-- 使用自定义指令,将当前 textColor 的值传递给 binding.value -->
<p v-color="textColor">这是一段会随数据变化的文字!</p>
<p>当前绑定的颜色值:<code>{{ textColor }}</code></p>
<!-- 通过点击按钮修改响应式数据,从而触发 update 钩子 -->
<button @click="textColor = 'red'">变红</button>
<button @click="textColor = 'blue'">变蓝</button>
<button @click="textColor = '#FF9800'">变橙</button>
</div>
</div>
<script>
// 1. 全局注册自定义指令 v-color
Vue.directive('color', {
// 当指令第一次绑定到元素时调用(初始化)
bind(el, binding) {
el.style.color = binding.value;
},
// 当所在组件的 VNode 更新时调用(数据发生变化时重新执行)
update(el, binding) {
el.style.color = binding.value;
}
});
// 2. 创建 Vue 实例
new Vue({
el: '#app',
data() {
return {
textColor: 'green' // 初始颜色
};
}
});
</script>
</body>
</html>
初始默认是红色,证明bind起到了作用,而点击变蓝,文字会变蓝,证明了update起到了作用。
三、Vue常用方法
学完了常用指令,再来看看Vue的常用方法,Vue 中的方法本质上就是 JavaScript 代码
1、data:定义响应式数据
作用:
数据的源头,Vue 会自动监听这里的变量变化并刷新页面。
2、methods:事件处理与业务逻辑
作用:
存放各种函数,通常用来响应用户的点击(@click)或表单提交等操作。
3、computed:计算属性
作用:
基于现有数据自动计算出新的值。自带缓存机制,只有当依赖的数据发生变化时才会重新计算。常用于字符串拼接、列表过滤等。
示例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Vue computed</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="app">
<p>姓:<input v-model="firstName"></p>
<p>名:<input v-model="lastName"></p>
<!-- 像普通变量一样使用,不需要加括号 -->
<h2>全名:{{ fullName }}</h2>
</div>
<script>
new Vue({
el: '#app',
data() {
return {
firstName: '张',
lastName: '三'
}
},
computed: {
fullName() {
// 只要 firstName 或 lastName 变了,这里就会自动重新执行
return this.firstName + this.lastName;
}
}
});
</script>
</body>
</html>

当姓或者名修改的时候全名自动修改
4、watch:侦听器
作用:
专门用来"盯"某个特定数据的变化。一旦该数据发生改变,就立刻去执行一段特定的逻辑(比如发送网络请求、打印日志)。
数据变化传参规则:
Vue 在检测到数据变化时,会按照严格的顺序把值塞进这两个参数里:
第一个参数 :代表变化后的新值。
第二个参数:代表变化前的旧值。
名字是可以随便起的
示例:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Vue watch</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="app">
<p>搜索框:<input v-model="keyword" placeholder="随便输入点什么"></p>
<p style="color:gray;">请打开浏览器控制台(F12)查看打印结果</p>
</div>
<script>
new Vue({
el: '#app',
data() {
return { keyword: '' }
},
watch: {
// 监听 keyword 的变化
keyword(newVal, oldVal) {
console.log(`关键词从 "${oldVal}" 变成了 "${newVal}"`);
// 实际开发中,这里通常会写 axios.get(...) 去请求后端接口
}
}
});
</script>
</body>
</html>
可以看到在输入1,2,3的过程中keyword值变化,这个函数也执行了打印日志。

在这个例子中,它只是打印了日志。但在实际开发中,watch 最常见的用途是**"防抖"** 和**"发送请求"**。
5、mounted:生命周期钩子
作用:
在组件的 DOM 元素完全渲染到页面上之后触发。非常适合用来获取 DOM 节点、初始化第三方图表库等。
具体意思:
Vue实例初始化完成过后,并且页面上的 DOM 节点(HTML标签)已经真实渲染出来了,Vue 就会自动帮你运行 mounted() 里的代码。
我们可以把 Vue 启动的过程分成几个关键节点:
准备阶段:Vue 读取了你的 data,知道了 name = 'Hello Vue!',但此时页面上还是空的或者显示着原始的 {{ name }} 占位符。
挂载阶段:Vue 在内存里把 {{ name }} 替换成了 'Hello Vue!',准备好了最终的 HTML,但还没把它贴到网页上。
完成挂载:Vue 把准备好的 HTML 正式贴到了网页上。就在这一瞬间,mounted() 的代码才会被执行。
特点:只执行一次
在组件的整个生命周期里,mounted() 只会执行一次。
示例:
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 1. 页面上有一个元素 -->
<h1 ref="title">等待被修改...</h1>
<!-- 2. 有一个按钮,点击后会改变元素内容 -->
<button @click="changeText">点击我改变文字</button>
</div>
<script>
new Vue({
el: '#app',
mounted() {
// 3. Vue一挂载(页面一显示),立刻执行这里的代码
console.log('页面已经显示在屏幕上了!');
// 安全地操作DOM
this.$refs.title.innerText = '我是 mounted 钩子修改的文字';
this.$refs.title.style.color = 'red';
},
methods: {
changeText() {
// mounted 里的代码执行完后,这个按钮的功能依然可用
this.$refs.title.innerText = '文字被用户点击改变了';
}
}
});
</script>
</body>
</html>
可以看到界面初始上的文字并不是"等待被修改...",而是"我是 mounted 钩子修改的文字",证明mounted在HTML渲染完毕后立即就执行了。
点击按钮仍然可以改变内容。

四、其他常用需注意:
这里还有一些我觉得需要注意的点
1、el:挂载点
核心作用:
决定了 Vue 的势力范围。
常用写法:
|------------|---------------|---------------------------|
| '#id' | 通过 ID 查找(最常用) | <div id="app"> |
| '.class' | 通过类名查找 | <div class="container"> |
| 'tag' | 通过标签名查找 | <body> (不推荐) |
示例解说:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Vue el 挂载点详解</title>
<!-- 引入 Vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
<!-- 区域 A:被 Vue 管理的区域 (通过 id="app" 绑定) -->
<div id="app" class="box managed">
<h3>区域 A:Vue 的势力范围 (el: '#app')</h3>
<p>当前数据:<strong>{{ message }}</strong></p>
<button @click="changeMessage">点击我修改数据</button>
<p style="font-size: 12px;">(这里的 {{ message }} 会被替换成真实数据)</p>
</div>
<!-- 区域 B:未被 Vue 管理的区域 (没有对应的 el) -->
<div id="other-zone" class="box unmanaged">
<h3>区域 B:普通 HTML 区域</h3>
<p>当前数据:<strong>{{ message }}</strong></p>
<button @click="changeMessage">点击我修改数据</button>
<p style="font-size: 12px;">(注意看:这里的 {{ message }} 没有被解析,直接显示出来了)</p>
</div>
<script>
// 创建 Vue 实例
var vm = new Vue({
// 【关键点】这里指定了 el,Vue 只会去管 id 为 app 的那个 div
el: '#app',
data: {
message: "你好,我是 Vue!"
},
methods: {
changeMessage: function() {
alert("数据正在被修改");
}
}
});
</script>
</body>
</html>
可以看到区域A的Message被解析成了"你好,我是Vue!",而区域B的没有,而点击区域B的"点击我修改数据按钮没反应,点击区域A的"点击我修改数据"会有弹出以下提示。

1、完成两个挂载
第一步:修改 HTML,增加第二个容器
在<body> 中,除了原来的 <div id="app">,我们再添加一个 <div id="app2">:
html
<body>
<div id="app">
<!--传递自定义参数,事件修饰符 -->
<input type="button" value="点击改名" @click="ChangeUser">
<!--vue修改数据方式:this.变量名-->
<h2>{{username}}</h2>
</div>
<div id="app2">
<h2 @click="changeUser">{{username}}</h2>
</div>
</body>
第二步:编写 JavaScript,创建两个实例
在 <script> 标签中,我们实例化两次 new Vue():
html
<script>
var app = new Vue({
el: '#app',
data: {
username: "张三"
},
methods:{
ChangeUser:function(){
this.username="张四";
}
}
});
var app2 = new Vue({
el: '#app2', // 指定第二个挂载点
data: {
username: "李四"
},
methods: {
changeUser: function () {
app.username = "赵五";
}
}
});
</script>

不同的Vue也可以通过名字引用其他Vue的成员。
这里点击改名只会修改张三为张四,点击李四会修改张三为赵五。
2、<template> 和 <div> 的对比
| 特性 | <div> |
<template> (内部包裹器) |
|---|---|---|
| 最终渲染结果 | 会直接渲染为真实的 DOM 节点 | 不会渲染到页面上,属于"隐形"容器 |
| 主要用途 | 用于页面的视觉布局、组织结构、添加样式 | 仅用于组织代码逻辑,避免产生冗余的 DOM 节点 |
支持 v-show |
支持(通过 CSS display:none 隐藏) |
不支持(因为它本身就不生成 DOM 节点) |
当你在一个标签上写了 v-for="item in list" 时,Vue 会把这个标签当作一个模具,根据数组的长度,循环克隆出多少个一模一样的标签。 假设你的数据 list 有 3 条数据,我们来看看这两种写法的区别:
示例:
(1)把 v-for 写在 <div> 上
html
<ul>
<div v-for="item in list" :key="item.id">
<li>{{ item.name }}</li>
<span>{{ item.desc }}</span>
</div>
</ul>
Vue 会把 <div> 作为模具进行 3 次克隆。最终浏览器解析出来的真实 DOM 结构是这样的:
html
<ul>
<!-- 第1个克隆出的 div -->
<div>
<li>苹果</li>
<span>红色的水果</span>
</div>
<!-- 第2个克隆出的 div -->
<div>
<li>香蕉</li>
<span>黄色的水果</span>
</div>
<!-- 第3个克隆出的 div -->
<div>
<li>橘子</li>
<span>酸甜的水果</span>
</div>
</ul>
页面上凭空多出了 3 个 <div> 盒子,可能会破坏你原本写好的 CSS 排版样式。
(2)把 v-for 写在 <template> 上
html
<ul>
<template v-for="item in list" :key="item.id">
<li>{{ item.name }}</li>
<span>{{ item.desc }}</span>
</template>
</ul>
Vue 在执行 v-for 时,虽然也是克隆了 3 次,但 <template> 自身在渲染完毕后会自动"消失"。
本篇结束!







