Vue2.x-04Vue插值、資料繫結、樣式繫結、過濾器
文章目錄
概述
Vue2.x-03使用vue-cli搭建Vue開發環境搭建好了開發環境,也看了下專案結構,接下來繼續來分析下建立的專案吧。
Vue 例項啟動入口
Vue 例項啟動入口 的是main.js ,那就先看看main.js吧
import Vue from 'vue'
import App from './App.vue'
new Vue({
el: '#app',
render: h => h(App)
})
Vue2必須通過 Render 方法來實現渲染 ,h => h(App) 這種寫法其實是ES6的寫法,當我們渲染的函式裡只有一個引數的時候,可以通過 =>的方式來複制 ,等同於
render: function(h) {
return h(App);
}
分析main.js的程式碼可知,main.js完成的主要工作是: 通過 import 將一個 Vue .js 的元件檔案引入,並建立一個 Vue 物件的例項,在 Vue 例項中用 Render 方法來繪製這個 Vue 元件( App )完成初始化。
el: '#app'
將 Vue 例項繫結到一個頁面上,真實存在的元素 App Vue 程式就引導成功了。
開啟 index.html 檔案可以看到 Vue 例項與頁面的對應關係
也就是說, 一個 Vue 例項必須與一個頁面元素繫結。
App.vue分析
我們通過腳手架為我們建立的這個 App 元件,其主要的結構如下:
<template>
<div id="app">
</div>
</template>
<script type="text/ecmascript-6">
export default{
name:'app'
}
</script>
<style></style>
主要有三部分組成:
- template:檢視模板
- script:元件定義
- style:元件樣式表
Vue 的基本組成部分
插值
Vue 的檢視模板是基於 DOM 實現的,這意味著所有的 Vue 模板都是可解析的有效的HTML。比如我們在模板上定義一個標題,並通過資料繫結語法將App元件上定義的資料模型繫結到模板上。
首先,在元件指令碼定義中使用 data 定義用於內部訪問的資料模型:
export default{
....
data () {
return {
title: "artisan learn vue"
}
}
}
以上方式 data返回了 Object 物件的函式, 使用函式返回是為了可以具有更高的靈活性,例如對內部資料進行一些初始化的處理,推薦使用。
當然了,data也可返回一個物件屬性,如下所示:
export default{
...
data : {
title: "artisan learn vue"
}
}
在模板中引用 data.title 資料時我們並不需要寫上 data,這只是 Vue 定義時的一個內部資料容器,通過 Vue 模組的插值方式直接寫上 title 即可
<h1>{{ title }}</h1>
用雙大括號{{}}引住的內容被稱為“Mustache ” 語法, Mustache 標籤會被相應資料物件的 title 屬性的值替換。每當這個屬性變化時它也會更新。
插值是 Vue 模板語言的最基礎用法,很多的變數輸出都會採用插值的方式,而且插值還可以支援 JavaScript 表示式運算和過濾器。
從 Vue2 開始,元件模板必須且只能有一個頂層元素,如果在元件模組內設直多個頂層元素將會引發編譯異常 。
在上述程式碼中 template 屬性是 V,也就是檢視, title 屬性是 M,也就是模型。
資料繫結
舉個例子,我們先約定一個數據模型來表述 Todo, 定義結構如下
{
value: '任務1', //待辦事項的文字內容
done: false // 標記該事項是否已完成
}
由於是多個事項,那麼這個資料模型應該是一個數組,為了能先顯示這些待辦事項,先設定一些樣本資料。在 Vue 例項定義中的 data 屬性中加入以下程式碼 :
export default {
data () {
return {
title : "TodoList",
todos: [
{
value:'任務一',
done:true
},
{
value:'任務二',
done:false
},
{
value:'任務三',
done:true
}
]
}
}
}
data幹啥用的呢 ? 可以將 Vue 例項定義看作一個類的定義,data相當於這個類的內部欄位屬性的定義區域。在 Vue 例項內的其他地方可以直接用 this 引用data 內定義的任何屬性,比如 this.title 就是引用了 data.title
v-for渲染陣列
要顯示 todos 的資料就需要使用 Vue 模板的一個最常用 的 v-for 指令標記,它可以用於列舉一個數組並將物件渲染成一個列表.這個指令使用與 JS 類似的語法對 items 進行列舉,形式為 item in items
, items 是資料陣列 , item 是當前陣列元素的別名
<ul>
<li v-for="todo in todos">
<lable>{{ todo.value }}</lable>
</li>
</ul>
如果要輸出待辦事項的序號,可以用 v-for 中 隱藏的一個 index 值來進行輸出,
<ul>
<li v-for="(todo,index) in todos" :id="index">
<lable>{{ index + 1 }}.{{ todo.value }}</lable>
</li>
</ul>
索引是由 0 開始計數的,要輸出的序號應該從 1 開始,所以這裡是index + 1.
這裡除了用插值繫結,還使用了屬性繫結語法,就是上面的:id="index"
,意思是將 index 的值輸出到 DOM 的 id 屬性上,如果沒有在 id 前面加上“:”,那麼 Vue 就會認為我們正在為 id屬性賦予一個字串。
v-for渲染物件屬性
v-for 不單單可以迴圈渲染陣列,還可以渲染物件屬性.
<li v-for="info in obj">
{{ info }}
</li>
data () {
return {
obj: {
name:"小工匠1",
sex:'男',
age:20
}
}
}
在 Vue 的程式碼中直接操作 DOM 是不被推薦的,並不像Jquery那樣。 DOM 是被 Vue 直接託管的,所有“繫結”到 DOM 上的變數一旦發生變化, DOM 所對應的屬性就會被 Vue 自動重繪而不需要像 jQuery那樣通過編碼來顯式地操作,這才是繫結的意義所在。
樣式繫結
沒有樣式的輸出結果樣子很醜,此時我們就需要用 css 來美化我們的 App. 這裡我們使用less
Step1: 安裝 webpack 支援 less 編譯的包的方法:
npm i less style-loader css-loader less-loader - D
Step2: 安裝完成後在 webpack.config.js 的 modules 設定內加入以下的配置:
{
test: /\.less$/,
loader:"style-loader!css-loader!less-loader"
}
Step3: 在/assets/中新增一個 todos.less 檔案,並在 App.vue 的元件定義內引入 less 樣式表
import './assets/todos.less'
export default{
.....
}
Step4: 通過class使用樣式
執行應用,目前的樣子如下:
所有的待辦事項都沒有顯示任何的狀態,此時就需要使用 Vue的樣式繫結功能了 。
將 done=true的待辦事項<li>
繫結一個 checked 的樣式類:
:class="{'checked':todo.done}"
完整程式碼如下
<li v-for="(todo,index) in todos" :class="{'checked':todo.done}">
<label>{{ index + 1 }}.{{ todo.value }}</label>
</li>
效果如下:
Vue 的屬性繫結語法是通過 v-bind 實現的,完整的寫法是這樣
<li v-for="(todo,index) in todos" v-bind:class="{'checked':todo.done}">
但 v-bind 可以採用縮寫方式“:”表示,採用完整寫法又將出現各種重複,所以建議還是直接使用縮寫方式,這樣會更直觀。
總結一下:
-
Vue 的屬性繫結語法是 attribute=”expression”, attribute 就是元素接收的屬性值(既可以是原生的也可以是自定義的) , expression 則是在 Vue 元件內由 data 或props性值(既可以是原生的也可以是自定義的),expression 則是在 Vue 元件內由 data 或 props
-
元素屬性中必須加上: ,否則Vue認為是向這個屬性賦上字串值而不是Vue 元件上定義的屬性引用
-
Vue 的樣式繫結,無論繫結的是樣式類還是樣式屬性,:class 和:style 表示式內 一定是一個 JSON 物件
-
:class 的 JSON 物件的值一定是布林型的, true 表示加上樣式, false 表示移除樣式類
-
:style 的 JSON 物件則像是一個樣式配置項, key 宣告屬性名, value 則是樣式屬性的具體值。
過濾器
現在我們打算在待辦事項的右側增加一個時間欄位 createTime,並用<time>
元素表示。
效果如下:
很明顯,時間的輸出的是一個整數,不是我們想要的結果。因為將 Date 物件直接輸出的話, JavaScript 引擎會將其時間戳作為值輸出 ,所以我們需要對這個時間戳進行格式化 。
這時候我們需要依賴先安裝 moment.js , 先安裝 moment.js :
npm i moment -S
Step1:引入 moment,並設定 moment 的區域為中國:
import moment from 'moment'
import 'moment/locale/zh-cn'
moment.locale('zh-cn')
Step2:加入一個 date 的過濾器:
filters:{
date(val){
return moment(val).calendar()
}
}
Step3:模板上應用這個過濾器:
<time>{{ todo.createTime | date }}</time>
效果如下:
在所有的過濾器中是沒有 this 引用的,過濾器內的 this 是一個 undefined 的值,所以不要在過濾器內嘗試引用元件例項內的變數或方法,否則會引發空值引用的異常 。
App.vue
<template>
<div id="app">
<h1>{{ title }}</h1>
<ul class="todos">
<li v-for="(todo,index) in todos" :class="{'checked':todo.done}">
<label>{{ index + 1 }}.{{ todo.value }}</label>
<time>{{ todo.createTime | date }}</time>
</li>
</ul>
</div>
</template>
<script type="text/ecmascript-6">
import './assets/todos.less'
import moment from 'moment'
import 'moment/locale/zh-cn'
moment.locale('zh-cn')
export default {
name: 'app',
data () {
return {
title : "TodoList",
todos: [
{
value:'任務一',
done:true,
createTime:Date.now()
},
{
value:'任務二',
done:false,
createTime:Date.now() - 300000
},
{
value:'任務三',
done:true,
createTime:Date.now() + 300000
}
]
}
},
filters:{
date(val){
return moment(val).calendar()
}
}
}
</script>
<style>
</style>