Vue對象提供的屬性功能

一. 過濾器

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

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

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

  示例:html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>過濾器</title>
    <script src="js/vue.js"></script>
</head>
<body>

<div id="app">
    {{price}}
    <p>{{price|RMB}}</p>
</div>
<script>
    // 經過Vue.filter() 進行全局聲明,是在vm對象建立以前聲明好的。
    // 語法:Vue.filter("過濾器名稱", func);
    Vue.filter('RMB', function (data) {
        return "" + data;
    });
    var vm = new Vue({
        el: "#app",
        data: {
            price: 10.3333333,
        }
    })
</script>
</body>
</html>

  效果:vue

  2. 在Vue對象中經過filters屬性來定義

  示例:java

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>過濾器</title>
    <script src="js/vue.js"></script>
</head>
<body>

<div id="app">
    {{price}}
    <p>{{price|RMB}}</p>
    <p>{{price|p_format(2)}}</p>
    <!--這裏會報錯,由於過濾器後的數據,已經不是數值了。爲了不報錯,只需將過濾器換個位置便可。-->
    <!--<p>{{price|RMB|p_format(2)}}</p>-->
    <p>{{price|p_format(2)|RMB}}</p>
</div>
<script>
    // 用法一:
    // 經過Vue.filter() 進行全局聲明,是在vm對象建立以前聲明好的。
    // 語法:Vue.filter("過濾器名稱", func);
    Vue.filter('RMB', function (data) {
        return "" + data;
    });
    var vm = new Vue({
        el: "#app",
        data: {
            price: 10.3333333,
        },
        // 用法二:
        // 經過vm對象內部的filters屬性進行局部聲明,過濾器只能用於當前vm實例對象。
        filters: {
            // "過濾器名稱": function(){
            //     // 過濾器執行的代碼
            // }
            // p_format: function (data, num) {
            //     return data.toFixed(num);
            // }
            // 能夠簡寫爲
            p_format(data, num){
                return data.toFixed(num);
            }
        }
    })
</script>
</body>
</html>

  效果:ajax

  總結:後端

1. 一個數據能夠調用多個過濾器,每一個過濾器之間使用 "|"豎槓隔開,可是過濾器之間的執行順序是從左往右執行,因此有可能產生衝突問題.這時候能夠嘗試調整調用過濾器之間的順序

2. 過濾器本質上就是一個函數,全部咱們必須有返回值,不然數據調用了過濾器之後,沒法獲得處理後的數據結果
3. vue1.x版本時,有內置過濾器的,可是官方認爲,過多的封裝工具給開發者使用,會容易形成框架自己的臃腫,因此在vue2.x版本之後又廢除了.
4. 過濾器本質上來講就是函數,因此函數不只只有一個參數的.咱們過濾器也支持多個參數的寫法.

二. 計算屬性

  咱們以前學習過字符串反轉,若是直接把反轉的代碼寫在元素中,則會使得其餘同事在開發時時不易發現數據被調整了,因此vue提供了一個計算屬性(computed),可讓咱們把調整data數據的代碼存在在該屬性中。數組

  示例:瀏覽器

<!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: 10.3333333,
        },
        // 計算屬性,從新產生一個新的變量值
        computed: {
            /*
            新的變量名: function(){
                // 內部必須有返回值,若是要對原有的data裏面的屬性計算調用,則經過this.變量名來調用
            },
            */
            new_price: function () {
                return this.price.toFixed(2);
            },
            href: function () {
                return location.href;
            }
        }
    })
</script>
</body>
</html>

  效果:服務器

三. 監聽屬性

  偵聽屬性,能夠幫助咱們偵聽data某個數據的變化,從而作相應的自定義操做。

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

  示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>監聽屬性(偵聽屬性)</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,
        },
        // 監聽屬性,監控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 id="app">
    地址:
    <select name="" v-model="province_id">
        <option value="0">請選擇省份</option>
        <option v-for="province in province_list" :value="province.id">{{province.name}}</option>
    </select>
    <select name="" 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 name="" v-model="area_id">
        <option value="0">請選擇地區</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":"廣東省"},
            ],
            city_list: [],
            area_list: [],
        },
        // 偵聽屬性
        watch: {
            province_id (){
                // 假設ajax從後端獲取的城市列表數據
                this.city_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.city_id = 0,
                this.area_id = 0
            },
            city_id(){
                this.area_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":"寶安區"},
                ]
            }
        }
    })
