Python笔记_65_vue属性功能_过滤器_计算属性_监听属性_生命周期_阻止事件冒泡_阻止元素默认行为

Vue对象提供的属性功能

过滤器

过滤器,就是vue允许开发者自定义的文本格式化函数,可以使用在两个地方:输出内容操作数据中。

  • 全局定义
    语法:Vue.filter("过滤器名称", func);
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>过滤器</title>
    <script src="js/vue.js"></script>
</head>
<body>

<div id="app" align="center">
	<h2>{{price}}</h2>
	<h2>{{price|RMB}}</h2>
</div>
<script>
    // 通过Vue.filter() 进行全局声明,是在vm对象创建之前声明好的。
    // 语法:Vue.filter("过滤器名称", func);
    Vue.filter('RMB', function (data) {
        return "¥" + data;
    });
    var vm = new Vue({
        el: "#app",
        data: {
            price: 1234.567890,
        }
    })
</script>
</body>
</html>

在这里插入图片描述

  • 局部定义
    在Vue对象中通过filters属性来定义
    语法:
    filters: {
                "过滤器名称": function(){
               // 过滤器执行的代码
                }
    

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>过滤器</title>
    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app" align="center">
        <h2>{{price}}</h2>
        <h2>{{price|RMB}}</h2>
        <h2>{{price|p_format(2)}}</h2>
        <!--这里会报错,因为过滤器后的数据,已经不是数值了。为了避免报错,只需将过滤器换个位置即可。-->
	    <!--<p>{{price|RMB|p_format(2)}}</p>-->
        <h2>{{price|p_format(2)|RMB}}</h2>

    </div>
    <script>
    // 用法一:
    // 通过Vue.filter() 进行全局声明,是在vm对象创建之前声明好的。
    // 语法:Vue.filter("过滤器名称", func);
        Vue.filter('RMB',function (data) {
            return '¥' + data;
        });
        var vm = new Vue({
            el: '#app',
            data:{
                price: 1234.567890
            },
            // 用法二:
        // 通过vm对象内部的filters属性进行局部声明,过滤器只能用于当前vm实例对象。
            filters: {
                p_format(data,num){
                    return data.toFixed(num)
                }
            }
        })
    </script>
</body>
</html>

效果:
在这里插入图片描述

总结

  1. 一个数据可以调用多个过滤器,每个过滤器之间使用 |竖杠隔开,但是过滤器之间的执行顺序是从左往右执行,所以有可能产生冲突问题.这时候可以尝试调整调用过滤器之间的顺序

  2. 过滤器本质上就是一个函数,所有我们必须有返回值,否则数据调用了过滤器以后,无法得到处理后的数据结果

  3. vue1.x版本时,有内置过滤器的,但是官方认为,过多的封装工具给开发者使用,会容易造成框架本身的臃肿,所以在vue2.x版本以后又废除了.

  4. 过滤器本质上来说就是函数,所以函数不仅只有一个参数的.我们过滤器也支持多个参数的写法.

计算属性

可以把调整data数据的代码存在在该属性中
语法:

computed: {
            新的变量名: function(){
               // 内部必须有返回值
            },

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <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: {
            price: 19.999888,
        },
        // 计算属性,重新产生一个新的变量值
        computed: {
            /*
            新的变量名: function(){
                // 内部必须有返回值,如果要对原有的data里面的属性计算调用,则通过this.变量名来调用
            },
            */
            new_price: function () {
                return this.price.toFixed(2);
            },
            href: function () {
                return location.href;
            }
        }
    })
</script>
</body>
</html>

效果:
在这里插入图片描述

监听属性

侦听属性,可以帮助我们侦听data某个数据的变化,从而做相应的自定义操作。
  侦听属性是一个对象,它的键是要监听的对象或者变量,值一般是函数,当侦听的data数据发生变化时,会执行的对应函数,这个函数在被调用时,vue会传入两个实参,第一个是变化前的数据值,第二个是变化后的数据值。
语法:

watch: {
           监听变量: function(new_data, old_data){
               // 执行的代码
            },

示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>监听属性</title>
    <script src="js/vue.js"></script>
</head>
<body>
    <div id="app" align="center">
        <h2>{{num}}</h2>
        <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(new_data,old_data);
                    if(this.num>3){
                        this.num = 3;
                    }
                }
            }
        })
    </script>
</body>
</html>

效果:
在这里插入图片描述
案例:三级联动

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>三级联动</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div style="height: 100px">

