![](https://img.kancloud.cn/41/e0/41e066af9a6c25a24868d9667253ec98_1241x333.jpg)
*****
### 文本
在html中通过{{}}(双大括号)中可以把Vue对象中的数据插入到网页中。并且只要Vue对象上对应的值发生改变了,那么html中双大括号中的值也会立马改变。
```
<div id="app">
<p>{{username}}</p>
<button v-on:click="change">点击修改</button>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
"username": "逻辑教育"
},
methods: {
change: function(){
this.username = 'China';
}
}
});
</script>
```
当然,如果在html的{{}}中,第一次渲染完成后,不想要跟着后期数据的更改而更改,那么可以使用v-once指令来实现。
```
<p v-once>{{username}}</p>
```
### 显示原生的HTML
有时候我们的Vue对象中,或者是后台返回给我们一个段原生的html代码,我们需要渲染出来,那么如果直接通过{{}}渲染,会把这个html代码当做字符串。这时候我们就可以通过v-html指令来实现
```
<div id="app">
<div v-html="code"></div>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
"code": "<a href='https://www.baidu.com/'>百度一下,你就知道!</a>"
}
});
</script>
```
### 属性绑定
如果我们想要在html元素的属性上绑定我们Vue对象中的变量,那么需要通过v-bind来实现
```
<div id="app">
<img class="{{classname}}">你好,世界</p>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
"classname": "pclass"
},
});
</script>
```
需要使用v-bind才能生效
```
<div id="app">
<img v-bind:src="imgSrc" alt="">
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
"imgSrc": "https://i.ytimg.com/vi/5HKZ6bU6Zg0/maxresdefault.jpg"
}
});
</script>
```
### 属性绑定Class和Style
在绑定class或者style的时候,可以通过以下方式来实现。
#### 绑定Class
通过数组的方式来实现
```
<div id="app">
<p v-bind:class="[classname1,classname2]">你好,世界</p>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
classname1: "pcolor",
classname2: "pfont"
}
});
</script>
```
通过对象的方式来实现
```
<div id="app">
<p v-bind:class="{pcolor:isColor,pfont:isFont}">你好,世界</p>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
isColor: true,
isFont: true
}
});
</script>
```
#### 绑定Style
用对象的方式
```
# 读取对应样式的值
<li :style="{backgroundColor:pBgColor,fontSize:pFontSize}">首页</li>
# 或者是直接读取整个字符串
<li :style="liStyle">首页</li>
```
但是样式如果有横线,则都需要变成驼峰命名的方式
用数组的方式
```
<li :style="[liStyle1,liStyle2]">首页</li>
<script>
new Vue({
el: "#app",
data: {
liStyle: {
backgroundColor: "red",
fontSize: "14px"
},
liStyle2: {
fontWeight: 800
}
}
})
</script>
```
### 使用JavaScript表达式
在使用了v-bind的html属性,或者使用了{{}}的文本。我们还可以执行一个JavaScript表达式
```
<div id="app">
<p v-bind:style="{color:color?'red':'blue'}">{{username.split(" ").reverse().join(" ")}}</p>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
username: "luoji ketang",
color: false
}
});
</script>
```
注意,只能是JavaScript表达式,不能是语句,比如var a=1;a=2;这样的是js语句,不是表达式了
### 条件判断
在模板中,可以根据条件进行渲染。条件用到的是v-if、v-else-if以及v-else来组合实现的
```
<div id="app">
<p v-if="weather == 'sun'">今天去公园玩!</p>
<p v-else-if="weather == 'rain'">今天去看电影!</p>
<p v-else>今天哪儿也不去!</p>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
weather: 'sun'
}
});
</script>
```
有时候我们想要在一个条件中加载多个html元素,那么我们可以通过template元素上实现
```
<div id="app">
<template v-if="age<18">
<p>数学多少分?</p>
<p>英语多少分?</p>
</template>
<template v-else-if="age>=18 && age<25">
<p>女朋友找到了吗?</p>
<p>考研究生了吗?</p>
</template>
<template v-else>
<p>二胎生了吗?</p>
<p>工资多少?</p>
</template>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
age: 24
}
});
</script>
```
另外,在模板中,Vue会尽量重用已有的元素,而不是重新渲染,这样可以变得更加高效。如果你允许用户在不同的登录方式之间切换
```
<div id="app">
<template v-if="loginType=='username'">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" placeholder="用户名">
</template>
<template v-else-if="loginType=='email'">
<label for="email">邮箱:</label>
<input type="text" id="email" name="email" placeholder="邮箱">
</template>
<div>
<button v-on:click="changeLoginType">切换登录类型</button>
</div>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
loginType: "username"
},
methods: {
changeLoginType: function(event){
this.loginType = this.loginType=="username"?"email":"username";
}
}
});
</script>
```
这个里面会有一个问题,就是如果我在username的输入框中输入完信息,切换到邮箱中,之前的信息还是保留下来,这样肯定不符合需求的,如果我们想要让html元素每次切换的时候都重新渲染一遍,可以在需要重新渲染的元素上加上唯一的key属性,其中key属性推荐使用整形,字符串类型。
```
<div id="app">
<template v-if="loginType=='username'">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" placeholder="用户名" key="username">
</template>
<template v-else-if="loginType=='email'">
<label for="email">邮箱:</label>
<input type="text" id="email" name="email" placeholder="邮箱" key="email">
</template>
<div>
<button v-on:click="changeLoginType">切换登录类型</button>
</div>
</div>
```
注意,<label>元素仍然会被高效地复用,因为它们没有添加key属性
### v-show和v-if
v-if是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。 v-if也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。 相比之下,v-show就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于CSS进行切换。 一般来说, v-if有更高的切换开销,而v-show有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用v-show较好;如果在运行时条件很少改变,则使用v-if较好。
## 循环
在模板中可以用`v-for`指令来循环数组,对象等
### 循环数组
~~~
<div id="app">
<table>
<tr>
<th>序号</th>
<th>标题</th>
<th>作者</th>
</tr>
<tr v-for="(book,index) in books">
<td>{{index}}</td>
<td>{{book.title}}</td>
<td>{{book.author}}</td>
</tr>
</table>
</div>
~~~
### 循环对象
循环对象跟循环数组是一样的。并且都可以在循环的时候使用接收多个参数
~~~
<div id="app">
<div v-for="(value,key) in person">
{{key}}:{{value}}
</div>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
person: {
"username": "逻辑教育",
"age": 18,
"homepage": "https://www.baidu.com/"
}
}
});
</script>
~~~
### 保持状态
循环出来的元素,如果没有使用`key`元素来唯一标识,如果后期的数据发生了更改,默认是会重用的,并且元素的顺序不会跟着数据的顺序更改而更改
~~~
<div id="app">
<div v-for="(book,index) in books">
<label for="book">{{book}}</label>
<input type="text" v-bind:placeholder="book">
</div>
<button v-on:click="changeBooks">更换图书</button>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
books: ['三国演义','水浒传','红楼梦','西游记']
},
methods: {
changeBooks: function(event){
this.books.sort((x,y) => {
return 5 - parseInt(Math.random()*10)
});
}
}
});
</script>
~~~
### 触发视图更新
`Vue`对一些方法进行了包装和变异,以后数组通过这些方法进行数组更新,会出发视图的更新。
1. `push()`:添加元素的方法。
~~~
this.books.push("居然")
~~~
2. `pop()`:删除数组最后一个元素。
~~~
this.books.pop()
~~~
3. `shift()`:删除数组的第一个元素。
~~~
this.books.shift()
~~~
4. `unshift(item)`:在数组的开头位置添加一个元素。
~~~
this.books.unshift("居然")
~~~
5. `splice(index,howmany,item1,...,itemX)`:向数组中添加或者删除或者替换元素。
~~~
// 向books第0个位置添加元素
this.books.splice(0,0,"金瓶梅")
// 下标从0开始,删除2个元素
this.books.splice(0,2)
// 下标从0开始,替换2个元素
this.books.splice(0,2,'金瓶梅','骆驼祥子')
~~~
6. `sort(function)`:排序。
~~~
this.books.sort(function(x,y){
// 取两个随机数排序
a = Math.random();
b = Math.random();
return a-b;
});
~~~
7. `reverse()`:将数组元素进行反转。
~~~
this.books.reverse();
~~~
### 视图更新注意事项
1. 直接修改数组中的某个值是不会出发视图更新的。比如:
~~~
this.books[0] = 'Python';
~~~
这种情况应该改成用`splice`或者是用`Vue.set`方法来实现:
~~~
Vue.set(this.books,0,'Python');
~~~
2. 如果动态的给对象添加属性,也不会触发视图更新。只能通过`Vue.set`来添加。比如:
~~~
<div id="app">
<ul>
<li v-for="(value,name) in person">{{name}}:{{value}}</li>
</ul>
<script>
let vm = new Vue({
el: "#app",
data: {
person: {"username": '逻辑教育'}
},
methods: {
changePerson: function(event){
Vue.set(this.person,'age',18)
}
}
});
</script>
</div>
~~~
## 事件绑定
事件绑定就是在`HTML`元素中,通过`v-on`绑定事件的。事件代码可以直接放到`v-on`后面,也可以写成一个函数。
~~~
<div id="app">
<p>{{count}}</p>
<button v-on:click="count+=1">加</button>
<button v-on:click="subtract(10)">减10</button>
</div>
<script>
let vm = new Vue({
el: "#app",
data: {
count: 0
},
methods: {
subtract: function(value){
this.count -= value;
}
}
});
</script>
~~~
### 传入`event`参数
如果在事件处理函数中,想要获取原生的`DOM`事件,那么在`html`代码中,调用的时候,可以传递一个`$event`参数。
~~~
<button v-on:click="subtract(10,$event)">减10</button>
...
<script>
...
methods: {
subtract: function(value,event){
this.count -= value;
console.log(event);
}
}
...
</script>
~~~