標籤:

Vue學習筆記-3.Vue入門1-template

vue簡介

Vue.js(讀音 /vju?/,類似於 view) 是一套構建用戶界面的漸進式框架。與其他重量級框架不同的是,Vue 採用自底向上增量開發的設計。Vue 的核心庫只關注視圖層,它不僅易於上手,還便於與第三方庫或既有項目整合。另一方面,當與單文件組件和 Vue 生態系統支持的庫結合使用時,Vue 也完全能夠為複雜的單頁應用程序提供驅動。

上面的話,選自vue的中文文檔,我們可以從中看出:

1.從Vue官方文檔的定義來看,vue是構建用戶界面的框架

2.Vue的核心庫只關注視圖層,MVVM(Model-View-ViewModel)中的視圖層

這裡說了核心庫只關注視圖層,但是我個人認為,Vue對於MVVM(Model-View-ViewModel)中的三個部分,都有涉及。

MVVM 由 Model,View,ViewModel 三部分構成,Model 層代表數據模型,也可以在Model中定義數據修改和操作的業務邏輯;View 代表UI 組件,它負責將數據模型轉化成UI 展現出來,ViewModel 是一個同步View 和 Model的對象。

ViewModel在Vue中就是雙向數據綁定

參考自Vue.js 和 MVVM 小細節

因為,在vue單文件組件中,template標籤裡面的就是view層。script標籤中的數據和事件處理相關的欄位,如data,props,methods就代表了Model 層。最後ViewModel在Vue中就是雙向數據綁定就說明了vue中也有ViewModel層。

ViewModel在Vue中就是雙向數據綁定,這個說法,個人感覺不是很貼切。從官方文檔上看,ViewModel應該是vue的深入響應式原理

3.可以利用單文件組件和Vue 生態系統支持的庫來開發複雜的單頁應用程序

單文件組件就是一個文件定義了一個Vue組件,裡面包含了三個部分(我們在之前的小節中已經看到了)。 這個讀書筆記中的vue開發都使用了單文件組件,它解決了使用 Vue.component 來定義全局組件方式的諸多問題。

參考單文件組件 - vue.js

.vue文件構成

一般開發vue頁面或者說組件,我們都是通過.vue文件的形式,即vue的單文件組件。讓我們再來跟著count實例中的Counter.vue來看下vue基本語法。

1. template部分

<template>n <div id="app">n Clicked: {{ $store.state.count }} times, count is {{ evenOrOdd }}.n <button @click="increment">+</button>n <button @click="decrement">-</button>n <button @click="incrementIfOdd">Increment if odd</button>n <button @click="incrementAsync">Increment async</button>n </div>n</template>n

在寫template的時候,我們就是將傳統的html標籤和vue特定的一些語法聯繫在一起。在這裡,我們會關注數據綁定,控制語句和事件綁定。

1.1 數據綁定(ViewModel)

{{}}n

數據綁定最常見的形式就是使用 「Mustache」 語法(雙大括弧)的文本插值

{{}}裡面使用的是vue的表達式,和angular一樣,和react的jsx語法中的{}類似. 一般來說支持:

1. 簡單的單個js表達式

同react的jsx語法{}類似,如條件判斷不能用if-else,而要使用條件表達式?:。

2. {{ express || filter }}

filter的概念源自angular,就是接受前面表達式的值,處理,輸出新的格式化的值。具體可以參考後面的文章。

v-bind:xxn

在html代碼中空白的地方可以用{{}}。而在某個標籤內部,我們需要用v-bind:或者縮寫:來進行數據綁定。

讓我們來修改count實例,加入v-bind指令。我們給其中一個button綁定一個disable的欄位。

指令也是來自於angular的概念,具體可以參考後面的文章。

<template>n <div id="app">n Clicked: {{ $store.state.count }} times, count is {{ evenOrOdd }}.n <button @click="increment">+</button>n <button @click="decrement">-</button>n <button @click="incrementIfOdd" :disabled="$store.state.count%2 === 0">Increment if odd</button>n <button @click="incrementAsync">Increment async</button>n </div>n</template>n

這樣,名為「Increment if odd」的按鈕只有在count為奇數的時候才能點擊。其中的:等價於v-bind:

<button @click="incrementIfOdd" :disabled="$store.state.count%2 === 0">Increment if odd</button>nn等價於n<button @click="incrementIfOdd" v-bind:disabled="$store.state.count%2 === 0">Increment if odd</button>n

這裡,我們需要注意v-bind和不使用v-bind的屬性的本質區別就是:不使用v-bind,那麼這個屬性就是等待接受和被賦值一個字元串。而使用v-bind,字元串也變成了表達式。最明顯的就是true和false。

如果我們不要disable一個按鈕,同時我們使用了"false",那麼我們必須使用v-bind了的disabled的屬性,即下面的按鈕仍然被disabled。