</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: 10,
        },
        // 8個鉤子函數,經常使用的有6個下面列舉出來的。還有2個不經常使用分別是:destroy和bdforeDestroy

        // bdforeCreate會在vm對象建立實例化之後,初始化vm內部數據以前調用
        beforeCreate(){
            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>

五. 阻止事件冒泡和阻止元素的默認行爲

  1.阻止事件冒泡

  什麼是事件冒泡?  

    事件綁定時,若是同時給父子元素綁定同名事件,則在子元素觸發事件之後,父元素的同名事件也會觸發到,這種現象就是事件冒泡.

  好處:一個觸發,屢次執行

    利用事件冒泡的好處,能夠實現事件委託.

  壞處:造成事件的聯動反應.

  下面咱們先一塊兒來回顧一下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_div = document.getElementsByClassName("father")[0];
    var son_div = document.getElementsByClassName("son")[0];
    fa_div.onclick = function () {
        alert("父元素");
    };
    son_div.onclick = function (e) {
        alert("子元素");
        e.stopPropagation();  // 原生的js阻止事件冒泡
    };

    // 批量添加事件
    // var li_list = document.getElementsByTagName("li");
    // for (let i = 0; i < li_list.length; i++){
    //     console.log(li_list[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">
        <h3>{{num}}</h3>
        <!--使用 事件名稱.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>

  效果:

  2. 阻止元素的默認行爲

  先看沒有阻止的一個效果:

  代碼:

<!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="add">a標籤</a>
</div>
<script>
    var vm = new Vue({
        el: "#app",
        data: {

        },
        methods: {
            add(){
                alert("點擊了a標籤!");
            }
        }
    })
</script>
</body>
</html>

  效果:(注意看刷新按鈕)

  下面來看一下vue阻止元素的默認行爲。

  代碼:

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

  效果:(注意看刷新按鈕)

六. 綜合案例-計劃列表

  首先咱們看下初識頁面代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ToDoList案例</title>
    <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">
    <input type="button" name="" value="增長" id="btn1" class="inputbtn">

    <ul id="list" class="list">
        <!-- javascript:void(0); # 阻止a標籤跳轉 -->
        <li>
            <span>學習html</span>
            <a href="javascript:void(0);" class="up"></a>
            <a href="javascript:void(0);" class="down"></a>
            <a href="javascript:void(0);" class="del">刪除</a>
        </li>
        <li>
            <span>學習css</span>
            <a href="javascript:void(0);" class="up"></a>
            <a href="javascript:void(0);" class="down"></a>
            <a href="javascript:void(0);" class="del">刪除</a>
        </li>
        <li>
            <span>學習javascript</span>
            <a href="javascript:void(0);" class="up"></a>
            <a href="javascript:void(0);" class="down"></a>
            <a href="javascript:void(0);" class="del">刪除</a>
        </li>
    </ul>
</div>
</body>
</html>

  效果:

  下面咱們經過vue來實現頁面的列表計劃管理。

  首先進行需求分析:

    1. 把計劃數據展現到頁面中

    2. 當用戶填寫計劃之後,點擊"增長"按鈕時,把數據添加到計劃列表中,展現出來

    3. 當用戶點擊"刪除"按鈕,把當前一行的計劃數據移除掉

    4. 當用戶點擊"↑",則須要把當前一行和上一行數據之間的位置,進行互換

    5. 當用戶點擊"↓",則須要把當前一行和下一行數據之間的位置,進行互換

   而後,開始一項一項的完成需求:

  代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue完成ToDoList需求</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="" v-model="plan" id="txt1" class="inputtxt">
    <input type="button" name="" @click="add_data" value="增長" id="btn1" class="inputbtn">

    <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);" @click="move_up(index)" class="up"></a>
            <a href="javascript:void(0);" @click="move_down(index)" class="down"></a>
            <a href="javascript:void(0);" @click="del_data(index)" class="del">刪除</a>
        </li>

    </ul>
</div>
<script>
    var vm = new Vue({
        el: "#ToDoList",
        data: {
            plan: "",
            data_list: [
                {"title":"學習html"},
                {"title":"學習css"},
                {"title":"學習javascript"},
            ]
        },
        methods: {
            // 添加計劃
            add_data(){
                if (this.plan.length > 0){
                    // this.data_list.push({"title": this.plan});  // 追加
                    // this.data_list.unshift({"title": this.plan});  // 前置插入
                    // 或者使用數組的splice方法
                    // 尾部追加 data_list.splice(data_list.length + 1, 0, "添加元素")
                    // this.data_list.splice(this.data_list.length + 1, 0, {"title": this.plan});
                    // 頭部添加 data_list.splice(0, 0, "添加元素")
                    this.data_list.splice(0, 0, {"title": this.plan});
                }
            },
            // 刪除計劃
            del_data(index){
                console.log(index);  // 獲取當前刪除元素的index
                // 數組的splice刪除的語法:data_list.splice(index, 1)
                this.data_list.splice(index, 1);
            },
            // 向上移動計劃
            move_up(index){
                if (index > 0){
                    // 1. 先把當前要移動的元素提取出來
                    // let current = this.data_list[index];
                    let current = this.data_list.splice(index, 1)[0];
                    // console.log(current);
                    // 2. 再把提取出來的元素放到index - 1的位置
                    this.data_list.splice(index - 1, 0, current);
                }
            },
            // 向下移動計劃
            move_down(index){
                // 1. 先把當前要移動的元素提取出來
                let current = this.data_list.splice(index, 1)[0];
                // 2. 再把提取出來的元素放在index + 1 的位置
                this.data_list.splice(index + 1, 0, current);
            }
        }
    })
</script>
</body>
</html>

  效果:

相關文章
相關標籤/搜索