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>
上一篇 下一篇

猜你喜欢

热点阅读