<button @click="incrementIfOdd" disabled="false">Increment if odd</button>n

通過使用v-bind就可以不disable這個按鈕了,如下:

<button @click="incrementIfOdd" :disabled="false">Increment if odd</button>n

1.2 控制語句if和for

不管在哪個語言中,控制語句都起了非常重要的作用,if、if/else、for、while和switch等等,在我們學習編程語言的時候,都是在最開始的階段教的。在template中使用v-if指令可以用來掛在或者不掛在某個頁面元素(區別於v-show的顯示或者不顯示,兩者用法可以說一模一樣)。而用v-for指令可以循環掛在一系列類似的頁面元素。

在react中,我們可以在render函數的return之前定義一個元素(賦值或者null/undefined)來使用if控制語句,或者使用一個數組對象來實現for控制語句。

或者我們可以在return中的jsx語法中,使用條件表達式或者||和&&來實現if控制語句,或者使用.map函數來實現for控制語句

v-if實例

<template>n <div id="app">n Clicked: {{ $store.state.count }} times, count is {{ evenOrOdd }}.n <button @click="increment">+</button>n <button @click="decrement">-</button>n <button @click="incrementIfOdd" v-if="$store.state.count%2 === 0">Increment if odd</button>n <button @click="incrementAsync">Increment async</button>n </div>n</template>n

當count是奇數的時候,不顯示「」Increment if odd"的按鈕。

之前在看react的文檔的時候,看到過一個說法,就是不要頻繁使用if來掛載和卸載某個節點,可以使用設置對應節點的style來顯示和隱藏這個節點。這樣可以提高性能。

由於vue吸收了react虛擬dom的一套東西,因此這個建議在vue中也是有點用處的。

v-for實例

<template>n <div id="app">n Clicked: {{ $store.state.count }} times, count is {{ evenOrOdd }}.n <button v-for="(item, index) in [+, -, Increment if odd, Increment async]" :key="index">{{item}}</button>n </div>n</template>n

v-for的形式就是(item,index) in array,()中的兩個參數,第一個是數組中的某項,第二個參數就是該項在數組中的索引。

用過的另一個基於vue的開源項目,如果在上面的形式中,如果不使用key屬性,那麼會有警告。這一點和react一樣。對於element diff,指定key欄位可以提高diff演算法的效率(vue吸收了react的虛擬dom,那麼應該也有虛擬dom的diff演算法)。參考React 源碼剖析系列 - 不可思議的 react diff在那個項目中,和上面的形式對應的,如果沒有key屬性不會有警告的方式是「外包一層template標籤」。

<template>n <div id="app">n Clicked: {{ $store.state.count }} times, count is {{ evenOrOdd }}.n <template>n <button v-for="(item, index) in [+, -, Increment if odd, Increment async]">{{item}}</button>n <template>n </div>n</template>n

1.3 事件綁定

將事件綁定到標籤中,需要使用v-on指令或者縮寫的@,如@click和@input。

<button v-on:click="increment">+</button>nn等價於n<button @click="increment">+</button>n

vue的事件綁定同時支持函數名和執行函數的方式(一個內聯語句)。但在react中如果要只支持函數名的形式或者用bind或者箭頭函數的形式。

在vue中支持執行函數的方式:

<button v-on:click="increment(1)">+</button>n

在react中則不行:

<button onclick="increment(1)">+</button>n

上面的代碼會報錯,如果改正,需要在包一層,如下:

<button onclick="()=>increment(1)">+</button>n

事件綁定中的一些便利

vue提供了事件修飾符的小東西,可以簡化某些代碼。

如在提交表單的時候,由於現在都是ajax非同步請求的模式,表單提交的默認刷新頁面的操作變得多餘,而且違背了單頁應用的要求。如果在react中,我們需要在傳入的函數中對event對象進行event.preventDefault()的操作。如:

<button onclick="(e)=>increment(e, 1)">+</button>nnincrement = (e, num) {n e.preventDefault()n fetchXXX()n}n

在用vue寫代碼後,我們就可以省去的在函數內的e.preventDefault(),只需要在標籤中給@click加一個事件修飾符。如:

<button :click="increment(1)">+</button>nn在vue單文件組件的js代碼中的methods欄位下,我們可以直接請求數據了nincrement(num){n fetchXXX()n}n

推薦閱讀:

React 從青銅到王者系列教程之倔強青銅篇
【譯】React如何抓取數據
store的組織是扁平化好,還是分層級樹狀的好?大型的項目store該怎麼組織?
2016-我的前端之路:工具化與工程化
Flux todoMVC 為什麼要費那麼多力氣實現一個功能!!!!,這樣寫的好處是神馬?

TAG:Vuejs | MVVM | React |