v-text指令和Mustache语法的比较:
两者都是将数据显示在界面中,但是v-text没有Mustache语法灵活,在上图中,我们可以看到,v-text指令会覆盖原本标签中的值。在做字符串拼接的场景下,v-text指令将不再适合。
对象语法
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<style type="text/css">
.active {
color: red;
}
style>
head>
<body>
<div id="app">
<h2 :class="active">{{message}}h2>
<h2 class="title" :class="getClasses()">{{message}}h2>
<button v-on:click="click">点击切换颜色button>
div>
<script src="../js/vue.js">script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'Hello',
active: 'active',
isActive: true,
isLine: true
},
methods: {
click: function () {
this.isActive = !this.isActive;
},
getClasses: function () {
return {active: this.isActive, line: this.isLine};
}
}
})
script>
body>
html>
计算属性的使用场景:当我们需要对数据进行转化后再显示,或者需要将多个数据结合起来显示时,我们可以使用计算属性来进行处理。
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
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: 1001, name: 'Linux开发', price: 58},
{id: 1002, name: '软件测试技术', price: 42},
{id: 1003, name: '软件项目管理', price: 60},
]
},
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>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div id="app">
<h2>{{fullName}}h2>
div>
<script src="../js/vue.js">script>
<script>
const app = new Vue({
el: '#app',
data: {
firstName: '太子',
lastName: '殿下!'
},
computed: {
/*fullName: function () {
return this.firstName + ' ' + this.lastName;
}*/
fullName: {
set: function (newValue) {
let names = newValue.split(' ');
this.firstName = names[0];
this.lastName = names[1];
},
get: function () {
return this.firstName + ' ' + this.lastName;
}
}
}
})
script>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div id="app">
<h2>{{getFullName()}}h2>
<h2>{{getFullName()}}h2>
<h2>{{getFullName()}}h2>
<h2>{{getFullName()}}h2>
<hr>
<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: '太子',
lastName: '殿下'
},
methods: {
getFullName: function () {
console.log('getFullName');
return this.firstName + ' ' + this.lastName;
}
},
computed: {
fullName: function () {
console.log('fullName');
return this.firstName + ' ' + this.lastName;
}
}
})
script>
body>
html>
计算属性会进行缓存,如果多次使用时,计算属性只会被调用一次。
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div id="app">
<button @click="btn1Click">按钮1button>
<button @click="btn2Click">按钮2button>
<button @click="btn3Click(num, $event)">按钮3button>
div>
<script src="../js/vue.js">script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'Hello',
num: 888
},
methods: {
btn1Click() {
console.log('btn1被点击了');
},
btn2Click(num) {
console.log('btn2被点击了---->' + num);
},
btn3Click(num, event) {
console.log(num + '----------' + event);
}
}
})
script>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div id="app">
<div @click="divClick">
aaa
<button @click.stop="btnClick">按钮button>
div>
<form action="baidu">
<input type="submit" @click.prevent="submitClick">
form>
<input type="text" @keyup.enter="inputClick">
<br>
<button @click.once="btn1Click">只有第一次点击生效的按钮button>
div>
<script src="../js/vue.js">script>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'Hello'
},
methods: {
divClick() {
console.log('divClick');
},
btnClick() {
console.log('btnClick');
},
submitClick() {
console.log('submitClick');
},
inputClick() {
console.log('inputClick');
},
btn1Click() {
console.log('btn1Click');
}
}
})
script>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
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>
<h1>{{result}}h1>
div>
<script src="../js/vue.js">script>
<script>
const app = new Vue({
el: '#app',
data: {
score: 92
},
computed: {
result() {
let newScore = this.score;
let result = '';
if (newScore>90) {
result = '优秀';
}else if (newScore>80) {
result = '良好';
}else if (newScore>60) {
result = '及格';
}else {
result = '不及格';
}
return result;
}
}
})
script>
body>
html>
问题:如果我们在有输入内容的情况下,切换了类型,我们会发现文字依然显示之前的输入的内容?
解析:这是因为Vue在进行DOM渲染时,出于性能考虑,会尽可能的复用已经存在的元素,而不是重新创建新的元素。在上面的案例中,Vue内部会发现原来的input元素不再使用,直接作为else中的input来使用了。
解决方案:如果我们不希望Vue出现类似重复利用的问题,可以给对应的input添加key。并且我们需要保证key的不同。
v-show和v-if的区别:
v-if当条件为false时,压根不会有对应的元素在DOM中。
v-show当条件为false时,仅仅是将元素的display属性设置为none而已。
开发中如何选择呢?
当需要在显示与隐藏之间切换很频繁时,使用v-show。
当只有一次切换时,通过使用v-if。
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div id="app">
<ul>
<li v-for="item in student">{{item}}li>
ul>
<ul>
<li v-for="(value, key) in student">{{value}}--{{key}}li>
ul>
<ul>
<li v-for="(value, key, index) in student">{{value}}--{{key}}--{{index+1}}li>
ul>
div>
<script src="../js/vue.js">script>
<script>
const app = new Vue({
el: '#app',
data: {
student: {
name: '殿下',
aga: 22,
sex: '男',
score: 98
}
}
})
script>
body>
html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<div id="app">
<ul>
<li v-for="letter in letters">{{letter}}li>
<button @click="btnClick">按钮button>
ul>
div>
<script src="../js/vue.js">script>
<script>
const app = new Vue({
el: '#app',
data: {
letters: ['A', 'B', 'C', 'D', 'E']
},
methods: {
btnClick() {
//1.push()方法 在数组的最后添加一个或多个元素
/*this.letters.push('F');*/
//2.pop()方法 从数组的最后删除一个或多个元素
/*this.letters.pop();*/
//3.unshift()方法 在数组的最前面添加一个或多个元素
/*this.letters.unshift('aaa', 'bbb');*/
//4.shift()方法 从数组的最前面删除元素
/*this.letters.shift();*/
//5.splice()方法
/*this.letters.splice(1, 2); //删除元素 */
/*this.letters.splice(1, 2, 'bb', 'cc'); //替换元素*/
/* this.letters.splice(1, 0, 'bb'); //插入元素*/
//6.sort()方法
/*this.letters.sort();*/
//7.reverse()方法
/*this.letters.reverse();*/
//注意:修改数组元素中的值不是响应式的
/*this.letters[1] = 'bbb';*/
/*this.letters.splice(1, 1, 'bb');*/
Vue.set(this.letters, 1, 'bb');
}
}
})
script>
body>
html>
注意:当数组中的某个元素值被修改时,相应页面的值不修改。
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<style>
.active {
color: red;
}
style>
head>
<body>
<div id="app">
<ul>
<li v-for="(movie, index) in movies" :class="{active: currentIndex === index}" @click="liClick(index)">{{index}} {{movie}}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>
index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<link rel="stylesheet" href="style.css">
head>
<body>
<div id="app">
<table cellpadding="0" cellspacing="0" width="500px" height="300px">
<thead>
<tr align="center" style="background: rgba(0,0,0,0.1);">
<th>th>
<th>书籍名称th>
<th>出版日期th>
<th>价格th>
<th>购买数量th>
<th>操作th>
tr>
thead>
<tbody>
<tr v-for="(book,index) in books" align="center">
<td width="60px">{{book.id}}td>
<td>{{book.name}}td>
<td>{{book.date}}td>
<td>{{book.price | showPrice}}td>
<td>
<button @click="decrement(index)" :disabled="book.count <= 1">-button>
{{book.count}}
<button @click="increment(index)">+button>
td>
<td width="60px"><button @click="deleteOne(index)">移除button>td>
tr>
tbody>
table>
<br>
<button @click="clear()">清空购物车button>
<h2>总价格:{{totalPrice | showPrice}}h2>
<h2 v-show="books.length === 0" style="color: red">当前购物车还没有书籍!h2>
div>
<script src="../js/vue.js">script>
<script src="main.js">script>
body>
html>
style.css
tr td,th {
border: 1px solid rgba(0,0,0,0.2);
}
table {
border: 1px solid rgba(0,0,0,0.2);
}
main.js
var app = new Vue({
el: '#app',
data: {
books: [{
id: 1,
name: '《算法导论》',
date: '2006-9',
price: 85,
count: 1
},
{
id: 2,
name: '《UNIX编程艺术》',
date: '2006-2',
price: 59,
count: 1
},
{
id: 3,
name: '《编程珠玑》',
date: '2008-10',
price: 39,
count: 1
},
{
id: 4,
name: '《代码大全》',
date: '2006-3',
price: 128,
count: 1
},
]
},
computed: {
totalPrice() {
var totalPrice = 0;
for (var i=0; i < this.books.length; i++) {
totalPrice = totalPrice + (this.books[i].count) * (this.books[i].price);
}
return totalPrice;
}
},
methods: {
//自减书籍数量
decrement(index) {
this.books[index].count--;
},
//自增书籍数量
increment(index) {
this.books[index].count++;
},
//删除一个书籍
deleteOne(index) {
var conf = confirm("确认删除吗?");
if (conf == true) {
this.books.splice(index, 1);
}
},
//清空所有书籍
clear() {
var clear = confirm('确定清空购物车吗?该操作确定后将不可撤销!');
if (clear) {
this.books.splice(0, this.books.length);
}
}
},
filters: {
showPrice(price) {
return '¥' + price.toFixed(2);
}
}
})