</div>
<div id="app" align="center">
    <select v-model="location_id">
        <option value="0">选择你的位置</option>
        <option v-for="item in location_list" :value="item.id">{{item.name}}</option>
    </select>
    <select v-model="hero_id">
        <option value="0">选择你的英雄</option>
        <option v-if="location_id==item.parent_id" v-for="item in hero_list" :value="item.id">{{item.name}}</option>
    </select>
    <select v-model="skill_id">
        <option value="0">选择你的技能</option>
        <option v-if="hero_id==item.parent_id" v-for="item in skill_list" :value="item.id">{{item.name}}</option>
    </select>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            location_id: 0,
            location_list: [
                {'id': 1, 'name': 'tank'},
                {'id': 2, 'name': 'support'}
            ],
            hero_list: [],
            hero_id: 0,
            skill_list: [],
            skill_id: 0
        },
        watch: {
            location_id(){
                // console.log(this.location_id);
                this.hero_list=[
                    {'parent_id':1, 'id':1, 'name':'温斯顿'},
                    {'parent_id':1, 'id':2, 'name':'查莉雅'},
                    {'parent_id':2, 'id':3, 'name':'安娜'},
                    {'parent_id':2, 'id':4, 'name':'禅雅塔'}
                ];
                this.hero_id = 0;
                this.skill_id = 0;
            },
            hero_id(){
                this.skill_list=[
                    {'parent_id':1, 'id':1, 'name': '原始暴怒'},
                    {'parent_id':1, 'id':2, 'name': '喷气背包'},
                    {'parent_id':2, 'id':3, 'name': '重力喷涌'},
                    {'parent_id':2, 'id':4, 'name': '主盾'},
                    {'parent_id':3, 'id':5, 'name': '生化手雷'},
                    {'parent_id':3, 'id':6, 'name': '强化激素'},
                    {'parent_id':4, 'id':7, 'name': '圣'},
                    {'parent_id':4, 'id':8, 'name': '乱'}
                ];
                this.skill_id = 0;
            }
        }
    })
</script>
</body>
</html>

效果:
在这里插入图片描述

vue对象的生命周期

每个Vue对象在创建时都要经过一系列的初始化过程。在这个过程中Vue.js会自动运行一些叫做生命周期的的钩子函数,我们可以使用这些函数,在对象创建的不同阶段加上我们需要的代码,实现特定的功能。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue的生命周期</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
    <p>{{num}}</p>
    <button @click="num++">投票</button>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            num: 0 ,
        },
         // 8个钩子函数,常用的有6个下面列举出来的。还有2个不常用分别是:destroy和bdforeDestroy
        // bdforeCreate会在vm对象创建实例化以后,初始化vm内部数据之前调用
        beforeCreate(){  // 类似与Python面向对象的__new__
            console.log("----------beforeCreate start---------");
            console.log(this);
            console.log(this.$el);  // 还没有对视图模板进行初始化
            console.log(this.num);  // 还没有对数据进行初始化
            console.log("##########beforeCreate end#########");
        },
        // created 在vm对象实例化并初始化数据以后,视图模板加载之前调用
        // 一般情况下,会在这里编写ajax代码,从服务器端获取数据并赋值给data里面的数据(***)
        created(){
            console.log("----------created start---------");
            console.log(this);
            console.log(this.$el);  // 还没有对视图模板进行初始化
            console.log(this.num);  // 此时已经可以拿到数据了
            console.log("##########created end#########");
        },
        // beforeMount 在加载视图以后,给数据赋值之前调用
        beforeMount(){
            console.log("----------beforeMount start---------");
            console.log(this);
            console.log(this.$el);  // 已经拿到试图模板,但是数据还没别渲染
            console.log(this.num);  // 此时已经可以拿到数据了
            console.log("##########beforeMount end#########");
        },
        // 加载视图并进行数据赋值以后调用
        // 一般情况下,会在这里编写操作界面的代码,调整样式,制作初始化的js特效(***)
        mounted(){
            console.log("----------mounted start---------");
            console.log(this);
            console.log(this.$el);  // 已经拿到试图模板,但是数据还没别渲染
            console.log(this.num);  // 此时已经可以拿到数据了
            console.log("##########mounted end#########");
        },
        // 更新数据时,修改data数据以后,对模板的数据赋值之前调用
        beforeUpdate(){
            console.log("----------beforeUpdate start---------");
            console.log(this);
            console.log(this.$el.innerHTML);
            console.log(this.num);  // 此时已经可以拿到数据了
            console.log("##########beforeUpdate end#########");
        },
        // 更新数据完成以后调用
        updated(){
            console.log("----------updated start---------");
            console.log(this);
            console.log(this.$el.innerHTML);
            console.log(this.num);  // 此时已经可以拿到数据了
            console.log("##########updated end#########");
        }
    })
</script>
</body>
</html>
阻止事件冒泡

什么是事件冒泡?  
  事件绑定时,如果同时给父子元素绑定同名事件,则在子元素触发事件以后,父元素的同名事件也会触发到,这种现象就是事件冒泡.

优缺点
好处:一个触发,多次执行
利用事件冒泡的好处,可以实现事件委托.
坏处:形成事件的联动反应.
  • js原生阻止的事件冒泡:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>事件冒泡</title>
    <style>
        .father{
            width:300px;
            height: 300px;
            background: green;
        }
        .son{
            width: 100px;
            height: 100px;
            background: red;
        }
    </style>
</head>
<body>
<div class="father">
    <div class="son"></div>
