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>
使用語法糖可以簡化程式碼的書寫。