Vue对象提供的属性功能
3.1 过滤器
定义
:就是vue允许开发者自定义的文本格式化函数,可以使用在两个地方:输出内容和操作数据中。
定义过滤器的方式有两种。
3.1.1 使用Vue.filter进行全局定义
<div id="app">
<p>{{ price }}</p>
<p>{{ price|format }}</p>
</div>
<script>
Vue.filter('format', function (num) {
return num.toFixed(2) + '元'
});
var vm = new Vue({
el:'#app',
data:{
price : 14.5678
},
});
</script>
为了体现解耦合的思想,可以将过滤器单独写到一个js 文件中去,如:
filter.js
Vue.filter('format', function (num) {
return num.toFixed(2) + '元'
});
在使用全局过滤器的时候在head里面导入
<script src="filter.js"></script>
3.1.2 在 Vue对象中通过设置filter属性来定义局部过滤器
注意:该过滤器只作用于当前vm对象,局部过滤器的优先级是大于全局过滤器
<div id="app">
<p>{{ price }}</p>
<p>{{ price|format }}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
price: 3.151914
},
filters: {
format: function (param) {
return param.toFixed(2) + '元'
}
},
});
3.2 计算属性和监听属性
3.2.1 计算属性
针对字符串的反转,如果直接将法将发展的代码写在元素中,将会降低程序的可读性,如果多处地方使用了该字符串的反转,又会增加了代码的冗余度。
在vue中提供了一种计算属性,可以将处理data数据的代码存在该属性中,方便使用以及后面的维护。
<div id="app">
<p>{{str_1}}</p>
<p>{{strRevs}}</p>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
str_1: 'abcdefg',
},
computed: {
strRevs: function () {
return this.str_1.split('').reverse().join('')
}
},
});
</script>
3.2.2 监听属性
监听属性
:可以帮助我们监听data某个属性的变化,从而可以做相应的自定义操作。
侦听属性是一个对象,它的键是要监听的对象或者变量,值一般是函数,当侦听的data数据发生变化时,会自定执行的对应函数,这个函数在被调用时,vue会传入两个形参,第一个是变化前的数据值,第二个是变化后的数据值。
<div id="app">
<button @click="num++">点赞({{num}})</button>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
num: 0,
},
watch: {
num: function (newNum, oldNum) {
alert('新来的:' + newNum + ',后来的:' + oldNum)
}
}
});
</script>
3.3 Vue的生命对象周期
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
比如 created
钩子可以用来在一个实例被创建之后执行代码:
new Vue({
data: {
a: 1
},
created: function () {
// `this` 指向 vm 实例
console.log('a is: ' + this.a)
}
})
也有一些其它的钩子,在实例生命周期的不同阶段被调用,如 mounted
、updated
和 destroyed
。生命周期钩子的 this
上下文指向调用它的 Vue 实例。
Vue的生命周期图如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>局部过滤器</title>
<script src="vue.min.js"></script>
</head>
<body>
<div id="app">
<p @click="num++">{{num}}</p>
</div>
<script>
var vm = new Vue({
el:"#app",
data:{
num: 10,
},
beforeCreate(){
console.log("----vm对象初始化完成之前自动执行的代码----");
console.log(this.$el);// 没有查找到vm需要控制的元素
console.log(this.$data);// 没有把data模型中的数据注入到vm对象里面作为属性了
},
created(){ // 这里主要实现到服务端获取页面数据[ajax]
console.log("----vm对象初始化完成以后自动执行的代码----");
console.log(this.$el); // 没有查找到vm需要控制的元素
console.log(this.$data); // 已经把data模型中的数据注入到vm对象里面作为属性了 Object num: 10
},
beforeMount(){
console.log("----vm数据渲染到html模板之前执行的代码----");
console.log(this.$el); // 没有查找到vm需要控制的元素
},
mounted(){ // 修改页面的内容[页面特效]
console.log("----vm数据渲染到html模板之后执行的代码----");
console.log(this.$el); // 没有查找到vm需要控制的元素
},
beforeUpdate(){
console.log("----数据更新了,渲染之前执行的代码------");
console.log(this.num);
console.log(this.$el.innerHTML);
},
updated(){
console.log("----数据更新了,渲染之后执行的代码------");
console.log(this.num);
console.log(this.$el.innerHTML);
},
// 销毁vm对象 vm.$destroy()
beforeDestroy(){
console.log("--- 当vm对象被销毁之前,会自动执行这里的代码 ---");
console.log( this );
},
destroyed(){
console.log("--- 当vm对象被销毁以后,会自动执行这里的代码 ---");
}
});
</script>
</body>
</html>
3.4 阻止事件的冒泡和事件的刷新
事件的冒泡
:指代js中子元素的事件触发以后,会导致父级元素的同类事件一并被触发到。
事件的冒泡既有好处,如果能够正确的使用事件的冒泡,能够实现委托事件,提升性能;如果不能合理的使用事件的冒泡,将会导致一些Bug 的出现。
- 使用原生的js来阻止事件的冒泡
<body onclick="alert('点击了body')">
<div class="box1">
<div class="box2">
</div>
</div>
<script>
var box1Ele = document.getElementsByClassName('box1')[0];
var box2Ele = document.getElementsByClassName('box2')[0];
box1Ele.onclick = function (event) {
alert('点击了box1');
event.stopPropagation()
};
box2Ele.onclick = function (event) {
alert('点击了box2');
console.log(event);
//原生的js来阻止事件的冒泡
event.stopPropagation()
}
</script>
- 利用事件的冒泡现象来实现事件的委托
<ul id="app">
<li>111111111111</li>
<li>222222222222</li>
<li>333333333333</li>
<li>444444444444</li>
<li>555555555555</li>
<li>666666666666</li>
</ul>
<script>
//批量元素的绑定事件
// var list = document.getElementById('app').children;
// for (var item in list) {
// list[item].onclick = function () {
// console.log(this.innerHTML);
// }
// }
// 可以通过事件委托来提升性能
var ulEle = document.getElementById('app');
ulEle.onclick = function (event) {
var selfEle = event.target;
alert(selfEle.innerHTML);
}
</script>
- Vue中阻止事件的冒泡
<body>
<div id="app" class="box1" @click="show('点击了box1')">
<div class="box2" @click.stop="show('点击了box2')"></div>
</div>
<script>
// vue本质上就是js,所以vue中的事件操作也会存在事件冒泡现象
// 可以使用辅助指令 @click.stop来阻止事件冒泡
var vm = new Vue({
el: "#app",
methods: {
show(message) {
alert(message);
}
}
})
</script>
</body>
阻止事件的刷新
<div id="app">
<!-- 辅助指令可以多个链式调用 -->
<a href="http://www.mzitu.com" @click.prevent.stop="show">QaQ</a>
</div>
<script>
var vm = new Vue({
el: '#app',
methods: {
show() {
},
}
});
</script>
3.5 综合案例todolist
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>todolist</title>
<style type="text/css">
.list_con{
600px;
margin:50px auto 0;
}
.inputtxt{
550px;
height:30px;
border:1px solid #ccc;
padding:0px;
text-indent:10px;
}
.inputbtn{
40px;
height:32px;
padding:0px;
border:1px solid #ccc;
}
.list{
margin:0;
padding:0;
list-style:none;
margin-top:20px;
}
.list li{
height:40px;
line-height:40px;
border-bottom:1px solid #ccc;
}
.list li span{
float:left;
}
.list li a{
float:right;
text-decoration:none;
margin:0 10px;
}
</style>
</head>
<body>
<div class="list_con">
<h2>To do list</h2>
<input type="text" name="" id="txt1" class="inputtxt">
<input type="button" name="" value="增加" id="btn1" class="inputbtn">
<ul id="list" class="list">
<!-- javascript:; # 阻止a标签跳转 -->
<li>
<span>学习html</span>
<a href="javascript:;" class="up"> ↑ </a>
<a href="javascript:;" class="down"> ↓ </a>
<a href="javascript:;" class="del">删除</a>
</li>
<li><span>学习css</span><a href="javascript:;" class="up"> ↑ </a><a href="javascript:;" class="down"> ↓ </a><a href="javascript:;" class="del">删除</a></li>
<li><span>学习javascript</span><a href="javascript:;" class="up"> ↑ </a><a href="javascript:;" class="down"> ↓ </a><a href="javascript:;" class="del">删除</a></li>
</ul>
</div>
</body>
</html>
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>todolist</title>
<style type="text/css">
.list_con {
600px;
margin: 50px auto 0;
}
.inputtxt {
550px;
height: 30px;
border: 1px solid #ccc;
padding: 0px;
text-indent: 10px;
}
.inputbtn {
40px;
height: 32px;
padding: 0px;
border: 1px solid #ccc;
}
.list {
margin: 0;
padding: 0;
list-style: none;
margin-top: 20px;
}
.list li {
height: 40px;
line-height: 40px;
border-bottom: 1px solid #ccc;
}
.list li span {
float: left;
}
.list li a {
float: right;
text-decoration: none;
margin: 0 10px;
}
</style>
<script src="vue.min.js"></script>
</head>
<body>
<div class="list_con" id="app">
<h2>To do list</h2>
<input type="text" name="" id="txt1" class="inputtxt" v-model="class_name">
<input type="button" name="" value="增加" id="btn1" class="inputbtn" @click="add_class">
<ul id="list" class="list">
<!-- javascript:; # 阻止a标签跳转 -->
<li v-for="item,index in class_list">
<span>{{ item }}</span>
<a href="javascript:;" class="up" @click="up_class(index)"> ↑ </a>
<a href="javascript:;" class="down" @click="down_class(index)"> ↓ </a>
<a href="javascript:;" class="del" @click="delete_class(index)">删除</a>
</li>
</ul>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
class_name: '',
class_list: ['python从入门到脱坑', '数据库从入门到入狱', 'Vue从入门到放弃'],
},
methods: {
add_class: function () {
if (this.class_name === '') {
return false;
}
this.class_list.push(this.class_name);
this.class_name = '';
},
delete_class: function (index) {
this.class_list.splice(index, 1);
},
up_class: function (index) {
if(index === 0){
return false;
}
var upEle = this.class_list.splice(index, 1);
this.class_list.splice(index - 1, 0, upEle[0]);
},
down_class: function (index) {
var downEle = this.class_list.splice(index, 1);
this.class_list.splice(index + 1, 0, downEle[0]);
},
}
});
</script>
</body>
</html>