2-Vue- vue對象提供的屬性功能

今日內容

  • 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. Vue對象提供的屬性功能

3.1 過濾器

過濾器,就是vue容許開發者自定義的文本格式化函數,可使用在兩個地方:輸出內容和操做數據中。javascript

定義過濾器的方式有兩種。css

3.1.1 使用Vue.filter()進行全局定義

    // 全局過濾器
    Vue.filter("format",function(money){
        return money.toFixed(2)+"元"; // js中提供了一個toFixed方法能夠保留2位小鼠
    });

3.1.2 在vue對象中經過filters屬性來定義

<!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數據的代碼存在在該屬性中。html

<!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某個數據的變化,從而作相應的自定義操做。vue

偵聽屬性是一個對象,它的鍵是要監聽的對象或者變量,值通常是函數,當偵聽的data數據發生變化時,會自定執行的對應函數,這個函數在被調用時,vue會傳入兩個形參,第一個是變化前的數據值,第二個是變化後的數據值。java

<!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會自動運行一些叫作生命週期的的鉤子函數,咱們可使用這些函數,在對象建立的不一樣階段加上咱們須要的代碼,實現特定的功能。python

<!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>

總結:ajax

在vue使用的過程當中,若是要初始化操做,把初始化操做的代碼放在 mounted 中執行。
mounted階段就是在vm對象已經把data數據實現到頁面之後。通常頁面初始化使用。例如,用戶訪問頁面加載成功之後,就要執行的ajax請求。

另外一個就是created,這個階段就是在 vue對象建立之後,把ajax請求後端數據的代碼放進 created

3.4 阻止事件冒泡和刷新頁面

事件冒泡:指代js中子元素的事件觸發之後,會致使父級元素的同類事件一併被觸發到。後端

事件冒泡有好處,也有壞處。數組

好處:若是能正確利用這種現象,能夠實現事件委託,提高特效的性能app

壞處:若是沒有正確使用,則會致使沒必要要的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>Title</title>
    <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>   <!-- @click.stop來阻止事件冒泡 -->
        </div>

        <form action="#">
            <input type="text">
            <input type="submit">
            <input type="submit" value="提交02" @click.prevent=""> <!-- @click.prevent來阻止表單提交 -->
        </form>
    </div>

</body>
</html>

3.5 綜合案例-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>
    <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 list</h2>
        <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>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;
        }

        .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 list</h2>
    <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">
        <!-- javascript:; # 阻止a標籤跳轉 -->
        <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>
做業1參考答案

做業2答案

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <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>
做業2參考答案
相關文章
相關標籤/搜索