Vue
1、MVVM 思想
- M:即 Model,模型,包括数据和一些基本操作
- V:即 View,视图,页面渲染结果
- VM:即 View-Model,模型与视图间的双向操作(无需开发人员干涉)
在 MVVM 之前,开发人员从后端获取需要的数据模型,然后要通过 DOM 操作 Model 渲染
到 View 中。而后当用户操作视图,我们还需要通过 DOM 获取 View 中的数据,然后同步到
Model 中。而 MVVM 中的 VM 要做的事情就是把 DOM 操作完全封装起来,开发人员不用再关心 Model
和 View 之间是如何互相影响的:
- 只要我们 Model 发生了改变,View 上自然就会表现出来。
- 当用户修改了 View,Model 中的数据也会跟着改变。
把开发人员从繁琐的 DOM 操作中解放出来,把关注点放在如何操作 Model 上。

2、指令
1)、花括号
格式:{{表达式}}
说明:
该表达式支持 JS 语法,可以调用 js 内置函数(必须有返回值)
表达式必须有返回结果。例如 1 + 1,没有结果的表达式不允许使用,如:let a = 1 + 1;
可以直接获取 Vue 实例中定义的数据或函数
2)、插值闪烁
使用{{}}方式在网速较慢时会出现问题。在数据未加载完成时,页面会显示出原始的`{{}}`,
加载完毕后才显示正确数据,我们称为插值闪烁。
我们将网速调慢一些,然后刷新页面,试试看刚才的案例:
3)、v-text 和 v-html
可以使用 v-text 和 v-html 指令来替代{{}}
说明:
v-text:将数据输出到元素内部,如果输出的数据有 HTML 代码,会作为普通文本输出
v-html:将数据输出到元素内部,如果输出的数据有 HTML 代码,会被渲染
示例:
<div id="app">
v-text:<span v-text="hello"></span> <br />
v-html:<span v-html="hello"></span>
</div><script src="./node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el: "#app",
data: {
hello: "<h1>大家好</h1>"
}
})
</script>
2、v-bind
html 属性不能使用双大括号形式绑定,我们使用 v-bind 指令给 HTML 标签属性绑定值;
而且在将 `v-bind` 用于 `class` 和 `style` 时,Vue.js 做了专门的增强。
1)、绑定 class
<div class="static" v-bind:class="{ active: isActive, 'text-danger'
: hasError }">
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
isActive: true,
hasError: false
}
})
</script>2)、绑定 style
`v-bind:style` 的对象语法十分直观,看着非常像 CSS,但其实是一个 JavaScript 对象。style
属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,这种方式记得用单引号括起
来) 来命名。
例如:font-size-->fontSize
<div id="app" v-bind:style="{ color: activeColor, fontSize: fontSiz
e + 'px' }"></div>
<script>
let vm = new Vue({
el: "#app",
data: {
activeColor: 'red',
fontSize: 30
}
})
</script>
结果:<div style="color: red; font-size: 30px;"></div>
3)、绑定其他任意属性
<div id="app" v-bind:style="{ color: activeColor, fontSize: fontS
ize + 'px' }"
v-bind:user="userName">
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
activeColor: 'red',
fontSize: 30,
userName: 'zhangsan'
}
})
</script>
效果:
<div id="app" user="zhangsan" style="color: red; font-size: 30px;"></div>
4)、v-bind 缩写
<div id="app" :style="{ color: activeColor, fontSize: fontSize + 'px' }" :user="userName"> </div>
刚才的 v-text、v-html、v-bind 可以看做是单向绑定,数据影响了视图渲染,但是反过来就不
行。接下来学习的 v-model 是双向绑定,视图(
View)和模型(Model)之间会互相影响。
既然是双向绑定,一定是在视图中可以修改数据,这样就限定了视图的元素类型。目前
v-model 的可使用元素有:
- input
- select
- textarea
- checkbox
- radio
- components(
Vue 中的自定义组件)
基本上除了最后一项,其它都是表单的输入项。
示例:
<div id="app"> <input type="checkbox" v-model="language" value="Java" />Java<br /> <input type="checkbox" v-model="language" value="PHP" />PHP<br /> <input type="checkbox" v-model="language" value="Swift" />Swift<br /> <h1> 你选择了:{ {language.join(',') } } </h1> </div> <script src="../node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> let vm = new Vue({ el: "#app", data: { language: [] } }) </script>
- 多个`CheckBox`对应一个 model 时,model 的类型是一个数组,单个 checkbox 值默认是boolean 类型
- radio 对应的值是 input 的 value 值
- `text` 和`textarea` 默认对应的 model 是字符串
- `select`单选对应字符串,多选对应也是数组
4、v-on
1、基本用法
v-on 指令用于给页面元素绑定事件。
语法: v-on:事件名="js 片段或函数名"
示例:
<div id="app"> <!--事件中直接写 js 片段--> <button v-on:click="num++">点赞</button> <!--事件指定一个回调函数,必须是 Vue 实例中定义的函数--> <button v-on:click="decrement">取消</button> <h1>有{{num}}个赞</h1> </div> <script src="../node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> let vm = new Vue({ el: "#app", data: { num: 100 }, methods: { decrement() { this.num--; //要使用 data 中的属性,必须 this.属性名 } } }) </script>
另外,事件绑定可以简写,例如`v-on:click='add'`可以简写为`@click='add'`
2、事件修饰符
在事件处理程序中调用 `event.preventDefault()` 或 `event.stopPropagation()` 是非常常见的
需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,
而不是去处理 DOM 事件细节。
为了解决这个问题,Vue.js 为 `v-on` 提供了事件修饰符。修饰符是由点开头的指令后缀来
表示的。
`.stop` :阻止事件冒泡到父元素
`.prevent`:阻止默认事件发生
`.capture`:使用事件捕获模式
`.self`:只有元素自身触发事件才执行。(冒泡或捕获的都不执行)
`.once`:只执行一次
<div id="app"> <!--右击事件,并阻止默认事件发生--> <button v-on:contextmenu.prevent="num++">点赞</button> <br /> <!--右击事件,不阻止默认事件发生--> <button v-on:contextmenu="decrement($event)">取消</button> <br /> <h1>有{{num}}个赞</h1> </div> <script src="../node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> let app = new Vue({ el: "#app", data: { num: 100 }, methods: { decrement(ev) { // ev.preventDefault(); this.num--; } } }) </script>
效果:右键“点赞”,不会触发默认的浏览器右击事件;右键“取消”,会触发默认的浏览
器右击事件)
3、按键修饰符
在监听键盘事件时,我们经常需要检查常见的键值。Vue 允许为 `v-on` 在监听键盘事件时添
加按键修饰符:
<!-- 只有在 `keyCode` 是 13 时调用 `vm.submit()` -->
<input v-on:keyup.13="submit">
记住所有的 `keyCode` 比较困难,所以 Vue 为最常用的按键提供了别名:
<!-- 同上 -->
<input v-on:keyup.enter="submit">
<!-- 缩写语法 -->
<input @keyup.enter="submit">
全部的按键别名:
`.enter`
`.tab`
`.delete` (捕获“删除”和“退格”键)
`.esc`
`.space`
`.up`
`.down`
`.left`
`.right`
4、组合按钮
可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
`.ctrl`
`.alt`
`.shift`
<!-- Alt + C -->
<input @keyup.alt.67="clear">
<!-- Ctrl + Click --><div @click.ctrl="doSomething">Do something</div>
5、v-for
遍历数据渲染页面是非常常用的需求,Vue 中通过 v-for 指令来实现。
1、遍历数组
语法:v-for="item in items"
items:要遍历的数组,需要在 vue 的 data 中定义好。
item:迭代得到的当前正在遍历的元素
示例:
<div id="app"> <ul> <li v-for="user in users"> {{user.name}} - {{user.gender}} - {{user.age}} </li> </ul> </div> <script src="../node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> let app = new Vue({ el: "#app", data: { users: [ { name: '柳岩', gender: '女', age: 21 }, { name: '张三', gender: '男', age: 18 }, { name: '范冰冰', gender: '女', age: 24 }, { name: '刘亦菲', gender: '女', age: 18 }, { name: '古力娜扎', gender: '女', age: 25 } ] }, }) </script>
2、数组角标
在遍历的过程中,如果我们需要知道数组角标,可以指定第二个参数:
语法:v-for="(item,index) in items"
items:要迭代的数组
item:迭代得到的数组元素别名
index:迭代到的当前元素索引,从 0 开始。
示例:
<div id="app"> <ul> <li v-for="(user, index) in users"> {{index + 1}}. {{user.name}} - {{user.gender}} - {{user.age}} </li> </ul> </div>
3、遍历对象
v-for 除了可以迭代数组,也可以迭代对象。语法基本类似
语法:
v-for="value in object"
v-for="(value,key) in object"
v-for="(value,key,index) in object"
1 个参数时,得到的是对象的属性值
2 个参数时,第一个是属性值,第二个是属性名
3 个参数时,第三个是索引,从 0 开始
示例:
<div id="app"> <ul> <li v-for="(value, key, index) in user"> {{index + 1}}. {{key}} - {{value}} </li> </ul> </div> <script src="../node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> let vm = new Vue({ el: "#app", data: { user: { name: '张三', gender: '男', age: 18 } } }) </script>
4、Key
用来标识每一个元素的唯一特征,这样 Vue 可以使用“就地复用”策略有效的提高渲染的
效率。
示例:
<ul> <li v-for="(item,index) in items" :key=”index”></li> </ul> <ul> <li v-for="item in items" :key=”item.id”></li> </ul>
如果 items 是数组,可以使用 index 作为每个元素的唯一标识
如果 items 是对象数组,可以使用 item.id 作为每个元素的唯一标识
6、v-if 和 v-show
1、基本用法
v-if,顾名思义,条件判断。当得到结果为 true 时,所在的元素才会被渲染。
v-show,当得到结果为 true 时,所在的元素才会被显示。
语法:v-if="布尔表达式", v-show="布尔表达式",
示例:
<div id="app"> <button v-on:click="show = !show">点我呀</button> <br> <h1 v-if="show"> 看到我啦?! </h1> <h1 v-show="show"> 看到我啦?!show </h1> </div> <script src="../node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> let app = new Vue({ el: "#app", data: { show: true } }) </script>
2、与 v-for 结合
当 v-if 和 v-for 出现在一起时,v-for 优先级更高。也就是说,会先遍历,再判断条件。
修改 v-for 中的案例,添加 v-if:
<ul> <li v-for="(user, index) in users" v-if="user.gender == '女'"> {{index + 1}}. {{user.name}} - {{user.gender}} - {{user.age}} </li> </ul>
7、v-else 和 v-else-if
v-else 元素必须紧跟在带 `v-if` 或者 `v-else-if` 的元素的后面,否则它将不会被识别。
示例:
<div id="app"> <button v-on:click="random=Math.random()">点我呀 </button><span>{{random}}</span> <h1 v-if="random >= 0.75"> 看到我啦?!v-if >= 0.75 </h1> <h1 v-else-if="random > 0.5"> 看到我啦?!v-else-if > 0.5 </h1> <h1 v-else-if="random > 0.25"> 看到我啦?!v-else-if > 0.25 </h1> <h1 v-else> 看到我啦?!v-else </h1> </div> <script src="../node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> let app = new Vue({ el: "#app", data: { random: 1 } }) </script>
6、计算属性和侦听器
1、计算属性(computed)
某些结果是基于之前数据实时计算出来的,我们可以利用计算属性。来完成
示例:
<div id="app"> <ul> <li>西游记:价格{{xyjPrice}},数量: <input type="number" v-model="xyjNum"></li> <li>水浒传:价格{{shzPrice}},数量: <input type="number" v-model="shzNum"></li> <li>总价:{{totalPrice}}</li> </ul> </div> <script src="../node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> let app = new Vue({ el: "#app", data: { xyjPrice: 56.73, shzPrice: 47.98, xyjNum: 1, shzNum: 1 }, computed: { totalPrice(){ return this.xyjPrice*this.xyjNum + this.shzPrice*th is.shzNum; } }, }) </script>
2、监听(watch)
watch 可以让我们监控一个值的变化。从而做出相应的反应。
示例:
<div id="app"> <ul> <li>西游记:价格{{xyjPrice}},数量: <input type="number" v-model="xyjNum"></li> <li>水浒传:价格{{shzPrice}},数量: <input type="number" v-model="shzNum"></li> <li>总价:{{totalPrice}}</li> {{msg}} </ul> </div> <script src="../node_modules/vue/dist/vue.js"></script> <script type="text/javascript"> let app = new Vue({ el: "#app", data: { xyjPrice: 56.73, shzPrice: 47.98, xyjNum: 1, shzNum: 1, msg:"" }, computed: { totalPrice(){ return this.xyjPrice*this.xyjNum + this.shzPrice*th is.shzNum; } }, watch: { xyjNum(newVal, oldVal){ if(newVal >= 3){ this.msg = "西游记没有更多库存了"; this.xyjNum = 3; }else{ this.msg = ""; } } } }) </script>
3、过滤器(filters)
过滤器不改变真正的`data`,而只是改变渲染的结果,并返回过滤后的版本。在很多不同的
情况下,过滤器都是有用的,比如尽可能保持 API 响应的干净,并在前端处理数据的格式。
示例:展示用户列表性别显示男女
<body> <div id="app"> <table> <tr v-for="user in userList"> <td>{{user.id}}</td> <td>{{user.name}}</td> <!-- 使用代码块实现,有代码侵入 --> <td>{{user.gender===1? "男":"女"}}</td> </tr> </table> </div> </body> <script src="../node_modules/vue/dist/vue.js"></script> <script> let app = new Vue({ el: "#app", data: { userList: [ { id: 1, name: 'jacky', gender: 1 }, { id: 2, name: 'peter', gender: 0 } ] } }); </script>
1、局部过滤器
注册在当前 vue 实例中,只有当前实例能用
let app = new Vue({
el: "#app",
data: {
userList: [
{ id: 1, name: 'jacky', gender: 1 },
{ id: 2, name: 'peter', gender: 0 }
]
},
// filters 定义局部过滤器,只可以在当前 vue 实例中使用
filters: {
genderFilter(gender) {
return gender === 1 ? '男~' : '女~'
}
}
});
<!-- | 管道符号:表示使用后面的过滤器处理前面的数据 -->
<td>{{user.gender | genderFilter}}</td>
2、全局过滤器
// 在创建 Vue 实例之前全局定义过滤器: Vue.filter('capitalize', function (value) { return value.charAt(0).toUpperCase() + value.slice(1) }) 任何 vue 实例都可以使用: <td>{{user.name | capitalize}}</td>
过滤器常用来处理文本格式化的操作。过滤器可以用在两个地方:双花括号插值和 v-bind
表达式
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?