vue初探
https://www.zhihu.com/question/38213423 餓了么vue組件
很多同學一定都聽過MVVM、組件、數據綁定之類的專業術語,而vue框架正是這樣的一種框架。vue的作用是:通過盡可能簡單的 API 實現響應的數據綁定和組合的視圖組件。
掘金就是完全使用vue+webpack開發的一個單頁面應用, 然后就可以發現該網站在不同的模塊之間跳轉是沒有白色的進度條的,尤其是 https://juejin.im/zhuanlan/all 這個頁面就是一個單頁面應用,在不同的模塊切換的時候,不變的組件是固定不動的,只會加載變動的組件,並且在加載時會使用淺灰色的矩形框填充,這是很多公司目前的做法,以提高用戶體驗, 且並不是一個頁面,而是整個掘金網站都是這樣的,在切換時只有部分頁面的改動,用戶體驗非常好。
推薦文章: https://www.qcloud.com/community/article/348215?fromSource=gwzcw.117379.117379.117379
第一部分:vue介紹與使用
話不多說,我們先來看一看最簡單的vue是怎么使用的。實際上,我們只需要引入一個js文件即可(當然,這只是一種相對簡單的方法,還有其他的方法),這個js文件即對vue的封裝。下面的例子可以輸出hello world。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> </head> <body> <div id="example"> {{message}} </div> <script> var example=new Vue({ el:'#example', data:{ message: "hello word" } }); </script> </body> </html>
其中,我們可以看到{{message}}這實際上類似於模版字符串,其中的message為模版,我們在js文件中可以給其設置值。注意:這里{{}}是兩個大括號,並且這里既然看作了一個模版,終究會被字符串所代替,所以沒有加分號,它不是語句。比如,我們還可以寫成:
<div id="example"> 哈哈, {{message}} 是模版字符串 </div>
即{{message}}可以穿插在任何地方,而不需要
另外,我們可以看到var example = new Vue();這個語句實際上是創建了一個Vue的實例對象,顯然這個Vue構造函數是已經封裝好的,我們直接使用即可。注意:正因為Vue是構造函數,所以Vue中的V要大寫!
且Vue中可以接收一個JSON字符串,所以我們在圓括號里是一個{}。2017年5月2日補充: Vue中接受了一個對象,而不是JSON字符串。 而el是element的縮寫,我們把el的值寫成# . 等形式來獲取dom元素,這一點和jQuery非常像,而data又是一個JSON字符串,2017年5月2日補充: data是一個對象。我們這時可以給message賦任意想要的值,注意:這里的message還可以寫成其他任意的形式如mes等。而< div id="example" >也可以寫成 <div class="example">或<div>,在js中只需要使用el:".example"和"div"分別來引用即可。
這樣,一個最簡答的vue例子就做出來了。並且這還是響應式的,也就是vue中的雙向數據綁定,為什么這樣說呢?因為vue是一款MVVM框架,M表示Module是數據的意思(屬於js),V表示View是視圖的意思(屬於html)。
第二部分:vue中的指令( v-bind、v-if、v-for、v-on)
我們知道我們可以通過在div內部顯示文本處添加{{message}}再通過js來添加模版,但是如果我們希望這個模版作為一個屬性值存在於一個div的title屬性中,我們可以通過<div title="message">的方式嗎? 答案是否定的,大家可以自行嘗試。這時,我們就需要使用vue中的v-bind了。舉例如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> </head> <body> <div v-bind:title="message" > 使用鼠標划過我哦 </div> <script> var example=new Vue({ el:'div', data:{ message: "我是通過指令被綁定的" } }); </script> </body> </html>
這個v-bind即稱為指令,它帶有前綴 v- ,dfjfafdf
顯然,這表示它是由Vue.js提供的特殊的屬性。意思是:將元素節點的title屬性和Vue實例的message屬性綁定到一起。於是,我們可以通過修改message來修改title屬性的值。
下面的這個例子可能更加合適!
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> </head> <body> <a class="test" href="#" v-bind:title="message">Vue.js</a> <script> var myVue = new Vue({ el: ".test", data: { message: "鼠標懸停於:" + new Date() } }); </script> </body> </html>
即刷新頁面后,鼠標懸停上去,就可以發現時間改變了。
當然,vue中的指令絕不僅限於此,v-if就是一個判斷指令,用於控制顯示可隱藏之間的切換。舉例如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> </head> <body> <div v-if="seen"> 哈哈,我會根據v-if的判斷來顯示或者隱藏。 </div> <script> var example=new Vue({ el:'div', data:{ seen:true } }); </script> </body> </html>
這里,我們給div添加特殊屬性v-if,其值為seen。而在Vue中的data下的seen設置位true,這時我們就可以在瀏覽器中看到該div的內容。但是如果我們在控制台中輸入example.seen=false那么div的內容就會被隱藏。如下所示:

值得注意的是:這里最為重要的是判斷v-if的值的值是否為true,而v-if的值的名稱是無關緊要的,也就是說,我們可以寫成v-if="hah",在Vue中的data里,只要改成hah:true即可,效果相同。
還有一個常用的指令v-for,它可以綁定數據到數組來渲染一個列表。舉例如下所示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> </head> <body> <div> <p v-for="person in people"> {{person.name}} </p> </div> <script> var example=new Vue({ el:'div', data:{ people:[ {name:'zzw'}, {name:'htt'}, {name:'aini'} ] } }); </script> </body> </html>
最終效果如下所示:

而關於v-for指定的使用,有以下幾點需要注意:
- 添加v-for指令的元素節點一定不能是body的直接子元素,也就是說,該元素之外必須要有其他元素,這樣,這個元素才能在某一個元素內(有v-for屬性元素的父元素)全部列舉出來。
- 在Vue中el的值,一定是有v-for屬性的父元素,因為我們需要在這個父元素內全部列舉。
- 我們可以看到,之前的幾個例子包括這個例子,data的數據格式都是JSON字符串,而JSON中的people可以是數組,且既然用到了v-for列舉,那么一定是數組被列舉。
- 我們在控制台輸入example.people.push({name:'Jack'})之后我們就可以看到在原來的基礎上多顯示了一行Jack。
當然,如果我們希望用戶能和我們的應用互動,那么我們需要使用v-on添加一個監聽事件來調用我們在Vue實例中的方法。如下所示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> <style> .string{color:red;} </style> </head> <body> <div> <p>點擊按鈕,下面的文字將會反轉</p> <p class="string">{{message}}</p> <button v-on:click="reverseMessage">反轉</button> </div> <script> var example = new Vue({ el:'div', data:{ message:'i like coding' }, methods:{ reverseMessage:function(){ this.message=this.message.split("").reverse().join("") } } }) </script> </body> </html>
效果如下所示:

對於v-on指定我們需要注意以下幾點:
- 當有關Vue的使用只在一個元素時,el對應的就是這個元素;如果有關Vue的有多個元素,那么Vue實例中的el所對應的元素就是包含這多個元素的父元素。如本例所示。
- 這里,我們看到了method的使用,而之前只使用過el和data。
- split()方法可以將字符串分解為數組,如果是split("")則會把所有的字符都分成數組。
如下所示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> </head> <body> <div class="content"> <div class="wrap"> <button v-on:click="change">按鈕</button> <button v-on:click="ha">另一個</button> </div> </div> <script> var myVue = new Vue({ el: ".content", methods: { change: function () { alert("god"); }, ha: function () { alert('ha'); } } }); </script> </body> </html>
而如果我們希望將應用狀態和表單同時雙向數據綁定,這時我們就需要使用v-model指令了。舉例如下所示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> </head> <body> <div> <p>{{message}}</p> <input type="text" v-model="message"> </div> <script> var example = new Vue({ el:'div', data:{ message:'hello world' } }); </script> </body> </html>
效果如下所示:

當然,我們也可以使用如同title例子所將的v-bind指令,如<input type="text" v-bind:value="message">。
這就是著名的數據雙向綁定了!
第三部分:組件化
組件系統是Vue.js中的一個非常重要的概念,因為它提供了一種抽象,讓我們可以通過獨立可重復的小組件來構建大型應用,如果我們考慮到這點,幾乎任意類型的應用的界面都可以抽象成一個組件樹。
那么怎么構建一個組件呢?大體思路如下所示:
<div>
<ol>
<comp></comp>
<comp></comp>
<comp></comp>
</ol>
</div>
<script>
Vue.component('comp',{template:'<li>helloword</li>'});
</script>
但是我們可以發現一個問題,就是這樣得到的comp都是重復的,是沒有意義的,那么怎么讓這個組件可以變動呢?於是Vue給component方法提供了另一個參數props,舉例如下所示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> </head> <body> <div> <ol> <comp v-for="person in people" v-bind:item="person"></comp> </ol> </div> <script> Vue.component('comp',{props:['item'],template:'<li>{{item.name}}</li>'}); var example=new Vue({ el:'div', data:{ people:[ {name:'zzw'}, {name:'htt'}, {name:'love'}, ] } }); </script> </body> </html>
這里利用了組件component,但是為了不重復,這里就使用了v-for指令,並且將person綁定到每個comp的item屬性上,這樣組件就是變化的了。另外還需要注意的是component方法的第二個參數props的值是一個數組,因為這樣組件中就可以包括不只一種的變動的量,這樣的功能才更強大。
注:這里記錄的vue學習筆記主要參自中文官方文檔。
第四部分: v-if 和 v-for
v-if是控制組件是否顯示的指令,v-for適用於循環的,當v-for和v-if用在同一個組件上時,v-for的優先級要高於v-if ,看下面的例子:
<li v-for="todo in todos" v-if="!todo.isComplete"> {{ todo }} </li>
這意味着v-if將應用於每一個v-for循環之中,當你希望渲染僅有的一些節點的時候,這會非常有用。
但是,如果你是為了跳過循環,那么就可以在v-for所在組件之外再包裹一層,如下所示:
<ul v-if="shouldRenderTodos"> <li v-for="todo in todos"> {{ todo }} </li> </ul>
這樣, 如果不滿足 v-if 的條件,就不會有任何的循環啦~
,
