简介
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
options
el:
- 类型:string|HTMLElement
- 作用:决定Vue以后会管理哪一个Dom
data:
- 类型:Object
- 作用:Vue实例对应的对象
methods:
- 类型:{[key: value]: function}
- 作用:定义属于Vue的一些方法,可以在其他地方调用,也可以在指令中使用
Vue的生命周期
生命周期:事物从诞生到消亡的整个过程
Vue生命周期:
代码规范
一般缩进4个空格,但是前段缩进2个空格
基础语法
插值操作
mustache:{{}}
v-once
<h2 v-once>{{message}}</h2>
标签中的内容只渲染一次
v-html
将标签中的html标签去除
<h2>{{url}}</h2>
<h2 v-html="url"></h2>
v-text
和mustache插值操作相同,但是会将消息覆盖,不建议使用
v-pre
将内容原封不动的显示出来,不做任何解析
<h2>{{message}}</h2>
<!--展示原来的内容-->
<h2 v-pre>{{message}}</h2>
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>
{{message}}
</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: 'Hello World'
}
})
}, 1000)
</script>
</body>
</html>
v-bind
v-bind绑定基本属性
v-bind:src
v-bind:href
绑定标签的属性
<div id="app">
<!--错误的做法:这里不可以使用mustache语法-->
<!--<img src="{{imgURL}}" alt="">-->
<!--正确的做法:使用v-bind指令-->
<img v-bind:src="imgURL" alt="">
<a v-bind:href="aHref">百度一下</a>
<!--语法糖的写法-->
<img :src="imgURL" alt="">
<a :href="aHref">百度一下</a>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'Hello World',
imgURL: 'https://imgcps.jd.com/ling4/100009077475/5Lqs6YCJ5aW96LSn/5L2g5YC85b6X5oul5pyJ/p-5bd8253082acdd181d02fa3b/5517aa3e/cr/s/q.jpg',
aHref: 'https://www.baidu.com'
}
})
</script>
v-bind动态绑定class
- 对象语法:作业:class=’{类名: boolean}’
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.active {
color: red;
}
</style>
</head>
<body>
<div id="app">
<!--<h2 class="active">{{message}}</h2>-->
<!--<h2 :class="active">{{message}}</h2>-->
<!--<h2 v-bind:class="{key1: value1, key2: value2}">{{message}}</h2>-->
<!--<h2 v-bind:class="{类名: true, 类名2: boolean}">{{message}}</h2>-->
<h2 class="title" v-bind:class="{active: isActive, line: isLine}">{{message}}</h2>
<h2 class="title" v-bind:class="getClasses()">{{message}}</h2>
<button v-on:click="btnClick">按钮</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'Hello World',
isActive: true,
isLine: true
},
methods: {
btnClick: function () {
this.isActive = !this.isActive;
},
getClasses: function () {
return {active: this.isActive, line: this.isLine}
}
}
})
</script>
</body>
</html>
- 数组语法
<div id="app">
<h2 class="title" :class="[active,line]">{{message}}</h2>
<h2 class="title" :class="getClasses()">{{message}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'Hello World',
active: 'aaaaa',
line: 'bbbbb'
},
methods: {
getClasses: function () {
return [this.active,this.line];
}
}
})
</script>
v-bind绑定style
-
对象语法
<div id="app"> <!--<h2 :style="{key(属性名): value(属性值)}">{{message}}</h2>--> <!--'50px'必须加上单引号,否则是当做一个变量去解析的--> <!--<h2 :style="{fontSize: '50px'}">{{message}}</h2>--> <!--把finalSize当成一个变量去使用--> <!--<h2 :style="{fontSize: finalSize}">{{message}}</h2>--> <!--<h2 :style="{fontSize: finalSize + 'px',color: finalColor}">{{message}}</h2>--> <h2 :style="getStyles()">{{message}}</h2> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { message: 'Hello World', finalSize: 100, finalColor: 'red' }, methods: { getStyles: function () { return {fontSize: this.finalSize + 'px',color: this.finalColor} } } }) </script>
-
数组语法(使用的少)
<div id="app"> <h2 :style="[baseStyle,baseStyle1]">{{message}}</h2> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { message: 'Hello World', baseStyle: {backgroundColor: 'red'}, baseStyle1: {fontSize: '100px'} } }) </script>
作业:点击列表中的哪一项,那么该项的文字就变为红色
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.active {
color: red;
}
</style>
</head>
<body>
<!--作业需求:点击列表中的哪一项,那么该项的文字就变为红色-->
<div id="app">
<ul>
<li v-for="(item, index) in movies"
:class="{active: currentIndex === index}"
@click="liClick(index)">
{{index}}.{{item}}
</li>
<!--<li :class="{active: 0===currentIndex}"></li>-->
<!--<li :class="{active: 1===currentIndex}"></li>-->
<!--<li :class="{active: 2===currentIndex}"></li>-->
<!--<li :class="{active: 3===currentIndex}"></li>-->
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
movies: ['教父','千与千寻','龙猫','红辣椒'],
currentIndex: 0
},
methods: {
liClick(index) {
this.currentIndex = index
}
}
})
</script>
</body>
</html>
计算属性
-
基本使用
<div id="app"> <h2>{{firstName + ' ' + lastName}}</h2> <h2>{{firstName}} {{lastName}}</h2> <h2>{{getFullName()}}</h2> <h2>{{fullName}}</h2> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { firstName: 'Einstein', lastName: 'Albert' }, // computed:计算属性() computed: { fullName: function () { return this.firstName + ' ' + this.lastName; } }, methods: { getFullName: function () { return this.firstName + ' ' + this.lastName; } } }) </script>
-
复杂操作
<div id="app"> <h2>总价格:{{totalPrice}}</h2> </div> <script src="../js/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { books: [ {id: 114514, name: 'Unix编程艺术', price: 119}, {id: 128061, name: '代码大全', price: 105}, {id: 345683, name: '深入理解计算机原理', price: 678}, {id: 110312, name: '现代操作系统', price: 87}, ] }, computed: { // filter/map/reduce totalPrice: function () { let result = 0; for (let i=0; i < this.books.length; i++) { result += this.books[i].price } return result // for (let i in this.books) { // // } // // for (let book in this.books) { // // } } } }) </script>
计算属性的getter和setter
<div id="app">
<h2>{{fullName}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
firstName: 'Einstein',
lastName: 'Albert'
},
computed: {
// fullName: function () {
// return this.firstName + ' ' + this.lastName
// }
// 计算属性一般是没有set方法的,只读属性
fullName: {
set: function (newValue) {
// console.log('----' + newValue)
const names = newValue.split(' ');
this.firstName = names[0];
this.lastName = names[1];
},
get: function () {
return this.firstName + ' ' + this.lastName
}
},
}
})
</script>
计算属性和methods的对比
-
计算属性:会产生缓存,如果结果相同则不会重新进行计算,速度快
-
methods:不会产生缓存,无论如何都要重新进行计算,速度较慢
<div id="app"> <!--1.直接拼接:语法过于繁琐--> <h2>{{firstName}} {{lastName}}</h2> <!--2.通过定义methods--> <!--<h2>{{getFullName()}}</h2>--> <!--<h2>{{getFullName()}}</h2>--> <!--<h2>{{getFullName()}}</h2>--> <!--<h2>{{getFullName()}}</h2>--> <!--3.通过computed--> <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: 'Einstein', lastName: 'Albert' }, methods: { getFullName: function () { console.log('getFullName'); return this.firstName + ' ' + this.lastName } }, computed: { fullName: function () { console.log('fullName'); return this.firstName + ' ' + this.lastName } } }) </script>
计算属性只打印了一次,而methods打印了四次,证明计算属性存在缓存。
v-on
v-on的参数传递问题
-
如果事件所调用的方法没有参数,则使不使用括号没有区别
<button @click="btn1Click()">按钮1</button> <button @click="btn1Click">按钮1</button>
-
如果方法本身需要参数,但是使用的时候省略了小括号,这时Vue会默认将浏览器所生产的event事件作为参数传入到方法
<!--2.在事件定义时,写函数时省略了小括号,但是方法本身是需要一个参数的,这个时候 Vue会默认将浏览器生成的event事件对象作为参数传入到方法--> <button @click="btn2Click(123)">按钮2</button> <button @click="btn2Click()">按钮2</button> <button @click="btn2Click">按钮2</button>
第一个按钮传入参数123,打印出123,第二个按钮有小括号但没有传递任何参数,此时打印undefined,第三个按钮没有小括号,因此打印出此时的鼠标事件MouseEvent
-
方法定义时,我们需要event对象,同时又需要其他参数
<!--在调用方法时,如何手动的获取到浏览器参数的event对象:$event--> <button @click="btn3Click(123, $event)">按钮3</button>
此时我们需要使用
$event
来手动的获取到浏览器的参数,如果我们按照下面的代码来调用方法<button @click="btn3Click(123, event)">按钮3</button>
此时event作为Vue里面data的一个变量,如果我们没有定义相关的变量,则浏览器会报错
v-on修饰符的使用
-
.stop
<!--1. .stop修饰符的使用--> <!--点击按钮的时候不会触发divClick函数,只会触发btnClick函数--> <div @click="divClick"> aaaaaaa <button @click.stop="btnClick">按钮</button> </div>
使用
.stop
修饰符可以使当点击按钮的时候不会同时触发divClick函数,只会触发btnClick函数 -
.prevent
<!--阻止自动提交--> <form action="baidu"> <input type="submit" value="提交" @click.prevent="submitClick"> </form>
使用
.prevent
修饰符可以使表单不提交,只触发submitClick函数 -
.enter(监听键盘某一个键的键帽)
<input type="text" @keyup.enter="keyUp">
只有按下回车键的时候才会触发keyUp函数
注意:
keyup
是指松开键帽时才会执行函数 -
.once
<button @click.once="btn2Click">按钮2</button>
只会执行一次点击按钮所触发的函数,之后再点击的话不会执行btn2Click函数
条件判断
v-if
<div id="app">
<h2 v-if="isShow">
<div>abc</div>
<div>abc</div>
<div>abc</div>
<div>abc</div>
{{message}}
</h2>
</div>
isShow为变量,如果isShow为true,则显示下面的标签内容,如果isShow为false,则不显示下面的标签内容。
v-else
<div id="app">
<h2 v-if="isShow">
<div>abc</div>
<div>abc</div>
<div>abc</div>
<div>abc</div>
{{message}}
</h2>
<h1 v-else>isShow为false时,显示我</h1>
</div>
v-else-if
<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 showMessage = ' ';
if (this.score >= 90) {
showMessage = '优秀';
} else if (this.score >= 80) {
showMessage = '良好';
} else if (this.score >= 60) {
showMessage = '及格';
} else {
showMessage = '不及格';
}
return showMessage;
}
}
})
</script>
建议使用计算属性(computed)
案例:登录切换
用户在登录的时候可以切换账号登录和邮箱登录
<div id="app">
<span v-if="isUser">
<label for="username">用户账号</label>
<input type="text" id="username" placeholder="用户账号">
</span>
<span v-else>
<label for="email">用户邮箱</label>
<input type="text" id="email" placeholder="用户邮箱">
</span>
<button @click="change">切换类型</button>
</div>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
isUser: true
},
methods: {
change() {
this.isUser = !this.isUser;
}
}
})
</script>
使用v-if
和v-else
来进行选择
小问题:用户输入了文字之后想更改登录方式,此时切换登录方式输入框里面的文字不会被清空,是由于虚拟Dom所引起的,使得js复用同一个输入框所导致。
解决方案:在输入框之后添加key
属性来解决
<input type="text" id="username" placeholder="用户账号" key="username">
<input type="text" id="email" placeholder="用户邮箱" key="email">