</div>
<ul id="content_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 fa_dic = document.getElementsByClassName('father')[0];
    var son_dic = document.getElementsByClassName('son')[0];
    fa_dic.onclick = function () {
        alert('再来酒一碗 再来酒一碗');
    };
    son_dic.onclick = function (e) {
        alert('何不如 烟花三月下江南');
        e.stopPropagation()  // 原生的js阻止事件冒泡
    };

	// 批量添加事件
	// 批量绑定事件,当数据量非常大时,会出现页面加载慢。
    // var li_list = document.getElementsByTagName('li')
    // for (i = 0; i < li_list.length; i++) {
    //     li_list[i].onclick = function () {
    //         console.log(this.innerHTML);
    //     }
    // };
	// 为了解决上的问题,我们可以利用事件委托来完成。
    // 事件委托:利用事件冒泡的特性,把子元素要执行的代码,委托给父元素来执行
    var fa_ul = document.getElementById('content_list');
    fa_ul.onclick = function (e) {
        console.log(e);		// 事件对象:浏览器会把本次事件相关的内容和属性,封装成一个对象作为参数提供给我们
        console.log(e.target);	// 事件触发对象
        let _this = e.target;
        console.log(_this.innerHTML)
    }
</script>
</body>
</html>
  • vue的事件冒泡和阻止事件冒泡:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue事件冒泡</title>
    <script src="js/vue.js"></script>
    <style>
        .father{
            width:300px;
            height: 300px;
            color: white;
            background: green;
        }
        .son{
            width: 100px;
            height: 100px;
            background: red;
        }
    </style>
</head>
<body>
<div id="app">
    <div class="father" @click="add">
        <h2>{{num}}</h2>
        <!--使用 事件名称.stop 即可阻止事件冒泡-->
        <div class="son" @click.stop="add"></div>
    </div>
</div>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            num: 0
        },
        methods: {
            add(){
                this.num++;
            }
        }
    })
</script>
</body>
</html>

效果:
在这里插入图片描述

阻止元素的默认行为
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>阻止元素的默认行为</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
    <a href="" @click.prevent="add">a标签</a>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {

        },
        methods: {
            add(){
                alert("点击了a标签!");
            }
        }
    })
</script>
</body>
</html>

效果对比:
没有prevent,会刷新
在这里插入图片描述
有prevent,不会刷新
在这里插入图片描述

综合案例-计划列表

在这里插入图片描述
首先进行需求分析:

1. 把计划数据展示到页面中

2. 当用户填写计划以后,点击"增加"按钮时,把数据添加到计划列表中,展示出来

3. 当用户点击"删除"按钮,把当前一行的计划数据移除掉

4. 当用户点击"↑",则需要把当前一行和上一行数据之间的位置,进行互换

5. 当用户点击"↓",则需要把当前一行和下一行数据之间的位置,进行互换

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>计划列表</title>
    <script src="js/vue.js"></script>
    <style>
        .list_con {
            width: 600px;
            margin: 50px auto 0;
        }

        .inputtxt {
            width: 550px;
            height: 30px;
            border: 1px solid #ccc;
            padding: 0;
            text-indent: 10px;
        }

        .inputbtn {
            width: 40px;
            height: 32px;
            padding: 0;
            border: 1px solid #ccc;
        }

        .list {
            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" v-model="plan">
    <input type="button" name="" value="增加" id="btn1" class="inputbtn" @click="add">

    <ul id="list" class="list">
        <!-- javascript:void(0); # 阻止a标签跳转 -->
        <li v-for="item,index in data_list">
            <span>{{item.title}}</span>
            <a href="javascript:void(0);" class="up" @click="move_up(index)"></a>
            <a href="javascript:void(0);" class="down" @click="move_down(index)"></a>
            <a href="javascript:void(0);" class="del" @click="del(index)">删除</a>
        </li>

    </ul>
</div>
<script>
    var vm = new Vue({
        el: '#ToDoList',
        data: {
            plan:'',
            data_list: [
                {"title":"学习html"},
                {"title":"学习css"},
                {"title":"学习javascript"},
            ]
        },
        methods: {
            add(){
            	// this.data_list.push({"title": this.plan});  // 追加
                // this.data_list.unshift({"title": this.plan});  // 前置插入
                if(this.plan.length>0){
                	// this.data_list.splice(this.data_list.length + 1, 0, {"title": this.plan});  // 尾部追加
                    this.data_list.splice(0,0,{'title':this.plan});   // 头部添加
                }
            },
            del(index){
           	 	// 数组的splice删除的语法:data_list.splice(index, 1)
                this.data_list.splice(index,1);
            },
            move_up(index){
                if(index>0){
                    let current = this.data_list.splice(index,1)[0];
                    this.data_list.splice(index-1,0,current);
                    }
            },
            move_down(index){
                let current = this.data_list.splice(index,1)[0];
                this.data_list.splice(index+1,0,current);
            }
        }
    })
</script>
</body>
</html>

效果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值