1.1 指令表
指令 | 说明 |
---|---|
v-cloak | 作用:解决插值表达式{{msg}}闪烁的问题<br/>注意:需要配合属性选择器[v-cloak]{display:none;} 使用 |
v-text | 作用:输出文本 |
v-html | 作用:以浏览器能够解析的方式输出 |
v-bind | 格式:v-bind: <br/>简写::属性 <br/>作用:用于绑定属性的指令,可以写合法的JS表达式 |
v-on | 格式:v-on: 简写:@事件 作用:用于绑定事件 |
v-model | 作用:实现双向绑定(M => V, V => M) <br/>注意:只能用在表单元素中 |
v-for | 作用:for 循环 |
v-if v-else-if v-else | 作用:根据条件展示元素 缺点:直接对DOM节点进行删除和添加,有较高的性能消耗<br/> 建议:若元素并非频繁切换,推荐使用v-if |
v-show | 作用:根据条件展示元素 <br/>缺点:对元素进行 display 操作,有较高的初始渲染消耗<br/>建议:若元素需要频繁的切换,建议使用v-show |
1.1.0 基本的代码结构
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
{{msg}}
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
msg: 'Study',
text: '<strong>加粗了呀</strong>',
num: 0,
flag: 'A',
list: [
{ id: 1, name: '小炎' },
{ id: 2, name: '小天' },
{ id: 3, name: '小若' },
{ id: 4, name: '小修' },
{ id: 5, name: '小瑞' }
]
},
methods: {
btn(){
alert('click')
}
}
})
</script>
</body>
</html>
1.1.1 v-cloak
<!-- CSS Code -->
<style>
[v-cloak] {
display: none;
}
</style>
<!-- Html Code -->
<div id="app">
<!-- 插值表达式 -->
<!-- v-clock 解决插值表达式闪烁问题 -->
<p v-cloak>{{ msg }}</p>
</div>
<!-- Script Code -->
<!-- 为了方便演示,所以不在头部引入 Vue ,而是在这里 -->
<script src='https://cdn.staticfile.org/vue/2.6.9/vue.min.js'></script>
- 打开浏览器调试工具,按如下顺序:
Network -> Presets(Disable cache 右边) -> show 3G
勾上 - 运行后发现,当 Vue 还没完全加载完成时,会直接把源代码给显示出来。
因为我们的网络不稳定,导致了 Vue 还未加载完成,而 DOM 就已经渲染完了,此时用户最先看到的自然是 DOM 元素。
1.1.2 v-text
<!-- Html Code -->
<div id="app">
<!-- 不会解析html标签 -->
<p v-text="text"></p>
</div>
1.1.3 v-html
<!-- Html Code -->
<div id="app">
<!-- 不会解析html标签 -->
<p v-text="text"></p>
<!-- 可以解析HTML标签 -->
<p v-html="text"></p>
</div>
1.1.4 bind
<!-- Html Code -->
<div id="app">
<!-- v-bind: 是vue中用于绑定属性的指令 -->
<p v-bind:title="msg" class="title">TITLE</p>
<!-- v-bind: 中可以书写合法的js表达式 -->
<p v-bind:title="msg" class="'my '+title">TITLE</p>
<!-- v-bind: 可以简写为冒号:要绑定的属性 -->
<p v-bind:title="msg" class="'my '+title">TITLE</p>
</div>
1.1.5 v-on
<!-- Html Code -->
<div id="app">
<!-- v-on: 绑定事件-->
<!-- 点击触发btn方法 -->
<button v-on:click='btn'>单击</button>
</div>
跑马灯效果案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>跑马灯</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input type="button" value="浪起来" @click="lang">
<input type="button" value="低调" @click="stop">
<p v-html="msg"></p>
</div>
<script>
const vm = new Vue({
el:'#app',
data: {
msg: '猥琐发育,别浪~~!!!',
intervalId: null,
},
methods: {
lang(){
if(this.intervalId != null)return;
this.intervalId = setInterval(()=>{
// 获取到头的第一个字符
let start = this.msg.substring(0,1);
// 获取到后面所有的字符
let end = this.msg.substring(1);
// 将第一个字符放到最后面
this.msg = end+start;
},400)
},
stop(){
clearInterval(this.intervalId);
this.intervalId = null;
}
}
});
</script>
</body>
</html>
1.1.6 v-model
v-model 指令通过绑定值和捕获 input 事件来模拟双向绑定,它能轻松实现表单输入和应用状态之间的数据双向绑定。
<!-- 双向绑定:实时更新 -->
<input :value="num" @input="e => num = e.target.value">
<textarea :value="num" @input="e => num = e.target.value"></textarea>
<p v-text="msg"></p>
v-model 双向绑定 只能用于表单元素
<!-- Html Code -->
<div id="app">
<!-- v-bind只能实现数据的单向绑定 -->
<input v-bind:value="num" >
<!-- 双向绑定:实时更新 -->
<input v-model="num" >
<p v-text="num"></p>
<!-- 双向绑定:延迟更新 修饰符lazy -->
<input v-model.lazy="num" >
<!-- 相当于失去焦点时才触发更新操作 -->
<p v-text="num"></p>
</div>
简易计算器案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>简易的计算器</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" v-model="x">
<select v-model="opt">
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
<input type="text" v-model="y">
<input type="button" value="=" @click="calc">
<input type="text" v-model="result">
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
x: 0,
y: 0,
result: 0,
opt: '+',
},
methods: {
calc() {
/*switch (this.opt) {
case '+':
this.result = parseInt(this.x) + parseInt(this.y);
break;
case '-':
this.result = parseInt(this.x) - parseInt(this.y);
break;
case '*':
this.result = parseInt(this.x) * parseInt(this.y);
break;
case '/':
this.result = parseInt(this.x) / parseInt(this.y);
break;
}*/
let codeStr = `parseInt(this.x) ${this.opt} parseInt(this.y)`;
this.result = eval(codeStr);
}
}
});
</script>
</body>
</html>
1.1.7 v-for
<!-- Html Code -->
<div id="app">
<ul v-for="item in list" :key="item.id">
<li>
<input type="checkbox" /> 【id】:{{item.id}} -- 【姓名】:{{item.name}}
</li>
</ul>
</div>
Vue指令之v-for
和key
属性
- 迭代数组
<ul> <li v-for="(item, i) in list">索引:{{i}} --- 姓名:{{item.name}} --- 年龄:{{item.age}}</li></ul>
- 迭代对象中的属性
<ul>
<li v-for="(item, i) in list">索引:{{i}} --- 姓名:{{item.name}} --- 年龄:{{item.age}}</li>
</ul>
- 迭代数字
<p v-for="i in 10">这是第 {{i}} 个P标签</p>
2.2.0+ 的版本里,当在组件中使用 v-for 时,key 现在是必须的。
v-for 中未设置 key 的问题
从这幅GIF中,我们可以很清楚的看到,一开始选择的是
5
号,然后unshift()
后,复选框选择的位置依然没有跟着变动,而是在原位置一动不动。
当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用 “就地复用” 策略。如果数据项的顺序被改变,Vue将不是移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。
解决这个问题,添加一个key
即可,需要v-bind
绑定
<ul>
<li v-for="item in list" :key="item.id">
<input type="checkbox" />
【id】:{{item.id}} -- 【姓名】:{{item.name}}
</li>
</ul>
1.1.8 v-if / v-else-if / v-else
<!-- Html Code -->
<div id="app">
<p v-if="flag === 'A'">A</p>
<p v-else-if="flag === 'B'">B</p>
<p v-else>C</p>
</div>
1.1.9 v-show
<!-- Html Code -->
<div id="app">
<p v-show="flag">A</p>
</div>
v-if 的特点:每次都会重新删除或创建元素
v-show的特点:每次不会重新进行DOM的删除和创建操作,只是切换了元素的display:none样式
v-if 有较高的切换性能消耗,v-show有较高的初始渲染消耗,如果元素涉及到频繁的切换,最好使用v-show,但如果元素可能永远也不会被用户看到,则推荐使用v-if指令
选项卡切换案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.vertical-tab {
width: 920px;
margin: 100px auto;
}
.vertical-tab .nav {
list-style: none;
width: 200px;
}
.vertical-tab .nav-tabs1 {
border-right: 3px solid #e7e7e7;
}
.vertical-tab .nav-tabs2 {
border-left: 3px solid #e7e7e7;
}
.vertical-tab .nav a {
display: block;
font-size: 18px;
font-weight: 700;
text-align: center;
letter-spacing: 1px;
text-transform: uppercase;
padding: 10px 20px;
margin: 0 0 1px 0;
text-decoration: none;
}
.vertical-tab .tab-content {
color: #555;
background-color: #fff;
font-size: 15px;
letter-spacing: 1px;
line-height: 23px;
padding: 10px 15px 10px 25px;
display: table-cell;
position: relative;
}
.vertical-tab .nav-tabs1 {
float: left;
}
.vertical-tab .tabs {
width: 500px;
box-sizing: border-box;
float: left;
}
.vertical-tab .tab-content h3 {
font-weight: 600;
text-transform: uppercase;
margin: 0 0 5px 0;
}
.vertical-tab .nav-tabs2 {
float: right;
}
.tab-content {
position: relative;
}
.tab-content .tab-pane {
position: absolute;
top: 10px;
left: 20px;
}
.nav li.active a {
color: #198df8;
background: #fff;
border: none;
}
.fade {
opacity: 0;
transition: all .3s linear;
}
.fade.active {
opacity: 1;
}
</style>
</head>
<body>
<div class="vertical-tab" id="app">
<!-- Nav tabs -->
<ul class="nav nav-tabs1">
<li v-on:click='change(index,0)' :class='currentIndex==index?"active":""' v-if="index < list.length/2" v-for="(item, index) in list"><a href="#"> {{item.title}} </a></li>
</ul>
<!-- Tab panes -->
<div class="tab-content tabs">
<div class="tab-pane fade" :class='currentIndex==index?"active":""' :key='item.id' v-for='(item, index) in list'>
<h3>{{item.title}}</h3>
<p>{{item.content}}</p>
</div>
</div>
<!-- Nav tabs -->
<ul class="nav nav-tabs2">
<li v-on:click='change(index,1)' :class='currentIndex==index?"active":""' v-if="index >= list.length/2" v-for="(item, index) in list"><a href="#"> {{item.title}} </a></li>
</ul>
</div>
<script type="text/javascript" src="js/vue.js"></script>
<script>
new Vue({
el: "#app",
data: {
currentIndex: 0, // 选项卡当前的索引
list: [{
id: 1,
title: 'Section 1',
content: 'content1'
}, {
id: 2,
title: 'Section 2',
content: 'content2'
}, {
id: 3,
title: 'Section 3',
content: 'content3'
}, {
id: 4,
title: 'Section 4',
content: 'content4'
}, {
id: 5,
title: 'Section 5',
content: 'content5'
}, {
id: 6,
title: 'Section 6',
content: 'content6'
}]
},
methods: {
change(index, flag) {
if (flag) {
console.log(index)
this.currentIndex = index;
} else {
this.currentIndex = index;
}
}
}
})
</script>
</body>