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
如果我們不要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 為什麼要費那麼多力氣實現一個功能!!!!,這樣寫的好處是神馬?