1. 程式人生 > >Vue(一) 資料繫結和第一個Vue應用

Vue(一) 資料繫結和第一個Vue應用

學習 Vue.js 最有效的方法是檢視官網文件

資料繫結和第一個Vue應用

先從一段簡單的 HTML 程式碼開始,感受 Vue.js 最核心的功能。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue示例</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <input type="text" v-model="name" placeholder="你的名字">
        <h1>你好,{{ name }}</h1>
    </div>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                name: ''
            }
        })
    </script>
</body>
</html>

這是一段非常簡單的程式碼,但是體現了 Vue 最核心的功能:雙向繫結。在輸入框輸入的內容會實時顯示在頁面的 h1 標籤內。

Vue例項與資料繫結

例項與資料

通過建構函式 Vue 就可以建立一個 Vue 的根例項,並啟動 Vue 應用:

var app = new Vue({
    //選項
})

變數 app 就代表了這個 Vue 例項。

首先,必不可少的一個選項就是 el 。el 用於指定一個頁面已存在的 DOM 元素來掛載 Vue 例項,它可以是 HTMLElement,也可以是 CSS 選擇器,比如:

<div id="app"><div>

var app = new Vue({
    el: document.getElementById('app')  //或者是'#app'
})

掛載成功後可以使用 app.$el 來訪問該元素。

通過 Vue 例項的 data 選項,可以宣告應用內需要雙向繫結的資料。

var app = new Vue({
    el: '#app',
    data: {
        a: 2
    }
})

console.log(app.a); // 2

除了顯示宣告資料外,也可以指向一個已有的變數,並且他們之間預設建立了雙向繫結,當修改其中一個,另一個也會一起變化。

var myDate = {
    a: 1
}

var app = new Vue({
    el: '#app',
    data: myDate
})

生命週期

每個 Vue 例項建立時,都會經歷一系列的初始化過程,同時也會呼叫相應的生命週期鉤子,我們可以利用這些鉤子,在合適的時機執行我們的業務邏輯,如果你使用過 jQuery,一定知道它的 ready() 方法,比如以下示例:

$(document).ready(function() {
    //DOM 載入完後,會執行這裡的程式碼
})

Vue的生命週期鉤子與之類似,比較常用的有:

  • created:例項建立完成後呼叫,此階段完成了資料的觀測等,但尚未掛載,$el 還不可用,需要初始化處理一些資料時會比較有用。
  • mounted:el 掛載到例項上後呼叫,一般我們的第一個業務會在這裡開始。
  • beforeDestory:例項銷燬之前呼叫,主要解綁一些使用 addEventListener 監聽的事件等。

這些鉤子與 el 和 data 類似,也是作為選項寫入 Vue 例項內,並且鉤子的 this 指向的是呼叫它的 Vue 例項:

var app = new Vue({
    el: '#app',
    data: {
        a: 2
    },
    created: function() {
        console.log(this.a);    // 2
    }
    mounted: function() {
        console.log(this.$el);  // <div id="app"></div>
    }
})

插值與表示式

使用雙大括號(Mustache 語法)"{{}}" 是最基本的文字插值方法,它會將我們雙向繫結的資料實時顯示出來,例如:

<div id="app">
    <h1>{{ name }}</h1>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            name: 'Vue.js'
        }
    })
</script>

大括號裡的內容會被替換為 Vue.js, 通過任何方式修改資料 name,大括號裡的內容都會被實時替換,比如下面的示例,實時顯示當前的時間,每秒更新:

<div id="app">
    <p>時間:{{ date }}</p>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            date: new Date()
        },
        mounted: function () {
            this.timer = setInterval(() => {
                this.date = new Date();
            }, 1000)
        },
        beforeDestory: function () {
            if(this.timer) {
                clearInterval(this.timer);
            }
        }
    })
</script>

這裡的 {{ date }} 輸出的是瀏覽器預設的時間格式,比如 2017-01-02T14:04:49.470Z,並非格式化的時間(2017-01-02 22:04:49),所以需要注意時區,有多種方法可以對時間格式化,比如賦值時先使用自定義的函式處理。Vue 的過濾器(filter)或計算屬性(computed)也可以實現。

如果有的時候想輸出 HTML,而不是將資料解釋後的純文字,可以使用 v-html:

<div id="app">
    <span v-html="link"></span>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            link: '<a href="#">這是一個連結</a>'
        }
    })
</script>

如果想顯示 {{}} 標籤,使用 v-pre 即可跳過這個元素和它的子元素的編譯過程,例如:

<span v-pre>{{ 這裡的內容不會被編譯 }}</span>

在 {{}} 中,除了簡單的繫結屬性值外,還可以使用 JavaScript 表示式進行簡單的運算、三元運算等,例如:

