Vue
Vue14年发布、16年2.0版本、
特点():易用、灵活、高效
是一套用于构建用户界面的渐进式框架
vue使用基本步骤
<title>你好世界</title>
</head>
<body>
<div id="app">
<div>{{msg}}</div>
<div>{{1+2}}</div>
<div>{{msg+'-----'+1+2}}</div>
</div>
</body>
<script src="js/vue.js"></script>
<script>
/*vue基本步骤
1、提供标签用于填充数据
2、引入库文件
3、使用vue语法做功能
4、把vue提供的库文件填充到标签中
*/
var vm= new Vue({
//el 元素挂载位置
//data数据模型(值是一个对象)
//{{}}叫插值表达式、填充数据、支持简单计算
el:'#app',
data:{
msg:'hello Vue'
}
})
</script>
指令
本质就是自定义属性
Vue 指令是 Vue 在解析模板时对 DOM 进行操作的特殊标记,本质上是 Vue 解析时执行的一种指令机制,而不是普通的 HTML 自定义属性(更新20250307)- Vue中指令都是以
v-
开头
v-cloak
作用:防止页面加载时出现闪烁问题
闪烁问题原因:vue语法编译前、有短暂显示原始插值表达式
原理:先隐藏替换好值后在显示最终的值
<style type="text/css">
/*
1、通过属性选择器 选择到 带有属性 v-cloak的标签 让他隐藏
*/
[v-cloak]{
/* 元素隐藏 */
display: none;
}
</style>
<body>
<div id="app">
<!-- 2、 让带有插值 语法的 添加 v-cloak 属性
在 数据渲染完成之后,v-cloak 属性会被自动去除,
v-cloak一旦移除也就是没有这个属性了 属性选择器就选择不到该标签
也就是对应的标签会变为可见
-->
<div v-cloak >{{msg}}</div>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
// el 指定元素 id 是 app 的元素
el: '#app',
// data 里面存储的是数据
data: {
msg: 'Hello Vue'
}
});
</script>
</body>
</html>
v-html、v-text、v-pre、v-once
v-text ---- 填充纯文本、没有闪动问题
v-html ---- 填充html片段、会解析标签(存在安全问题、第三方数据不推荐同)
v-pre ---- 填充元素信息 不编译
v-once ---- 只编译一次
双向数据绑定
双向数据绑定
- 当数据发生变化的时候,视图也就发生变化(数据改变页面)
- 当视图发生变化的时候,数据也会跟着同步变化(页面影响数据)
v-model
v-model是一个指令,限制在 <input>、<select>、<textarea>、components中使用
v-model本质:
通过V-bind去绑定属性值、
热后通过input事件去处理值的变化
<div id='app'>
<div>{{msg}}</div>
<!-- v-model的本质:通过v-bind绑定属性值、然后通知input事件去处理值的变化 -->
<input type="text" v-bind:value='msg' @input='handle'>
<input type="text" v-bind:value='msg' @input='msg=$event.target.value'>
<input type="text" v-model='msg'>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script>
/*v-model指令的本质*/
var vm = new Vue({
el: '#app',
data: {
msg: 'hello'
},
methods: {
handle: function (event) {
//输入域中最新的数据覆盖原来的数据
this.msg = event.target.value;
}
}
})
</script>
mvvm
m:模型:数据
v:视图:元素
vm:视图模型:控制逻辑
view 通过监听器影响(Listeners) model
model 通过数据劫持(Object.definedProperty)改变 view
事件绑定v-on
- 用来绑定事件
- 形式如:v-on:click 缩写为 @click;
v-on事件函数中传入参数
<!-- 1、如果事件直接绑定函数名称,那么默认会传递事件对象作为事件函数的第一个参数 -->
例如: <button v-on:click='handle1'>点击1</button>
(默认传递$event)
<!-- 2、函数调用的方式、**推荐使用**、 -->
<button v-on:click='handle2(123, 456, $event)'>点击2</button>
(事件对象的名称必须是$event、顺序要与形参对应)
事件修饰符
Vue 不推荐我们操作DOM 、为此Vue.js 为 v-on 提供了事件修饰符
修饰符是由点开头的指令后缀来表示的
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 即阻止冒泡也阻止默认事件 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。
按键修饰符
Vue 允许为 v-on 在监听键盘事件时添加按键修饰符
<!-- 只有在 `keyCode` 是 13 时调用 `vm.submit()` -->
<input v-on:keyup.13="submit">
<!-- -当点击enter 时调用 `vm.submit()` -->
<input v-on:keyup.enter="submit">
<!--当点击enter或者space时 时调用 `vm.alertMe()` -->
<input type="text" v-on:keyup.enter.space="alertMe" >
常用的按键修饰符
.enter => enter键
.tab => tab键
.delete (捕获“删除”和“退格”按键) => 删除键
.esc => 取消键
.space => 空格键
.up => 上
.down => 下
.left => 左
.right => 右
<script>
var vm = new Vue({
el:"#app",
methods: {
submit:function(){},
alertMe:function(){},
}
})
</script>
自定义按键修饰符别名
在Vue中可以通过config.keyCodes
自定义按键修饰符别名
//创建自定义修饰符
Vue.config.keyCodes.hcj=13;
//使用自定义修饰符、监听是否按下13对应的键
@keyup.hcj='handle($event)'
自定义按键修饰符名字是自己定义的、但是值必须是按键中对应的event.keyCode值
:v-bind(属性绑定)
- v-bind 指令被用来响应地更新 HTML 属性
- v-bind:href 可以缩写为 :href;
<!-- 绑定一个属性 -->
<img v-bind:src="imageSrc">
<!-- 缩写 -->
<img :src="imageSrc">
v-bind:绑定对象
//:绑定对象方式
通过v-bind来绑定class属性、值通过对象的方法控制类名是否显示、
控制多个类名、添加多个键值对、用逗号隔开
//在页面中的动态绑定对象
<div v-bind:class='obj'>测试样式</div>
//在data中的给对象的属性设置布尔值、用于控制显示隐藏
obj:{ active: true, error:true,}
//在methods中控制isActive的值在true和false之间切换
this.obj.active= !this.obj.active
this.obj.error=!this.obj.error;
v-bind:绑定数组
<!-- 数组绑定样式 -->
<div v-bind:class='[activeClass,errorClass]'>测试样式</div>
与对象的区别
在方法中操作对应的值、移除数据中对应的值
数组值是实际类名、可以加多个属性
//在数据中样式绑定
data: {
activeClass:'active',
errorClass:'error'
},
//在方法中操作对应的值
methods:{
handle:function(){
this.activeClass='',
this.errorClass=''
}
}
推荐使用数据方式定义类、方便使用数组相关API
样式绑定语法细节
1、对象绑定与数组绑定可以结合使用
<div v-bind:class='[activeClass,errorClass,{test:isTast}]'>测试样式</div>
2、class的值可以简化操作
//2.1数组简化
<div v-bind:class='arrClasses'></div>
//data中
arrClasses: ['active', 'error'],
//2.2对象简化
<div v-bind:class='objClasses'></div>
//data
objClasses: { active: true, error: true,}
3、基础样式不会被覆盖
<div class="base" v-bind:class='objClasses'></div>
绑定对象和绑定数组 的区别
- 绑定对象的时候 对象的属性 即要渲染的类名 对象的属性值对应的是 data 中的数据
- 绑定数组的时候数组里面存的是data 中的数据
绑定style
<div v-bind:style="styleObject">绑定样式对象</div>'
<!-- CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用单引号括起来) -->
<div v-bind:style="{ color: activeColor, fontSize: fontSize,background:'red' }">内联样式</div>
<!--组语法可以将多个样式对象应用到同一个元素、相同的样式会被覆盖 -->
<div v-bind:style="[styleObj1, styleObj2]"></div>
<script>
new Vue({
el: '#app',
data: {
styleObject: {
color: 'green',
fontSize: '30px',
background:'red'
},
activeColor: 'green',
fontSize: "30px"
},
styleObj1: {
color: 'red'
},
styleObj2: {
fontSize: '30px'
}
</script>
分支结构
v-if 使用场景
- 1- 多个元素 通过条件判断展示或者隐藏某个元素。或者多个元素
- 2- 进行两个视图之间的切换
v-show:控制元素的样式是否显示:display:none
<div id="app">
<div v-if='score>=90'>优秀</div>
<div v-else-if='score<90&&score>=80'>良好</div>
<div v-else-if='score<80&&score>=60'>一般</div>
<div v-else>比较差的</div>
<div v-show='flag'>测试v-show</div>
<button @click='handle'>点击</button>
</div>
</body>
<script src="js/vue.js"></script>
<script>
var vm=new Vue({
el:'#app',
data:{
score:90,
flag:false
},
methods:{
handle:function(){
//取反
this.flag=!this.flag;
}
}
})
</script>
v-show 和 v-if的区别
- v-show本质就是标签display设置为none,控制隐藏
- v-show只编译一次,后面其实就是控制css,而v-if不停的销毁和创建,故v-show性能更好一点。
- v-if是动态的向DOM树内添加或者删除DOM元素
- v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件
v-show :控制元素样式(频繁显示隐藏时使用)
v-if :控制元素(渲染后变化比较少是用)
循环结构
遍历数组
v-for:用于循环的数组里面的值可以是对象,也可以是普通元素
<ul id="example-1">
<!-- 循环结构-遍历数组
item 是我们自己定义的一个名字 代表数组里面的每一项
items对应的是 data中的数组-->
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
<script>
new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
],
}
})
</script>
- 不推荐同时使用 v-if 和 v-for
- 当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级。
遍历对象
<!-- 循环结构-遍历对象
v 代表 对象的value
k 代表对象的 键
i 代表索引
--->
<div v-for='(v,k,i) in obj' v-if='v==13'>{{v + '---' + k + '---' + i}}</div>
<script>
new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
],
obj: {
uname: 'zhangsan',
age: 13,
gender: 'female'
}
}
})
</script>
key 的作用
- 就是区别不同的元素、提高性能
- key来给每个节点做一个唯一标识
- key的作用主要是为了高效的更新虚拟DOM
<ul>
<li v-for="item in items" :key="item.id">...</li>
</ul>
选项卡案例
1、在data中定义数据
2、在页面中遍历对应数据
3、 通过点击事件接收当前遍历项的索引号、
4、在data中创建一个变量用于接收准备接收index的值、
5、在事件中把index的值赋值给变量this.current=index
6、 在动态绑定的样式中的判断:如果接收的变量的值current===index的值就添加样式
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.tab ul {
overflow: hidden;
padding: 0;
margin: 0;
}
.tab ul li {
box-sizing: border-box;
padding: 0;
float: left;
width: 100px;
height: 45px;
line-height: 45px;
list-style: none;
text-align: center;
border-top: 1px solid blue;
border-right: 1px solid blue;
cursor: pointer;
}
.tab ul li:first-child {
border-left: 1px solid blue;
}
.tab ul li.active {
background-color: orange;
}
.tab div {
width: 500px;
height: 300px;
display: none;
text-align: center;
font-size: 30px;
line-height: 300px;
border: 1px solid blue;
border-top: 0px;
}
.tab div.current {
display: block;
}
</style>
</head>
<body>
<div id="app">
<div class="tab">
<ul>
<!--遍历水果相关的数据 -->
<li v-for='(item,index) in fruits' :class='allIndex===index?"active":""' @click='hendle(index)'>
{{item.name}}</li>
</ul>
<!-- 遍历水果对应的图片、、判断 如果当前点击的值的索引===接收的索引号的话就添加样式 -->
<div v-for='(item,index) in fruits' :class='allIndex===index?"current":""' :key='index'>
<img :src='item.img'>
</div>
</div>
</div>
</body>
<script src="js/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
//定义一个变量、用于接收当前项的index值
allIndex: 0,
//定义水果相关的数据
fruits: [
{ name: 'apple', img: 'img/apple.png' },
{ name: 'orange', img: 'img/orange.png' },
{ name: 'lemon', img: 'img/lemon.png' }],
},
methods: {
hendle(index) {
//点击后接收index的值
this.allIndex = index;
}
}
})
</script>