今日内容
- 3. Vue对象提供的属性功能
- 3.1 过滤器
- 3.1.1 使用Vue.filter()进行全局定义
- 3.1.2 在vue对象中通过filters属性来定义
- 3.2 计算和侦听属性
- 3.2.1 计算属性
- 3.2.2 监听属性
- 3.3 vue对象的生命周期
- 3.4 阻止事件冒泡和刷新页面
- 3.5 综合案例-todolist
- 3.1 过滤器
今日内容详细
3. Vue对象提供的属性功能
3.1 过滤器
过滤器,就是vue允许开发者自定义的文本格式化函数,可以使用在两个地方:输出内容和操作数据中。
定义过滤器的方式有两种。
3.1.1 使用Vue.filter()进行全局定义
// 全局过滤器
Vue.filter("format",function(money){
return money.toFixed(2)+"元"; // js中提供了一个toFixed方法可以保留2位小鼠
});
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>局部过滤器title>
<script src="vue.js">script>
head>
<body>
<div id="app">
<p>{{price}}p>
<p>{{price|format}}p>
div>
<script>
var vm = new Vue({
el:"#app", // vm的模板对象
data:{ // vm的数据
price: 8.156333,
},
methods:{}, // vm的方法
// 局部过滤器只能在当前vm对象中使用
filters:{
format(money){
return money.toFixed(2)+"元";
}
}
});
script>
body>
html>
3.2 计算和侦听属性
3.2.1 计算属性
我们之前学习过字符串反转,如果直接把反转的代码写在元素中,则会使得其他同事在开发时时不易发现数据被调整了,所以vue提供了一个计算属性(computed),可以让我们把调整data数据的代码存在在该属性中。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>局部过滤器title>
<script src="vue.js">script>
head>
<body>
<div id="app">
<input type="text" v-model="num1">+
<input type="text" v-model="num2">=<span>{{total}}span>
div>
<script>
var vm = new Vue({
el:"#app", // vm的模板对象
data:{ // vm的数据
num1: 0,
num2: 0,
},
methods:{}, // vm的方法
computed:{ // 计算属性,相当于创建一个新的变量保存数据计算的结果
total(){
// parseFloat 把数据转换成浮点数
// parseInt 把数据转换成整数
return parseFloat(this.num1)+parseFloat(this.num2);
}
}
});
script>
body>
html>
3.2.2 监听属性
侦听属性,可以帮助我们侦听data某个数据的变化,从而做相应的自定义操作。
侦听属性是一个对象,它的键是要监听的对象或者变量,值一般是函数,当侦听的data数据发生变化时,会自定执行的对应函数,这个函数在被调用时,vue会传入两个形参,第一个是变化前的数据值,第二个是变化后的数据值。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>局部过滤器title>
<script src="vue.js">script>
head>
<body>
<div id="app">
<button @click="num++">赞({{num}})button>
div>
<script>
var vm = new Vue({
el:"#app", // vm的模板对象
data:{ // vm的数据
num: 0,
},
watch:{ // 侦听属性,监听指定变量的值是否发生变化,当发生变化时调用对应的方法
num(v1,v2){
if(this.num>=5){
this.num=5;
}
console.log(this.num,"修改后num="+v1,"修改前num="+v2);
}
}
});
script>
body>
html>
3.3 vue对象的生命周期
每个Vue对象在创建时都要经过一系列的初始化过程。在这个过程中Vue.js会自动运行一些叫做生命周期的的钩子函数,我们可以使用这些函数,在对象创建的不同阶段加上我们需要的代码,实现特定的功能。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>局部过滤器title>
<script src="vue.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);
// console.log(this.$data);
// },
created(){ // 这里主要实现到服务端获取页面数据[ajax]
console.log("----vm对象初始化完成以后自动执行的代码----");
console.log(this.$el); // 没有查找到vm需要控制的元素
console.log(this.$data); // 已经把data模型中的数据注入到vm对象里面作为属性了
},
// 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>
总结:
在vue使用的过程中,如果要初始化操作,把初始化操作的代码放在 mounted 中执行。
mounted阶段就是在vm对象已经把data数据实现到页面以后。一般页面初始化使用。例如,用户访问页面加载成功以后,就要执行的ajax请求。
另一个就是created,这个阶段就是在 vue对象创建以后,把ajax请求后端数据的代码放进 created
3.4 阻止事件冒泡和刷新页面
事件冒泡:指代js中子元素的事件触发以后,会导致父级元素的同类事件一并被触发到。
事件冒泡有好处,也有坏处。
好处:如果能正确利用这种现象,可以实现事件委托,提升特效的性能
坏处:如果没有正确使用,则会导致不必要的bug出现。
使用.stop和.prevent
js的事件冒泡和阻止事件冒泡
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件冒泡title>
<style>
.box1{
width: 400px;
height: 300px;
background-color: orange;
padding-top: 100px;
}
.box2{
width: 200px;
height: 200px;
background-color: #000;
margin: auto;
}
style>
head>
<body onclick="alert('点击了body')">
<div class="box1">
<div class="box2">div>
div>
<script>
var box1 = document.getElementsByClassName("box1")[0];
var box2 = document.getElementsByClassName("box2")[0];
box1.onclick = function(){
alert("点击了box1");
}
box2.onclick = function(event){
alert("点击了box2");
console.log(event);
// 原生js阻止事件冒泡
event.stopPropagation();
}
script>
body>
html>
js中利用事件冒泡现象实现事件委托
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件冒泡title>
<style>
.box1{
width: 400px;
height: 300px;
background-color: orange;
padding-top: 100px;
}
.box2{
width: 200px;
height: 200px;
background-color: #000;
margin: auto;
}
style>
head>
<body onclick="alert('点击了body')">
<div class="box1">
<div class="box2">div>
div>
<script>
var box1 = document.getElementsByClassName("box1")[0];
var box2 = document.getElementsByClassName("box2")[0];
box1.onclick = function(){
alert("点击了box1");
}
box2.onclick = function(event){
alert("点击了box2");
console.log(event);
// 原生js阻止事件冒泡
event.stopPropagation();
}
script>
body>
html>
vue中阻止事件冒泡
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件冒泡title>
<style>
.box1{
width: 400px;
height: 300px;
background-color: orange;
padding-top: 100px;
}
.box2{
width: 200px;
height: 200px;
background-color: #000;
margin: auto;
}
style>
<script src="vue.js">script>
head>
<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>
html>
vue阻止页面刷新
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件冒泡title>
<script src="vue.js">script>
head>
<body>
<div id="app">
<a href="http://www.baidu.com" @click.stop.prevent="show">百度a>
div>
<script>
// vue本质上就是js,所以vue中的事件操作也会存在事件冒泡现象
// 可以使用辅助指令 @click.stop来阻止事件冒泡
var vm = new Vue({
el:"#app",
methods:{
show(){
}
}
})
script>
body>
html>
vue阻止表单内容提交
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<style>
.box1{
width: 200px;
height: 200px;
background: #ccc;
}
.box2{
width: 100px;
height: 100px;
background: pink;
}
style>
<script src="js/vue.min.js">script>
<script>
window.onload = function(){
var vm = new Vue({
el:"#app",
data:{}
})
}
script>
head>
<body>
<div id="app">
<div class="box1" @click="alert('box1')">
<div class="box2" @click.stop.prevent="alert('box2')">div>
div>
<form action="#">
<input type="text">
<input type="submit">
<input type="submit" value="提交02" @click.prevent="">
form>
div>
body>
html>
我的计划列表
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>todolisttitle>
<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 listh2>
<input type="text" name="" id="txt1" class="inputtxt">
<input type="button" name="" value="增加" id="btn1" class="inputbtn">
<ul id="list" class="list">
<li>
<span>学习htmlspan>
<a href="javascript:;" class="up"> ↑ a>
<a href="javascript:;" class="down"> ↓ a>
<a href="javascript:;" class="del">删除a>
li>
<li><span>学习cssspan><a href="javascript:;" class="up"> ↑ a><a href="javascript:;" class="down"> ↓ a><a href="javascript:;" class="del">删除a>li>
<li><span>学习javascriptspan><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>todolisttitle>
<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>
<script src="js/vue.js">script>
head>
<body>
<div id="todolist" class="list_con">
<h2>To do listh2>
<input type="text" v-model="message" class="inputtxt">
<input type="button" @click="addItem" value="增加" class="inputbtn">
<ul id="list" class="list">
<li v-for="item,key in dolist">
<span>{{item}}span>
<a @click="upItem(key)" class="up" > ↑ a>
<a @click="downItem(key)" class="down"> ↓ a>
<a @click="delItem(key)" class="del">删除a>
li>
ul>
div>
<script>
// 计划列表代码
let vm = new Vue({
el:"#todolist",
data:{
message:"",
dolist:[
"学习html",
"学习css",
"学习javascript",
]
},
methods:{
addItem(){
if(this.messsage==""){
return false;
}
this.dolist.push(this.message);
this.message = ""
},
delItem(key){
// 删除和替换
// 参数1: 开始下表
// 参数2: 元素长度,如果不填默认删除到最后
// 参数3: 表示使用当前参数替换已经删除内容的位置
this.dolist.splice(key, 1);
},
upItem(key){
if(key==0){
return false;
}
// 向上移动
let result = this.dolist.splice(key,1);
this.dolist.splice(key-1,0,result[0]);
},
downItem(key){
// 向下移动
let result = this.dolist.splice(key, 1);
console.log(result);
this.dolist.splice(key+1,0,result[0]);
}
}
})
script>
body>
html>
作业
1. 完成todolist的案例,在todolist中实现隔行换色效果
奇数行的计划, 背景色为"blue"
偶数行的计划,背景色为"orange"
2. 使用vue.js完成表格的管理功能[添加数据,取消添加、展示商品列表,编辑商品信息,取消编辑,删除商品]
商品id默认使用下标作为值
提示: v-for显示商品列表,商品列表作为数组保存vm对象的data属性里面
添加商品和删除商品就是对数组的添加成员和删除指定下标成员
作业1答案
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>todolisttitle>
<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;
}
.color1 {
background-color: orange;
}
.color2 {
background-color: blue;
}
style>
<script src="vue.js">script>
head>
<body>
<div class="list_con" id="app">
<h2>To do listh2>
<input type="text" v-model="content" id="txt1" class="inputtxt">
<input type="button" @click="add" value="增加" id="btn1" class="inputbtn">
<ul id="list" class="list">
<li v-for="item,index in todolist" :class="index%2==0?'color1':'color2'">
<span>{{item}}span>
<a href="javascript:;" class="up" @click="up(index)"> ↑ a>
<a href="javascript:;" class="down" @click="down(index)"> ↓ a>
<a href="javascript:;" class="del" @click="del(index)">删除a>
li>
ul>
div>
<script>
let vm = new Vue({
el: "#app",
data: {
content: "",
todolist: ["学习html", "学习css", "学习javascript"],
},
methods: {
add() {
// 添加计划
this.todolist.push(this.content);
// 清空单行文本框中的信息
this.content = "";
},
del(index) {
// 删除计划
this.todolist.splice(index, 1);
},
up(index) {
// 向上移动计划
let current = this.todolist.splice(index, 1)[0];
this.todolist.splice(index - 1, 0, current);
},
down(index) {
// 向下移动计划
let current = this.todolist.splice(index, 1)[0];
this.todolist.splice(index + 1, 0, current);
}
}
})
script>
body>
html>
作业2答案
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<style>
#goods table{
width: 600px;
border:1px solid #000;
border-collapse: collapse;
}
#goods td,#goods th{
border: 1px solid #000;
}
#goods .box{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
background-color: #eee;
width: 280px;
height: 160px;
padding: 40px 80px;
}
style>
<script src="vue.js">script>
head>
<body>
<div id="goods">
<button @click="is_show=true;goods_index=-1;">添加商品button>
<table>
<tr>
<th>商品编号th>
<th>商品标题th>
<th>商品数量th>
<th>商品价格th>
<th>操作th>
tr>
<tr v-for="goods,index in goods_list">
<td>{{index+1}}td>
<td>{{goods.name}}td>
<td>
<button>-button>
<input type="text" size="2" v-model="goods.num">
<button>+button>
td>
<td>{{goods.price.toFixed(2)}}td>
<td>
<button @click="update(index)">编辑button>
<button @click="del(index)">删除button>
td>
tr>
<tr>
<td colspan="5">总计: 1000元td>
tr>
table>
<div class="box" v-show="is_show">
商品标题: <input type="text" v-model="goods_name"><br><br>
商品数量: <input type="text" v-model="goods_num"><br><br>
商品价格: <input type="text" v-model="goods_price"><br><br>
<button @click="save">保存button>
<button @click="cancel">取消button>
div>
div>
<script>
var vm = new Vue({
el:"#goods",
data:{
is_show:false,
goods_name:"",
goods_num:"",
goods_price:"",
goods_index:-1, // 当前本次操作的商品信息[-1表示新增,大于0表示编辑]
goods_list:[
{"name":"python入门","num":27,"price":150},
{"name":"python进阶","num":21,"price":100},
{"name":"python高级","num":17,"price":75},
{"name":"python研究","num":37,"price":60},
{"name":"python放弃","num":57,"price":110},
]
},
methods:{
save(){
// 保存数据[添加数据]
if(this.goods_index==-1){
this.goods_list.push({
"name":this.goods_name,
"num":parseInt(this.goods_num),
"price":parseFloat(this.goods_price),
});
}else{
this.goods_list[this.goods_index].name=this.goods_name;
this.goods_list[this.goods_index].num=parseInt(this.goods_num);
this.goods_list[this.goods_index].price=parseFloat(this.goods_price);
}
this.cancel();
},
cancel(){
this.is_show=false;
this.goods_index= -1;
this.goods_name= "";
this.goods_num= "";
this.goods_price= "";
},
del(index){
// 删除数据
this.goods_list.splice(index,1);
},
update(index){
// 先弹窗
this.is_show=true;
// 显示当前编辑的商品信息
this.goods_index=index;
this.goods_name=this.goods_list[index].name;
this.goods_num=this.goods_list[index].num;
this.goods_price=this.goods_list[index].price;
// 当用户点击保存时,修改对应数据
}
}
})
script>
body>
html>