<div id="app">
    {{ number /10 }}
    {{ isOK ? '確定' : '取消' }}
    {{ text.split(',').reverse().join(',') }}
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            number: 100,
            isOK: false,
            text: '123, 456'
        }
    })
</script>

Vue.js 只支援單個表示式,不支援語句和流控制。另外,在表示式中,不能使用使用者自定義的全域性變數,只能使用 Vue 白名單內的全域性變數,例如 Math 和 Date。以下是一些無效的示例:

<!-- 這是語句,不是表示式-->
{{ var book = 'Vue.js'}}
<!-- 不能使用流控制,要使用三元運算 -->
{{ if(ok) return msg}}

過濾器

Vue.js 支援在 {{}} 插值的尾部新增管道符"(|)"對資料進行過濾,經常用於格式化文字,比如字母全部大寫,貨幣千位使用逗號分隔。過濾的規則是自定義的,通過給 Vue 例項新增選項 filters 來設定,例如在上一節中實時顯示當前時間的案例,可以對時間進行格式化處理。

<div id="app">
    <p>時間:{{ date | formatDate }}</p>
</div>
<script>
    var padDate = function (value) {
        return value < 10 ? '0' + value : value;
    };
    var app = new Vue({
        el: '#app',
        data: {
            date: new Date()
        },
        methods: {
        },
        filters: {
            formatDate: function (value) {
                var date = new Date(value);
                var year = date.getFullYear();
                var month = padDate(date.getMonth() + 1);
                var day = padDate(date.getDate());
                var hour = padDate(date.getHours());
                var minutes = padDate(date.getMinutes());
                var second = padDate(date.getSeconds());
                return year + '-' + month + '-' + day + '-' + hour + '-' + minutes + '-' + second;
            }
        },
        mounted: function () {
            this.timer = setInterval(() => {
                this.date = new Date();
            }, 1000)
        },
        beforeDestory: function () {
            if(this.timer) {
                clearInterval(this.timer);  //在 Vue 例項銷燬前,清除我們的定時器
            }
        }
    })
</script>

過濾器也可以串聯,而且可以接收資料,例如:

<!-- 串聯 -->
{{ message | filterA | filterB }}

<!-- 接收引數 -->
{{ message | filterA('arg1', 'arg2') }}

這裡的字串 arg1 和 arg2 將分別傳給過濾器的第二個和第三個引數,因為第一個引數是資料本身。

過濾器應當用於簡單的文字轉換,如果要實現複雜的資料變換,應當使用計算屬性。

指令與事件

指令是 Vue.js 模板中最常用的功能,它帶有字首 v-,指令的主要職責就是當其表示式的值改變時,相應地將某些行為應用到 DOM 上。

Vue.js 內建了很多指令,現在只需瞭解 v-bind 和 v-on 指令。

v-bind

v-bind 的基本用途是動態更新 HTML 的屬性, 比如 id,class,例如:

<div id="app">
    <a v-bind:href="url">百度一下</a>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            url: 'https://www.baidu.com'
        }
    })
</script>

此時示例中的連結地址與 url 進行了繫結,當通過某種方法改變 url 時,連結就會更新。

v-on

v-on 用來繫結事件監聽器,這樣就可以做一些互動了,例如:

<div id="app">
    <p v-if="show">這是一段文字</p>
    <button v-on:click="change">點我切換</button>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            show: true
        },
        methods: {
            change: function () {
                this.show = !this.show
            }
        }
    })
</script>

在 button 按鈕上,使用 v-on:click 給該元素繫結一個點選事件,在普通的元素上,v-on 可以監聽原生的 DOM 事件,除了 click 外,還有 dbclick,keyup,mousemove 等。表示式可以是一個方法名,這些方法都寫在 Vue 例項的 methods 屬性內,並且都是函式的形式,函式內的 this 指向當前 Vue 例項本身,因此你可以使用 this.xxx 的形式訪問或修改資料。

表示式除了方法名,也可以直接是一個內聯語句,上例可改為:

<div id="app">
    <p v-if="show">這是一段文字</p>
    <button v-on:click="show = !show">點我切換</button>
</div>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            show: true
        }
    })
</script>

語法糖

語法糖是指在不影響功能的情況下,新增某種方法實現同樣的效果,從而方便程式開發。

Vue.js 的 v-bind 和 v-on 指令,都提供了語法糖,也可以說是縮寫。

v-bind 可以直接寫成一個 “:” :

<a v-bind:href="url">百度一下</a>
<!-- 縮寫為 -->
<a :href="url">百度一下</a>

v-on 可以直接用 “@” 來縮寫:

<button v-on:click="change">點我切換</button>
<!-- 縮寫為 -->
<button @:click="change">點我切換</button>

使用語法糖可以簡化程式碼的書寫。