目录
计算属性 computed
在模板中可以直接通过插值语法显示一些data数据,但有些情况需要先对数据进行一些转化后再显示,或者需要将多个数据结合起来显示,可以使用计算属性的方式实现
计算属性会进行缓存,如果多次使用,计算属性只会调用一次
<div id="app">
<h2>{{fullName}}</h2>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
firstName: 'Mebor',
lastName: 'Kimi'
},
// 计算属性
computed: {
fullName: function() {
return this.firstName + ' ' + this.lastName
}
}
})
</script>
计算属性的复杂操作
<div id="app">
总价格:{{totalPrice}}
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
books: [{id: 1, name: 'Unix编程艺术', price: 119},
{id: 2, name: '代码大全', price: 105},
{id: 3, name: '深入理解计算机原理', price: 95},
{id: 4, name: '现代操作系统', price: 94}]
},
computed: {
totalPrice: function() {
return this.books.reduce(function(prev, cur) {
return cur.price + prev;
}, 0);
}
}
})
</script>
计算属性的setter和getter
通常情况下,直接使用getter来读取,在某些情况下,可以使用setter方法
<div id="app">
{{fullName}}
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
firstName: 'Kobe',
lastName: 'Bryant'
},
computed: {
fullName: {
set: function(newValue) {
console.log('-------', newValue)
let names = newValue.split(' ');
this.firstName = names[0];
this.lastName = names[1];
},
get: function() {
return this.firstName + ' ' + this.lastName
}
}
}
})
</script>
事件监听 v-on
在前端开发中,经常需要监听用户发生的事件,比如点击、拖拽等,在Vue中可以使用v-on指令
<div id="app">
<h3>{{counter}}</h3>
<!-- 方法1,适用于操作简单的函数 -->
<!-- <button v-on:click="counter++">+</button>
<button v-on:click="counter--">-</button> -->
<!-- 方法2,调用函数 -->
<!-- 在事件监听时,如果方法不需要额外的参数,方法后的 () 可以不添加 -->
<!-- <button v-on:click="increment">+</button>
<button v-on:click="decrement">-</button> -->
<!-- 语法糖方式 -->
<button @click="increment">+</button>
<button @click="decrement">-</button>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
counter: 0
},
methods: {
increment() {
this.counter++
},
decrement() {
this.counter--
}
}
})
</script>
v-on参数
当通过methods中定义方法,@click调用时,需要注意参数问题
- 如果该方法不需要额外的参数,那么方法后的 () 可以不添加,但是如果方法本身有一个参数,那么会默认将原生事件event参数传递进去;有 () 时,参数默认为undefined
- 如果需要传入某个参数,同时需要event时,可以通过$event传入事件
<!-- 事件调用的方法没有参数 -->
<button @click="btn1Click">按钮1</button>
<!-- 事件调用有其他参数,同时需要event对象 -->
<button @click="btn2Click(123, $event)">按钮2</button>
v-on修饰符
Vue提供了修饰符来帮助我们处理一些事件
- .stop - 调用 event.stopPropagation() 阻止冒泡事件
- .prevent - 调用 event.preventDefault() 阻止默认事件
- .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调
- .native - 监听组件根元素的原生事件
- .once - 只触发一次回调
<div id="app">
<!-- 1. .stop修饰符的使用 阻止冒泡事件,调用 event.stopPropagation() -->
<div @click="divClick">
aaaaaaaaa
<button @click.stop="btnClick">按钮</button>
</div>
<!-- 2. .prevent修饰符的使用 阻止默认事件,调用 event.preventDefault() -->
<form action="baidu">
<!-- 不使用默认提交的方法,自己写方法提交 -->
<input type="submit" value="提交" @click.prevent="submitClick">
</form>
<!-- 3. 监听键盘按键的方法,控制从特定键触发时才触发回调 -->
<!-- 键盘名 -->
<input type="text" @keyup.enter="keyUp">
<!-- 键代码 -->
<input type="text" @keyup.13="keyUp">
<!-- 4. .once修饰符的使用,只触发一次回调 -->
<button @click.once="btn2Click">按钮2</button>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
msg: '你好'
},
methods: {
divClick() {
console.log("divClick");
},
btnClick() {
console.log("btnClick");
},
submitClick() {
console.log("submitClick");
},
keyUp() {
console.log("keyUp");
},
btn2Click() {
console.log("btn2Click");
}
},
})
</script>
条件判断 v-if v-else-if v-else
v-if、v-else-if、v-else这三个指令和JavaScript的条件语句类似,Vue的条件指令可以根据表达式的值在DOM中渲染或销毁元素或组件
v-if后面的条件为false时,对应元素及其子元素不会渲染,也就是根本不会有对应的标签出现在DOM中
<div v-if="score>=90">优秀</div>
<div v-else-if="score>=80">良好</div>
<div v-else-if="score>=60">及格</div>
<div v-else>不及格</div>
条件渲染小案例
<div id="app">
<span v-if="isUser">
<label for="userName">用户账号</label>
<input type="text" placeholder="用户账号" id="userName">
</span>
<span v-else>
<label for="email">用户邮箱</label>
<input type="text" placeholder="用户邮箱" id="email">
</span>
<button @click="changeType">切换类型</button>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
isUser: true
},
methods: {
changeType() {
return this.isUser = !this.isUser
}
},
})
</script>
从图片可以看到一个问题,类型切换后,之前输入的文字依然还在,但是按道理来讲,切换到另一个input元素中,应该并没有内容,为什么会出现这个问题呢?
这是因为Vue在进行DOM渲染时,出于性能考虑,会尽可能的复用已经存在的元素,而不是重新创建新的元素,如何解决呢?
只需要在对应的input中添加属性key,并且保证key的值不同即可
<div id="app">
<span v-if="isUser">
<label for="userName">用户账号</label>
<input type="text" placeholder="用户账号" id="userName" key="userName">
</span>
<span v-else>
<label for="email">用户邮箱</label>
<input type="text" placeholder="用户邮箱" id="email" key="email">
</span>
<button @click="changeType">切换类型</button>
</div>
v-show
v-show和v-if非常相似,也用于决定一个元素是否渲染,不过v-show是当条件为false时,只是将元素的display的属性设置成了none而已;而v-if是直接不会渲染对应的元素。
在开发中当需要频繁的显示与隐藏时,使用v-show,若只有一次切换时,使用v-if
<div id="app">
<h3 v-if="isShow">{{msg}}</h3>
<h3 v-show="isShow">{{msg}}</h3>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
msg: '你好',
isShow: true
}
})
</script>
循环遍历 v-for
当我们有一组数据需要渲染时,可以使用v-for来完成,格式: item in items
v-for遍历数组
<div id="app">
<!-- 1.在遍历的过程中,没有使用索引值(下标值) -->
<ul>
<li v-for="item in names">{{item}}</li>
</ul>
<!-- 2.在遍历的过程中,获取索引值 -->
<ul>
<li v-for="(item, index) in names">{{index+1}}.{{item}}</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
names: ['kobe', 'james', 'curry']
}
})
</script>
v-for遍历对象
<div id="app">
<!-- 1.在遍历对象的过程中,如果只是获取一个值,那么获取到的是value -->
<ul>
<li v-for="item in info">{{item}}</li>
</ul>
<!-- 2.获取key和value 格式: (value, key) -->
<ul>
<li v-for="(value, key) in info">{{key}}: {{value}}</li>
</ul>
<!-- 3.获取key和value和index 格式: (value, key, index) -->
<ul>
<li v-for="(value, key, index) in info">{{index+1}}. {{key}}-{{value}}</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
info: {
name: 'xiaoming',
age: 18,
height: 1.78
}
}
})
</script>
组件的key属性
官方推荐在使用v-for时,给对应的元素或组件添加上一个 :key 属性
为什么需要这个key属性呢?
这其实和Vue的虚拟DOM的Diff算法有关,当某一层有跟多相同的加点时,也就是列表节点时,我们希望插入一个新的节点,比如希望在B和C之间加上一个F
Diff算法默认执行起来是这样的:C → F, D → C,E → D,最后再插入E
这样就很没效率,这时给每个节点加入key属性,Diff算法就能正确识别此节点,找到正确的位置插入新的节点
<div id="app">
<ul>
<li v-for="item in letters" :key="item">{{item}}</li>
</ul>
</div>
<script src="../js/vue.js"></script>
<script>
let app = new Vue({
el: '#app',
data: {
letters: ['A', 'B', 'C', 'D', 'E']
}
})
// B、C中间插入F: app.letters.splice(2, 0, 'F')
</script>
key的作用主要是为了高效更新虚拟DOM
检查数组更新
因为Vue是响应式的,所以当数据发生变化时,Vue会自动检测更新数据,Vue中包含了数组方法改变更新视图
如果通过索引修改数组中的元素,界面不会响应
// 1、push()
this.letters.push('aaaa');
// 2、pop():删除数组中的最后一个元素
this.letters.pop();
// 3、shift():删除数组中的第一个元素
this.letters.shift();
// 4、 unshift():在数组最前面添加元素
this.letters.unshift('zzz');
// 5、splice():删除元素、插入元素、替换元素
this.letters.splice(2, 2);
// 6、sort():排序
this.letters.sort();
// 7、reverse():翻转
this.letters.reverse();