Vue基础 | 二、Vue对象属性功能
2020-12-15 本文已影响0人
W11ng
一、Vue的三种属性
1.1 过滤器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
<script src="js/filters.js"></script>
</head>
<body>
<div id="app">
{{price | kdot(3) | RMB }}
</div>
<script>
// 通过vm对象内部的filters属性进行局部声明,过滤器只能用于当前vm实例对象
var vm = new Vue({
el:"#app",
data:{
price: 10.333333,
},
filters:{
// "过滤器名称": function(){
// // 过滤器执行的代码
// }
kdot(data,num){
return data.toFixed(num)
}
}
})
</script>
</body>
</html>
1.2 计算属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<p>{{price}}</p>
<p>{{new_price}}</p>
<p>{{href}}</p>
</div>
<script>
// 计算属性,这里的属性指代的就是data里面的内容,官方建议,针对数字的计算和调整,放在计算属性
var vm = new Vue({
el:"#app",
data:{
pi: 3.14,
price: 10.333333,
},
// 计算属性,重新产生一个新的变量值
computed:{
/*
新的变量名: function(){
// 内部必须有返回值,如果要对原有的data里面的属性计算调用,则通过this.变量名来调用
},
*/
new_price: function(){
return this.price.toFixed(2)
},
href: function(){
return location.href;
}
},
})
</script>
</body>
</html>
1.3 监听属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<span>{{num}}</span>
<button @click="num++">投票</button>
</div>
<script>
var vm = new Vue({
el:"#app",
data:{
num: 0,
},
// 监听属性,监控data属性的变化,一旦指定的属性发生值的变化时,则vue会自动调用watch里面的同名属性对应的函数,并且把修改后的值和修改前的值作为参数传递进去。
watch:{
num: function(new_data,old_data){
console.log(`num原来是${old_data},点击以后num=${new_data}`);
if(this.num>3){
this.num = 3;
}
}
}
})
</script>
</body>
</html>
1.4 监听属性案例(各地区联动)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
住址:
<select v-model="province_id">
<option value="0">请选择省份</option>
<option v-for="province in province_list " :value="province.id">{{province.name}}</option>
</select>
<select v-model="city_id">
<option value="0">请选择城市</option>
<option v-if="city.parent_id == province_id" v-for="city in city_list" :value="city.id">{{city.name}}</option>
</select>
<select v-model="area_id">
<option value="请选择地区">请选择地区</option>
<option v-if="area.parent_id==city_id" v-for="area in area_list" :value="area.id">{{area.name}}</option>
</select>
</div>
<script>
var vm = new Vue({
el:"#app",
data:{
province_id:0,
city_id: 0,
area_id: 0,
province_list:[
{"id":1,"name":"广东省"},
{"id":2,"name":"广西省"},
{"id":3,"name":"湖南省"},
],
city_list:[],
area_list:[],
},
// 侦听属性
watch:{
province_id(){
// ajax从后端获取城市列表
this.city_list = [
{"parent_id":1,"id":4,"name":"深圳市"},
{"parent_id":1,"id":5,"name":"广州市"},
{"parent_id":2,"id":6,"name":"桂林市"},
{"parent_id":2,"id":7,"name":"百色市"},
{"parent_id":2,"id":8,"name":"柳州市"},
{"parent_id":3,"id":9,"name":"长沙市"},
{"parent_id":3,"id":10,"name":"岳阳市"}
]
},
city_id(){
// ajax从后端获取地区列表
this.area_list = [
{"parent_id":5,"id":11,"name":"天河区"},
{"parent_id":5,"id":12,"name":"白云区"},
{"parent_id":6,"id":13,"name":"阳朔区"},
{"parent_id":6,"id":14,"name":"叠彩区"},
{"parent_id":4,"id":15,"name":"龙岗区"},
{"parent_id":4,"id":16,"name":"福田区"},
]
}
}
})
</script>
</body>
</html>
二、生命周期
2.1 vue对象的生命周期
mounted是所有数据挂载后触发的函数,适合用来初始化操作。比如执行ajax。
另一个是created,将ajax返回的数据放进created。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vm对象的生命周期</title>
<script src="js/vue.js"></script>
<script src="js/filters.js"></script>
</head>
<body>
<div id="app">
<p>{{num}}</p>
<button @click="num++">投票</button>
</div>
<script>
// 通过vm对象内部的filters属性进行局部声明,过滤器只能用于当前vm实例对象
var vm = new Vue({
el:"#app",
data:{
num: 10,
},
// 8个钩子函数,常用的有6个,destory beforeDestory不常用
// beforeCreate会在vm对象创建实例化以后,初始化vm内部数据之前调用
beforeCreate(){
console.log("------beforeCreate start------");
console.log( this );
console.log( this.num ); // 还没有对数据进行初始化
console.log("------beforeCreate end ------");
},
// created 在vm对象实例化并初始化数据以后,视图加载之前调用
// 编写ajax代码,从服务端获取数据并赋值给data里面的数据
created(){
console.log("------created start------");
console.log( this.num ); // 此时,能够获取并操作num的值
console.log( this.$el );
console.log("------created end ------");
},
// 加载视图以后,在数据赋值之前,调用
beforeMount(){
console.log("------beforeMount start------");
console.log( this.num );
console.log( this.$el );
console.log("------beforeMount end ------");
},
// 加载视图并进行数据赋值以后,调用
// 编写操作界面的代码,调整样式,制作初始化的js特效
mounted(){
console.log("------mounted start------");
console.log( this.num );
console.log( this.$el );
console.log("------mounted end ------");
},
// 更新数据时,修改data数据以后,对模板的数据赋值之前,调用
beforeUpdate(){
console.log("------beforeUpdate start------");
console.log( this.num );
console.log( this.$el.innerHTML );
console.log("------beforeUpdate end ------");
},
// 更新数据完成以后调用
updated(){
console.log("------beforeUpdate start------");
console.log( this.num );
console.log( this.$el.innerHTML );
console.log("------beforeUpdate end ------");
},
})
</script>
</body>
</html>
三、阻止事件
3.1 事件冒泡和事件委托
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#parent{
width: 200px;
height: 200px;
background-color: red;
}
#son{
width: 50px;
height: 40px;
background:blue;
}
</style>
</head>
<body>
<div id="parent">
<div id="son"></div>
</div>
<ul id="list">
<li>子元素1</li>
<li>子元素2</li>
<li>子元素3</li>
<li>子元素4</li>
<li>子元素5</li>
<li>子元素6</li>
<li>子元素7</li>
<li>子元素8</li>
</ul>
<script>
var par = document.getElementById("parent");
var son = document.getElementById("son");
par.onclick = function(e){
alert("父元素");
console.log(e);
}
son.onclick = function (e) {
alert("子元素");
e.stopPropagation(); // 原生的js阻止事件冒泡
};
// 批量添加事件
// var lis = document.getElementsByTagName("li");
// for(let i = 0;i<lis.length;i++){
// console.log(lis[i]);
// lis[i].onclick = function(){ // 批量绑定事件
// console.log( this.innerHTML );
// }
// }
//
// 事件委托:利用事件冒泡的特性,把子元素要执行的代码,委托给父元素来执行
var ul = document.getElementById("list");
ul.onclick = function(e){
// 核心代码
// console.log(e); // 事件对象:浏览器会把本次事件相关的内容和属性,封装成一个对象作为参数提供给我们
// console.log(e.target); // 事件触发对象
let _this = e.target;
console.log( _this.innerHTML )
}
</script>
</body>
</html>
3.2 vue的冒泡事件和阻止冒泡事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
<style>
#parent{
width: 200px;
height: 200px;
background-color: red;
color: white;
}
#son{
width: 50px;
height: 40px;
background:blue;
}
</style>
</head>
<body>
<div id="app">
<div id="parent" @click="add">
<p>{{num}}</p>
<div id="son" @click.stop="add">点击</div>
</div>
</div>
<script>
// 通过vm对象内部的filters属性进行局部声明,过滤器只能用于当前vm实例对象
var vm = new Vue({
el:"#app",
data:{
num:0,
},
methods:{
add:function(e){
this.num++;
}
}
})
</script>
</body>
</html>
3.3 阻止元素的默认行为
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
<a href="" @click.stop.prevent="add">a标签</a>
</div>
<script>
var vm = new Vue({
el:"#app",
data:{
},
methods:{
add(){
alert("点击了a标签");
}
}
})
</script>
</body>
</html>
四、总案例:todo list
4.1 分析需求和展示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>todolist</title>
<script src="js/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 id="ToDoList" 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">
<li v-for="item in data_list">
<span>{{item.title}}</span>
<a href="javascript:;" class="up"> ↑ </a>
<a href="javascript:;" class="down"> ↓ </a>
<a href="javascript:;" class="del">删除</a>
</li>
</ul>
</div>
<script>
// 1. 把计划数据展示到页面中
// 2. 当用户填写计划以后,点击"增加"按钮时,把数据添加到计划列表中,展示出来
// 3. 当用户点击"删除"按钮,把当前一行的计划数据移除掉
// 4. 当用户点击"↑",则需要把当前一行和上一行数据之间的位置,进行互换
// 5. 当用户点击"↓",则需要把当前一行和下一行数据之间的位置,进行互换
var vm = new Vue({
el: "#ToDoList",
data:{
data_list:[
{"title":"学习html"},
{"title":"学习css"},
{"title":"学习javascript"},
{"title":"学习python"},
]
}
})
</script>
</body>
</html>
4.2 添加计划
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>todolist</title>
<script src="js/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 id="ToDoList" class="list_con">
<h2>To do list</h2>
<input type="text" v-model="plan" id="txt1" class="inputtxt">
<input type="button" name="" value="增加" @click="add_data" id="btn1" class="inputbtn">
<ul id="list" class="list">
<li v-for="item in data_list">
<span>{{item.title}}</span>
<a href="javascript:;" class="up"> ↑ </a>
<a href="javascript:;" class="down"> ↓ </a>
<a href="javascript:;" class="del">删除</a>
</li>
</ul>
</div>
<script>
// 2. 当用户填写计划以后,点击"增加"按钮时,把数据添加到计划列表中,展示出来
// 3. 当用户点击"删除"按钮,把当前一行的计划数据移除掉
// 4. 当用户点击"↑",则需要把当前一行和上一行数据之间的位置,进行互换
// 5. 当用户点击"↓",则需要把当前一行和下一行数据之间的位置,进行互换
var vm = new Vue({
el: "#ToDoList",
data:{
plan:"",
data_list:[
{"title":"学习html"},
{"title":"学习css"},
{"title":"学习javascript"},
{"title":"学习python"},
]
},
methods:{
// 添加计划
add_data(){
if( this.plan.length > 0 ){
// this.data_list.push({"title":this.plan}); // 追加
this.data_list.unshift({"title":this.plan}); // 前置插入
}
}
}
})
</script>
</body>
</html>
4.3 删除列表
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>todolist</title>
<script src="js/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 id="ToDoList" class="list_con">
<h2>To do list</h2>
<input type="text" v-model="plan" id="txt1" class="inputtxt">
<input type="button" name="" value="增加" @click="add_data" id="btn1" class="inputbtn">
<ul id="list" class="list">
<li v-for="item,key in data_list">
<span>{{item.title}}</span>
<a href="javascript:;" class="up"> ↑ </a>
<a href="javascript:;" class="down"> ↓ </a>
<a href="javascript:;" @click="del_data(key)" class="del">删除</a>
</li>
</ul>
</div>
<script>
// 3. 当用户点击"删除"按钮,把当前一行的计划数据移除掉
// 4. 当用户点击"↑",则需要把当前一行和上一行数据之间的位置,进行互换
// 5. 当用户点击"↓",则需要把当前一行和下一行数据之间的位置,进行互换
var vm = new Vue({
el: "#ToDoList",
data:{
plan:"",
data_list:[
{"title":"学习html"},
{"title":"学习css"},
{"title":"学习javascript"},
{"title":"学习python"},
]
},
methods:{
// 添加计划
add_data(){
if( this.plan.length > 0 ){
// this.data_list.push({"title":this.plan}); // 追加
this.data_list.unshift({"title":this.plan}); // 前置插入
}
},
del_data(index){
// console.log(index)
// console.log( this.data_list[index] );
// 可以使用js原生的数组方法来完成删除指定下表的成员
// 数组.splice(开始截取的下表,截取的成员数量,替换的成员)
this.data_list.splice(index,1); // 截取
}
}
})
</script>
</body>
</html>
4.4 向上或向下移动
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>todolist</title>
<script src="js/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 id="ToDoList" class="list_con">
<h2>To do list</h2>
<input type="text" v-model="plan" id="txt1" class="inputtxt">
<input type="button" name="" value="增加" @click="add_data" id="btn1" class="inputbtn">
<ul id="list" class="list">
<li v-for="item,key in data_list">
<span>{{item.title}}</span>
<a href="javascript:;" @click="move_up(key)" class="up"> ↑ </a>
<a href="javascript:;" @click="move_down(key)" class="down"> ↓ </a>
<a href="javascript:;" @click="del_data(key)" class="del">删除</a>
</li>
</ul>
</div>
<script>
// 4. 当用户点击"↑",则需要把当前一行和上一行数据之间的位置,进行互换
// 5. 当用户点击"↓",则需要把当前一行和下一行数据之间的位置,进行互换
var vm = new Vue({
el: "#ToDoList",
data:{
plan:"",
data_list:[
{"title":"学习html"},
{"title":"学习css"},
{"title":"学习javascript"},
{"title":"学习python"},
]
},
methods:{
// 添加计划
add_data(){
if( this.plan.length > 0 ){
// this.data_list.push({"title":this.plan}); // 追加
this.data_list.unshift({"title":this.plan}); // 前置插入
}
},
// 删除计划
del_data(index){
// console.log(index)
// console.log( this.data_list[index] );
// 可以使用js原生的数组方法来完成删除指定下表的成员
// 数组.splice(开始截取的下表,截取的成员数量,替换的成员)
this.data_list.splice(index,1); // 截取
},
// 向上移动计划
move_up(index){
if(index>0){
// 先把当前要移动的计划提取出来
current = this.data_list.splice(index,1)[0];
console.log(current);
// 把提取出来的计划放到index-1的位置
this.data_list.splice(index-1,0,current);
}
},
// 向下移动计划
move_down(index){
// 先把当前要移动的计划提取出来
current = this.data_list.splice(index,1)[0];
// 把提取出来的计划放到index+1的位置
this.data_list.splice(index+1,0,current);
}
}
})
</script>
</body>
</html>
4.5 完整版
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>todolist</title>
<script src="js/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 id="ToDoList" class="list_con">
<h2>To do list</h2>
<input type="text" v-model="plan" id="txt1" class="inputtxt">
<input type="button" name="" value="增加" @click="add_data" id="btn1" class="inputbtn">
<ul id="list" class="list">
<li v-for="item,key in data_list">
<span>{{item.title}}</span>
<a href="javascript:;" @click="move_up(key)" class="up"> ↑ </a>
<a href="javascript:;" @click="move_down(key)" class="down"> ↓ </a>
<a href="javascript:;" @click="del_data(key)" class="del">删除</a>
</li>
</ul>
</div>
<script>
// 4. 当用户点击"↑",则需要把当前一行和上一行数据之间的位置,进行互换
// 5. 当用户点击"↓",则需要把当前一行和下一行数据之间的位置,进行互换
var vm = new Vue({
el: "#ToDoList",
data:{
plan:"",
data_list:[
{"title":"学习html"},
{"title":"学习css"},
{"title":"学习javascript"},
{"title":"学习python"},
]
},
methods:{
// 添加计划
add_data(){
if( this.plan.length > 0 ){
// this.data_list.push({"title":this.plan}); // 追加
this.data_list.unshift({"title":this.plan}); // 前置插入
}
},
// 删除计划
del_data(index){
// console.log(index)
// console.log( this.data_list[index] );
// 可以使用js原生的数组方法来完成删除指定下表的成员
// 数组.splice(开始截取的下表,截取的成员数量,替换的成员)
this.data_list.splice(index,1); // 截取
},
// 向上移动计划
move_up(index){
if(index>0){
// 先把当前要移动的计划提取出来
current = this.data_list.splice(index,1)[0];
console.log(current);
// 把提取出来的计划放到index-1的位置
this.data_list.splice(index-1,0,current);
}
},
// 向下移动计划
move_down(index){
// 先把当前要移动的计划提取出来
current = this.data_list.splice(index,1)[0];
// 把提取出来的计划放到index+1的位置
this.data_list.splice(index+1,0,current);
}
}
})
</script>
</body>
</html>