1. 程式人生 > >Vue2.x-04Vue插值、資料繫結、樣式繫結、過濾器

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>

效果如下:
Step4:

在所有的過濾器中是沒有 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>