3. Vue对象提供的属性功能
3.1 过滤器
过滤器,就是vue允许开发者自定义的文本格式化函数,可以使用在两个地方:输出内容和操作数据中。
定义过滤器的方式有两种。
3.1.1 使用Vue.filter()进行全局定义
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="js/filters.js"></script>
</head>
<body>
<div id="box">
<p>{{price|RMB}}</p>
</div>
<script>
/*
* // 过滤器,有两种:
// 全局过滤器, 通过Vue.filter("过滤器名称",匿名函数)
Vue.filter("RMB", function(v){
return "¥"+v;
});
*/
var vm = new Vue({
el:"#box",
data:{
price:30.5
}
})
</script>
</body>
</html>
3.1.2 在vue对象中通过filters属性局部
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="box">
<p>{{price|RMB}}</p>
</div>
<script>
var vm = new Vue({
el:"#box",
data:{
price:30.5
},
filters:{
RMB(v){
return "¥"+v;
}
}
})
</script>
</body>
</html>
3.4 计算和侦听属性
3.4.1 计算属性
我们之前学习过字符串反转,如果直接把反转的代码写在元素中,则会使得其他同事在开发时时不易发现数据被调整了,所以vue提供了一个计算属性(computed),可以让我们把调整data数据的代码存在在该属性中。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="box">
<p>{{price}}</p>
<p>{{price2}}</p>
</div>
<script>
// 当我们需要针对data的数据尽心调整成另一个变量,留作后面其他地方进行运算使用时,可以使用计算属性得出一个新的变量
var vm = new Vue({
el: "#box",
data: {
price: 30.5
},
// 计算属性
computed: {
price2: function () {
return this.price.toFixed(2);
}
}
})
</script>
</body>
</html>
3.4.2 监听属性
侦听属性,可以帮助我们侦听data某个数据的变化,从而做相应的自定义操作。
侦听属性是一个对象,它的键是要监听的对象或者变量,值一般是函数,当侦听的data数据发生变化时,会自定执行的对应函数,这个函数在被调用时,vue会传入两个形参,第一个是变化前的数据值,第二个是变化后的数据值。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="box">
数量:<input type="text" v-model="num">
单价:<input type="text" v-model="price">
总价:{{total}}
</div>
<script>
var vm = new Vue({
el: "#box",
data: {
num: 0,
price: 30.5,
total: 0
},
watch: {
num(newval, oldval) {
console.log("修改后num="+newval);
console.log("修改前num="+oldval);
this.total = this.price * this.num;
},
price() {
this.total = this.price * this.num;
}
}
})
</script>
</body>
</html>
3.5 vue对象的生命周期
每个Vue对象在创建时都要经过一系列的初始化过程。在这个过程中Vue.js会自动运行一些叫做生命周期的的钩子函数,我们可以使用这些函数,在对象创建的不同阶段加上我们需要的代码,实现特定的功能。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="box">
{{num}}
<input type="text" v-model="num">
</div>
<script>
var vm = new Vue({
el: "#box",
data: {
num: 30,
},
beforeCreate() {
// 这里的代码执行时,vm对象尚未创建,所以data中的数据是无法操作
// console.log(this.num); // undefined
},
created() {
// 这里的代码执行时,vm对象已经创建完成,但是还没有把数据和视图模板进行绑定
// console.log(this.num); // data的数据已经可以操作了。
// console.log(this.$el); // 此时还没有绑定视图
// 这里可以用于编写从后端获取数据的代码
},
beforeMount() {
// 这里的代码执行时,已经绑定了视图,但是没有更新视图中的数据
console.log(this.$el.innerHTML);
},
mounted() {
// 这里的代码执行时,已经把data中的数据替换了模板视图中对应的内容了
console.log(this.$el);
// 这里可以用于编写一些需要操作视图额初始化代码
},
beforeUpdate() {
// 更新html模板的数据之前
console.log(this.num);
console.log(this.$el.innerHTML)
},
updated() {
// 更新html模板的数据之后
console.log(this.num);
console.log(this.$el.innerHTML)
}
})
</script>
</body>
</html>
总结:
在vue使用的过程中,如果要初始化操作,把初始化操作的代码放在 mounted 中执行。
mounted阶段就是在vm对象已经把data数据实现到页面以后。一般页面初始化使用。例如,用户访问页面加载成功以后,就要执行的ajax请求。
另一个就是created,这个阶段就是在 vue对象创建以后,把ajax请求后端数据的代码放进 created
3.2 阻止事件冒泡和刷新页面
什么是事件冒泡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body onclick="alert('body')">
<div onclick="alert('div')">
<button>按钮</button>
</div>
<script>
// 事件,event,在js中表示用户和浏览器之间进行的一次交互过程
// 事件在触发时,就会有一个事件对象来记录整个事件发生的过程和发生的位置
// 从事件发生位置由内及外,根据标签之间父子嵌套关系,逐层往外传播,让父级元素触发同类事件,这种事件的传递方式,就是 事件冒泡
// 事件冒泡有好,有坏。
// 好处就是可以利用这种机制,实现事件委托
// 坏处就是当前元素的父级元素有同类事件,会随着冒泡直接全部执行
</script>
</body>
</html>
使用.stop和.prevent
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="box" @click="show2">
<!-- @click.stop来阻止事件冒泡 -->
<button @click.stop="show">按钮</button>
<!-- @click.prevent来阻止标签刷新 -->
<a href="" @click.prevent="show3">a链接</a>
</div>
<script>
var vm = new Vue({
el: "#box",
data: {},
methods: {
show() {
alert("按钮");
},
show2() {
// alert("父元素");
},
show3() {
console.log("一句话");
}
}
})
</script>
</body>
</html>
3.3 综合案例-todolist
我的计划列表
html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>todolist</title>
<style type="text/css">
.list_con{
width:600px;
margin:50px auto 0;
}
.inputtxt{
width:550px;
height:30px;
border:1px solid #ccc;
padding:0px;
text-indent:10px;
}
.inputbtn{
width: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>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style type="text/css">
.list_con {
width: 600px;
margin: 50px auto 0;
}
.inputtxt {
width: 550px;
height: 30px;
border: 1px solid #ccc;
padding: 0px;
text-indent: 10px;
}
.inputbtn {
width: 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" id="app">
<h2>To do list</h2>
<input type="text" v-model="text" id="txt1" class="inputtxt">
<input type="button" @click="add" value="增加" id="btn1" class="inputbtn">
<ul id="list" class="list">
<!-- javascript:; # 阻止a标签跳转 -->
<li v-for="item,key in todolist">
<span>{{item}}</span>
<a href="javascript:;" @click="up(key)" class="up"> ↑ </a>
<a href="javascript:;" @click="down(key)" class="down"> ↓ </a>
<a href="javascript:;" @click="del(key)" class="del">删除</a>
</li>
</ul>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
text: "",
todolist: [
"学习html",
"学习css",
"学习javascript",
]
},
methods: {
add() {
this.todolist.push(this.text);
this.text = "";
},
del(key) {
// splice 万能函数
// 删除和替换
// 参数1: 开始下表
// 参数2: 元素长度,如果不填默认删除到最后
// 参数3: 表示使用当前参数替换已经删除内容的位置
this.todolist.splice(key, 1);
},
up(key) {
// 向上移动
// splice(删除的开始位置,删除的成员个数, 替换的新数据)
if (key === 0) {
return;
}
//就是删掉然后插入
ret = this.todolist.splice(key, 1)[0];
this.todolist.splice(key - 1, 0, ret);
},
down(key) {
// 向下移动
ret = this.todolist.splice(key, 1)[0];
this.todolist.splice(key + 1, 0, ret);
}
}
});
</script>
</body>
</html>