MVVM架构及Vue语法
1. MVVM架构

2. Vue语法
2.1 动态绑定v-bind
2.1.1 基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<img v-bind:src="imageURL">
<!--语法糖的写法-->
<img :src="imageURL">
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
message: '你好呀',
imageURL: 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1819216937,2118754409&fm=26&gp=0.jpg'
}
})
</script>
</body>
</html>
动态绑定,需要解析的绑定
2.1.2 v-bind动态绑定class
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<style>
.active{
color: red;
}
</style>
<body>
<div id="app">
<h2 :class="{active: isActive,line:isLine}">{{message}}</h2>
<button v-on:click="btnClick">按钮</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
message: '你好啊',
isActive: true,
isLine: true,
},
methods: {
btnClick: function (){
this.isActive=!this.isActive
}
}
})
</script>
</body>
</html>
数组语法:
2.1.3 v-bind动态绑定style对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<style>
.active{
color: red;
}
</style>
<body>
<div id="app">
<!--'50px'必须要加上单引号,否则就是被当做一个变量去解析-->
<!--finalSize当做一个变量使用-->
<h2 :style="{fontSize: finalSize + 'px',color: finalColor}">{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
message: '你好啊',
finalSize: 200,
finalColor: 'red'
}
})
</script>
</body>
</html>
2.2 mustache语法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>{{message}}</h2>
<!--mustache语法中,不仅仅可以直接协变量,也可以写简单的表达式-->
<h2>{{firstName + " "+ lastName}}</h2>
<h2>{{firstName}} {{lastName}}</h2>
<h2>{{counter*2}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
message: '你好啊',
firstName: 'Kobe',
lastName: 'Bryant',
counter: 100
}
})
</script>
</body>
</html>
2.3 v-model
2.3.1 v-model的使用和原理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<input type="text" v-model="message">
{{message}}
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
</script>
</body>
</html>
2.3.2 v-model结合radio类型
2.3.3 v-model结合checkbox
- label好处:增强了表单控制间的关系,点击文字的时候都可以选中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--1.checkbox单选框-->
<label for="agree">
<input type="checkbox" id="agree" v-model="isAgree">同意协议
</label>
<h2>您选择的是:{{isAgree}}</h2>
<button :disabled="!isAgree">下一步</button>
<!--1.checkbox多选框-->
<input type="checkbox" value="篮球" v-model="hobbies">篮球
<input type="checkbox" value="足球" v-model="hobbies">足球
<input type="checkbox" value="乒乓球" v-model="hobbies">乒乓球
<input type="checkbox" value="羽毛球" v-model="hobbies">羽毛球
<h2>您的爱好是:{{hobbies}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
isAgree: false,
hobbies: []
}
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--1.选择一个-->
<select name="abc" v-model="fruit">
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="葡萄">葡萄</option>
<option value="橘子">橘子</option>
</select>
<h2>您选择的水果是:{{fruit}}</h2>
<!--1.选择多个-->
<select name="abc" v-model="fruits" multiple>
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="葡萄">葡萄</option>
<option value="橘子">橘子</option>
</select>
<h2>您选择的水果是:{{fruits}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
message: '你好啊',
fruit: '苹果',
fruits: '苹果'
}
})
</script>
</body>
</html>
2.3.4 v-model结合select类型
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--1.选择一个-->
<select name="abc" v-model="fruit">
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="葡萄">葡萄</option>
<option value="橘子">橘子</option>
</select>
<h2>您选择的水果是:{{fruit}}</h2>
<!--1.选择多个-->
<select name="abc" v-model="fruits" multiple>
<option value="苹果">苹果</option>
<option value="香蕉">香蕉</option>
<option value="葡萄">葡萄</option>
<option value="橘子">橘子</option>
</select>
<h2>您选择的水果是:{{fruits}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
message: '你好啊',
fruit: '苹果',
fruits: '苹果'
}
})
</script>
</body>
</html>
2.3.5 v-model修饰符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--1.修饰符:lazy-->
<input type="text" v-model.lazy="message">
<h2>{{message}}</h2>
<!--2.修饰符:number-->
<input type="number" v-model.number="age">
<h2>{{typeof age}}</h2>
<!--3.修饰符:trim-->
<input type="text" v-model.trim="name">
<h2>您输入的名字:{{name}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
message: '你好啊',
age: '',
name: ''
}
})
</script>
</body>
</html>
2.4 计算属性computed
2.4.1 计算属性的基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>{{getFullName()}}</h2>
<h2>{{fullName}}</h2>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
firstName: 'Lebron',
lastName: 'James'
},
//计算属性()
computed: {
fullName: function (){
return this.firstName + ' ' + this.lastName
}
},
methods: {
getFullName(){
return this.firstName + '' + this.lastName
}
}
})
</script>
</html>
2.4.2 计算属性的复杂操作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>总价格:{{TotalPrice}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data:{
books:[
{id:110,name:'Linux编程艺术',price:119},
{id:111,name:'代码大全',price:105},
{id:112,name:'深入理解计算机原理',price:98},
{id:113,name:'现代操作系统',price:55},
]
},
computed:{
TotalPrice: function (){
let result=0
for(let i=0;i<this.books.length;i++){
result +=this.books[i].price;
}
return result;
}
}
})
</script>
</body>
</html>
2.4.3 计算属性的setter和getter
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>{{fullName}}</h2>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
firstName: 'Kobe',
lastName: 'Bryant'
},
computed: {
fullName:{
set: function (){
},
get: function (){
return this.firstName+ ' '+ this.lastName;
}
}
}
})
</script>
</html>
一般的写法都是省略了set方法,然后将get方法和属性名简写了,本质上是调用了get方法,可以通过set方法改变get方法。kobe->james
2.4.4 计算属性和methods
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>{{getFullName()}}</h2>
<h2>{{getFullName()}}</h2>
<h2>{{getFullName()}}</h2>
<h2>{{getFullName()}}</h2>
<h2>{{FullName}}</h2>
<h2>{{FullName}}</h2>
<h2>{{FullName}}</h2>
<h2>{{FullName}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
firstName: 'Kobe',
lastName: 'Bryant'
},
computed: {
FullName: function (){
console.log('FullName')
return this.firstName + ' ' + this.lastName
}
},
methods: {
getFullName: function () {
console.log('getFullName')
return this.firstName + ' ' + this.lastName
}
}
})
</script>
</body>
</html>
计算属性使用了缓存,而methods没有!
2.5 事件监听v-on
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>{{counter}}</h2>
<button @click="decrement">+</button>
<button @click="increment">_</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
counter: 0
},
methods: {
increment(){
this.counter--
},
decrement(){
this.counter++
}
}
})
</script>
</body>
</html>
2.5.1 v-on的参数传递
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<button @click="btn1Click">按钮1</button>
<!--在事件定义时,写方法时省略了小括号,但是方法本身需要一个参数,这个时候Vue会默认将浏览器产生的event事件对象作为参数传入到方法-->
<button @click="btn2Click">按钮2</button>
<!--在方法定义时,需要event对象,同时又需要其他参数-->
<!--在调用方法时,如何手动获取到浏览器参数的event对象? $event-->
<button @click="btn3Click(123,$event)">按钮3</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
},
methods: {
btn1Click(){
console.log("btn1Click")
},
//如果函数需要参数,但是没有传入,那么函数的形参为undefined
btn2Click(event){
console.log('-------------',event)
},
btn3Click(abc,event){
console.log('++++++++++',abc,event)
}
}
})
</script>
</body>
</html>
2.5.2 v-on的修饰符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--1.stop修饰符的使用-->
<div @click="divClick">
<button @click.stop="btnClick" >按钮</button>
</div>
<br>
<!--2.stop修饰符的使用-->
<form action="baidu">
<input type="submit" value="提交" @click.prevent="submitClick">
</form>
<!--3.监听某个键盘的键帽-->
<input type="text" @keyup.enter="keyUp">
<!--4.once修饰符的使用-->
<button @click.once="btn2Click">按钮2</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
message: '你好啊'
},
methods: {
divClick() {
console.log('divClick')
},
btnClick() {
console.log('btnClick')
},
submitClick() {
console.log('submitClick')
},
keyUp() {
console.log('keyUp')
},
btn2Click() {
console.log("btn2Click")
}
}
})
</script>
</body>
</html>
- .stop:阻止事件冒泡
- .prevent:阻止默认事件发生
- .enter:指定键帽
- .once:只触发一次
、
2.6 v-show、v-if
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<!--v-if:当条件为false时,包含v-if指令的元素,不会存在在DOM中-->
<h2 v-if="isShow" id="aaa">{{message}}</h2>
<!--v-show:当条件为false时,v-show只是给我们的元素添加了一个行内样式:dispaly: none-->
<h2 v-show="isShow" id="bbb">{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
message: '你好啊',
isShow: true
},
methods:{
}
})
</script>
</body>
</html>
2.7 遍历v-for
- 遍历数组
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <!--在遍历的过程中,没有使用索引值(下标值)--> <ul> <li v-for="items in names">{{items}}</li> </ul> <!--2.在遍历的过程中,获取索引的下标值--> <ul> <li v-for="(item,index) in names"> {{index+1}}.{{item}} </li> </ul> </div> <script src="../js/vue.js"></script> <script> const app=new Vue({ el: '#app', data: { names: ['James','Kobe','Curry','Durant'] } }) </script> </body> </html>
- 遍历对象
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <!--1.在遍历对象的过程中,如果只是获取一个值,那么获取到的是value--> <ul> <li v-for="item in info">{{item}}</li> </ul> <!--我们获取key和value,格式(value,key,index)--> <ul> <li v-for="(value,key,index) in info">{{value}}.{{key}}.{{index}}</li> </ul> </div> <script src="../js/vue.js"></script> <script> const app=new Vue({ el: '#app', data: { info: { name: 'James', age: 12, height: 1.88, } } }) </script> </body> </html>
2.8 key值的作用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<ul>
<li v-for="item in letters" :key="item">{{item}}</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
letters: ['a','b','c','d']
}
})
</script>
</body>
</html>
加了==:key==之后,内部的效率会更高!
2.9 其它指令使用
2.9.1 v-once
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app">
<h2>{{message}}</h2>
<h2 v-once>{{message}}</h2>
</div>
</body>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
</script>
</html>
只有一次改变,不随着客户端的改变而改变
2.9.2 v-html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2 v-html="url"></h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
message: '你好啊',
url: '<a href="http://www.baidu.com" target="_blank" rel="external nofollow" >百度一下</a>'
}
})
</script>
</body>
</html>
2.9.3 v-text
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2>{{message}}</h2>
<h2 v-text="message"></h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
</script>
</body>
</html>
v-text仍然不够灵活哈!!!!!!!!!
2.9.4 v-pre
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<h2 v-pre>{{message}}</h2>
<h2 v-text="message"></h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
</script>
</body>
</html>
2.9.5 v-cloak
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
[v-cloak]{
display: none;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<h2>{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
//在vue解析之前,div中有一个属性v-cloak
//在vue解析之后,div中没有属性v-cloak
setTimeout(function (){
const app=new Vue({
el: '#app',
data: {
message: '你好啊'
}
})
},1000)
</script>
</body>
</html>
body中的内容在被Vue实体渲染之前,v-cloak属性是存在的,在被渲染之后,v-cloak属性不存在。
2.9.6 v-if、else-if、v-else
<!DOCTYPE html>
<html lang="en">
<head>
<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>
<h2>{{result}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app=new Vue({
el: '#app',
data: {
score: 99
},
computed: {
result(){
let resultScore=''
if(this.score>=90){
resultScore='优秀'
}else if(this.score>=80){
resultScore='良好'
}
return resultScore
}
}
})
</script>
</body>
</html>