2. 基础语法¶
2.1. 插值操作¶
通过插值操作可以完成vue对象的数据,填充到html中去。
<h2> {{ message }} </h2>
2.1.1. v-once¶
可以完成vue仅仅一次的数据绑定,后续的数据修改不在同步页面。
2.1.2. v-html¶
可以将数据中的html内容,以html展示到页面上。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <!doctype html>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<p>Using mustaches: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
rawHtml: '<span style="color:red"> this should be red</span>'
}
})
</script>
</body>
</html>
|
2.1.3. v-text¶
可以将数据中的html内容,以text展示到页面上。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <!doctype html>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<p>Using mustaches: {{ rawHtml }}</p>
<p>Using v-text directive: <span v-text="rawHtml"></span></p>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
rawHtml: '<span style="color:red"> this should be red</span>'
}
})
</script>
</body>
</html>
|
2.1.4. v-pre¶
用于跳过这个元素和他子元素的编译过程,用于展示原本内容。
2.1.5. v-cloak¶
某些情况下 ,浏览器可能会直接展示未编译的mustache标签。 通过此可以不展示这些信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <!doctype html>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
[v-cloak] {
display: none ;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<h2 >{{ cnt }}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
setTimeout(function(){
let app = new Vue({
el: "#app",
data: {
cnt: 1,
}
})},3000)
</script>
</body>
</html>
|
2.2. 绑定属性¶
v-bind可以绑定属性。
2.2.1. 绑定基本使用¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <!DOCTYPE html>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<img :src="srcUrl" alt="">
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
srcUrl: "https://i1.hdslb.com/bfs/face/c850c18ae6b507d0ef34837f53a51090b6a7451f.jpg@96w_96h_1c.webp"
}
})
</script>
</body>
</html>
|
2.2.2. 动态绑定class¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <!doctype html>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.active{
color: red;
}
.line{
background-color: blue;
}
</style>
</head>
<body>
<div id="app">
<h2 v-bind:class="getClass()">{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
message: "panda",
isActive: true,
isLine: true
},
methods:{
getClass: function(){
return {active:this.isActive,line:this.isLine}
}
}
})
</script>
</body>
</html>
|
2.2.3. 动态绑定style¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <!doctype html>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.active{
color: red;
}
.line{
background-color: blue;
}
</style>
</head>
<body>
<div id="app">
<h2 v-bind:style="{fontSize: messageFontSize}">{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
message: "panda",
messageFontSize: "100px",
},
methods:{
}
})
</script>
</body>
</html>
|
2.2.4. v-for和v-bind作业¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <!doctype html>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.active{
color: red;
}
.line{
background-color: blue;
}
</style>
</head>
<body>
<div id="app">
<ul>
<li v-for="(zoom,index) in zooms">
<p v-bind:class="{active: curentIndex==index}" @click="ChangeClass($event,index)"> {{index }} - {{ zoom }} </p>
</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
zooms: ['cat','dog','pig'],
curentIndex:0,
isActive: false
},
methods:{
ChangeClass: function (event,index){
this.curentIndex =index
}
}
})
</script>
</body>
</html>
|
2.3. 计算属性¶
可以根据已有的属性生成其他属性。
2.3.1. 基本使用¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <!DOCTYPE html>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>{{ fullName }}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
firstName: "jie di",
secondName: "zhao",
},
computed:{
fullName: function (){
return this.secondName + " " + this.firstName
}
}
})
</script>
</body>
</html>
|
2.3.2. 复杂使用¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | <!DOCTYPE html>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>{{ totalPrice }}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
books: [
{id:1,name:'abc',price:100},
{id:2,name:'abc',price:101},
{id:3,name:'abc',price:102},
{id:4,name:'abc',price:103},
]
},
computed:{
totalPrice: function (){
let result=0
// for (let i=0; i< this.books.length; i++){
// result +=this.books[i].price
// }
for (let book of this.books){
result += book.price
}
return result
}
}
})
</script>
</body>
</html>
|
2.3.3. getter和setter¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <!doctype html>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<h2>{{ fullName }}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
firstName: "jiedi",
secondName: "zhao",
},
computed:{
// fullName: function(){
// return this.firstName+ this.secondName
// },
fullName: {
get: function (){
return this.firstName + " " + this.secondName
},
set: function (newValue){
const names = newValue.split(" ")
this.firstName = names[0]
this.secondName =names[1]
}
}
}
})
</script>
</body>
</html>
|
2.3.4. 计算属性和methods的对比¶
计算属性是缓存的, 方法是不缓存的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <!DOCTYPE html>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>{{ fullName }}</h2>
<h2>{{ fullName }}</h2>
<h2>{{ fullName }}</h2>
<h2>{{ fullName }}</h2>
<h2>{{ getFullName() }}</h2>
<h2>{{ getFullName() }}</h2>
<h2>{{ getFullName() }}</h2>
<h2>{{ getFullName() }}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
firstName: "jie di",
secondName: "zhao",
},
methods:{
getFullName: function(){
console.log("------getFullName------")
return this.secondName + " " + this.firstName
},
},
computed: {
fullName: function () {
console.log("------fullName------")
return this.secondName + " " + this.firstName
}
}
})
</script>
</body>
</html>
|
2.4. 事件监听¶
事件监听用于在用户点击、拖拽等场景。
2.4.1. 监听基本使用¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <!doctype html>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="../js/vue.js"></script>
<div id="app">
<h2>{{ cnt }}</h2>
<button @click="add">+</button>
<button @click="sub">-</button>
</div>
<script>
let app = new Vue({
el: "#app",
data: {
cnt:1,
},
methods:{
add: function (){
this.cnt+=1
console.log("-----add-------" )
},
sub: function(){
this.cnt-=1
console.log("-----sub-------" )
}
}
})
</script>
</body>
</html>
|
2.4.2. 参数传递¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <!DOCTYPE html>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<button @click="bntClick">按钮1</button>
<button @click="bntClick2(12,$event)">按钮2</button>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
cnt: 1,
},
methods:{
bntClick(event){
console.log(event)
},
bntClick2(abc,event){
console.log("第一个参数:" + abc)
console.log("第二个参数:" + event)
},
}
})
</script>
</body>
</html>
|
2.4.3. 修饰符¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | <!DOCTYPE html>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<div @click="divClick">
<button @click.stop="btnClick">button1</button>
</div>
<!-- <div @click="divClick">-->
<!-- <button @click="btnClick">button1</button>-->
<!-- </div>-->
<form action="baidu">
<input type="submit" value="提交" @click.prevent="submitClick">
</form>
<input type="text" value="提交2" @keyup.enter="keyup">
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
},
methods:{
btnClick(){
console.log("btn click")
},
divClick(){
console.log("div click")
},
submitClick(){
console.log("div click")
},
keyup(){
console.log("key up")
}
}
})
</script>
</body>
</html>
|
2.5. 条件判断¶
2.5.1. v-if¶
简单的判定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <!DOCTYPE html>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!-- <h2 v-if="isShow">{{ cnt }}</h2>-->
<h2 v-if="isShow">
<div>abc</div>
<div>abc</div>
<div>abc</div>
{{ message }}
</h2>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
isShow: true,
message: "abc",
}
})
</script>
</body>
</html>
|
2.5.2. v-else-if¶
稍微复杂的判定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | <!DOCTYPE html>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2 v-if="score>90">优秀 </h2>
<h2 v-else-if="score>80">良好</h2>
<h2 v-else-if="score>60">及格 </h2>
<h2 v-else> 不及格</h2>
<br>
<br>
<br>
<h2 > {{result}} </h2>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
score: 80
},
computed:{
result(){
let message=''
if (this.score >90){
message ="优秀"
}
else if (this.score >80){
message="良好"
}
else if (this.score >60){
message="及格"
}
else {
message = "不及格"
}
return message
},
}
})
</script>
</body>
</html>
|
2.5.3. 用户登录案例¶
进行一个用户登录切换的案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <!DOCTYPE html>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<span v-if="currentType == 'username'">用户名</span>
<span v-if="currentType == 'email'">用户邮箱</span>
<input type="text"> </input>
<button @click="btnClick"> 切登录方式</button>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
currentType: "username",
},
methods:{
btnClick(){
if (this.currentType == "username" ){
this.currentType="email"
}
else if (this.currentType == "email" ){
this.currentType="username"
}
}
}
})
</script>
</body>
</html>
|
2.5.4. v-show¶
当需要在显示和隐藏之间切回频繁的时候使用 v-show。只有一次切回使用v-if 。
2.6. 循环¶
2.6.1. v-for遍历数组¶
简单遍历数组样例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <!DOCTYPE html>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="(name,index) in names ">{{index }} {{ name}}</li>
</ul>
<ul>
<li v-for="(v,k,index) in person ">{{index }} {{ k}} {{ v}}</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
names: [ "panda","pdna02", "panda03"],
person:{
name: 'zhaojiedi',
age: 28,
weight: 60,
}
}
})
</script>
</body>
</html>
|
2.6.2. v-for遍历对象¶
简单遍历数组样例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <!DOCTYPE html>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="(v,k,index) in person ">{{index }} {{ k}} {{ v}}</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
person:{
name: 'zhaojiedi',
age: 28,
weight: 60,
}
}
})
</script>
</body>
</html>
|
2.6.3. v-for遍历添加key¶
添加key避免插入对象导致大量的对象移动。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | <!DOCTYPE html>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="(name,index) in names " :key="name">{{index }} {{ name}}</li>
</ul>
<button @click="btnClick">添加</button>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
names: [ "panda","pdna02", "panda03"],
person:{
name: 'zhaojiedi',
age: 28,
weight: 60,
}
},
methods:{
btnClick(){
this.names.push("panda05")
},
}
})
</script>
</body>
</html>
|
2.6.4. v-for数组哪些是响应式的¶
目前一些数组操作是支持响应式的, 不是所有修改都是响应式的。 通过索引方式修改对象是无法响应式的。可以通过splice来实现。 或者使用vue.set方式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | <!DOCTYPE html>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="(name,index) in names " :key="name">{{index }} {{ name}}</li>
</ul>
<button @click="btnClick">添加</button>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: "#app",
data: {
names: [ "panda","pdna02", "panda03"],
person:{
name: 'zhaojiedi',
age: 28,
weight: 60,
}
},
methods:{
btnClick(){
//push
// pop
// unshift
// splice
// sort
// reverse
this.names.push("panda05")
// 这是非响应式的。
this.names[0]="zhaojiedi"
// 这是响应式的
this.names.splice(1,1,"zhaojiedi")
//这是是响应式的
Vue.set(this.names,0,'zhaojiedi')
},
}
})
</script>
</body>
</html>
|
2.7. 购入车案例¶
2.7.2. 详细代码¶
下面展示各个代码的详细内容。
2.7.2.1. html¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | <!DOCTYPE html>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="app">
<div v-if="infos.length>=1">
<table>
<th>
<td>书籍名称</td>
<td>出版日期</td>
<td>价格</td>
<td>购买数量</td>
<td>操作</td>
</th>
<tr v-for="(item,index) in infos" >
<td>{{index}}</td>
<td>{{item.name}}</td>
<td>{{item.date}}</td>
<td>{{item.price|formatPrice}}</td>
<td>
<button @click="sub(item)" :disabled="item.count<=1">-</button>
{{item.count}}
<button @click="add(item)">+</button>
</td>
<td><button @click="removeLine(index)">移除</button></td>
</tr>
</table>
总价: {{totalPrice|formatPrice}}
</div>
<h2 v-else>没有商品的</h2>
</div>
<script src="../js/vue.js"></script>
<script src="./main.js"></script>
</body>
</html>
|
2.7.2.2. style¶
1 2 3 4 5 6 7 8 9 10 11 12 13 | table{
border-spacing: 0;
}
th,td{
padding: 8px 16px;
border: 1px solid #e9e9e9;
text-align: left;
}
th{
background-color: #f7f7f7;
color: #5c6b77;
font-weight: 600;
}
|
2.7.2.3. js¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | let app = new Vue({
infos: [
{"name": "算法导论", "date": "2006-9", "count": 1, "price": 85},
{"name": "编程艺术", "date": "2006-2", "count": 1, "price": 59},
{"name": "编程珠玑", "date": "2008-10", "count": 1, "price": 39},
{"name": "代码大全", "date": "2006-3", "count": 1, "price": 128},
],
},
methods: {
add(item) {
console.log("add")
item.count++
},
sub(item) {
item.count--
},
removeLine(index) {
this.infos.splice(index, 1)
}
},
filters: {
formatPrice(price) {
return "¥ " + price.toFixed(2)
}
},
computed: {
totalPrice() {
let totalPriceSum = 0
for (let info of this.infos) {
totalPriceSum += info.count * info.price
}
return totalPriceSum
}
}
})
|