個人Vue學習筆記css
MVVM是Model-View-ViewModel的簡寫,即:模型-視圖-視圖模型.
模型是指後端傳遞的數據
視圖是指咱們看到的頁面
視圖模型則是MVVM思想的核心部分,它連接了View和Model並做爲它們之間通訊的橋樑,它有兩個方向:一是將Model轉化爲View,即後端傳遞的數據轉化成看到的頁面,二則是將View轉化爲Model,也就是將用戶操做在頁面上的內容轉化爲後端的數據,這兩個功能是經過數據綁定以及DOM事件監聽來實現的,咱們稱之爲數據的雙向綁定。如圖所示:
html
vue 建立實例的方法以下:vue
<div id="app">
{{myData}}
</div>
<script>
var vueApp = new Vue({
el:'#app',
data:{
myData:'Hello World'
myData2:'Fuck World'
}
});
</script>
複製代碼
代碼中 el 和 data 都是vue實例的屬性,el 用於指定頁面當中已存在的用來掛載Vue實例的DOM元素,data則是Vue須要雙向綁定的數據。後端
當掛載後,咱們可使用 vue實例.$vue實例的屬性
這樣的語法來獲取vue實例的屬性,例如: vueApp.$el
,訪問data中的屬性則不一樣,咱們能夠直接使用vue實例.data的屬性名
這樣的語法來訪問,例如:vueApp.myData
數組
vue生命週期鉤子是在Vue對象生命週期的某一個階段執行的已定義的方法。從初始化vue實例對象,到它被銷燬,對象會遵循不一樣的生命階段,具體內容我截了一張很著名的生命週期鉤子圖:
瀏覽器
vue生命週期有不少階段,可是咱們最經常使用到的是這三個階段:緩存
舉例說明:bash
var vueApp = new Vue({
el:'#app',
data:{
myData:'Hello World'
},
created:function () {
alert('vue實例建立完畢了,可是尚未掛載到DOM元素上');
},
mounted:function () {
alert('vue實例已經掛載到DOM上了');
}
});
複製代碼
對於上述示例頁面來講,打開瀏覽器,首先會彈出"vue實例建立完畢了,可是尚未掛載到DOM元素上"這樣的提示信息,對於created 這個階段來講,實際上已經完成了vue實例的建立,可是並無掛載至DOM元素上,而後會彈出「vue實例已經掛載到DOM上了」的提示框,mounted階段是vue建立的實例掛載到DOM後進行調用的,咱們的第一個業務邏輯也一般會在這裏開始,對於beforeDestory 階段,經過字眼意思也能夠知道 這是vue實例銷燬前的階段,經過會在這個階段進行解綁一些監聽事件。app
對於本示例來說,咱們會在頁面上看到Hello World 的字樣,在html中,咱們書寫了這樣的語法:框架
<div id="app">
{{myData}}
</div>
複製代碼
這種語法就是Vue的文本插值語法,它支持單個表達式,注意只是單個表達式:
{{1<0 ? myData:myData2}}
這是三元運算符表達式,由於它屬於單個表達式
因此這是合法的,咱們會在頁面上看到Fuck World
{{var a = 6}}
注意:這是非法的
var a = 6 是一個聲明表達式 + 一個賦值表達式
咱們提到過 Vue 的文本插值語法只支持單個表達式
因此 這句話會報錯
複製代碼
vue.js 支持在{{}}插值的尾部添加一小管道符" | "對數據進行過濾,常常用於格式化文本,好比字母所有大寫、貨幣千位使用逗號分隔等,同時也支持過濾器串聯寫法,傳參等等。咱們來看一個示例:
頁面實時顯示當前時間:
<div id="app">
{{currentDate | format}}
</div>
<script>
function formatTime(value) {
return value <10 ? '0'+value : value;
}
var vueApp = new Vue({
el:'#app',
data:{
currentDate: new Date()
},
filters:{
format:function (currentDate) {
var date = new Date(currentDate);
var year = date.getFullYear(); // 獲取當前年
var month = formatTime(date.getMonth()+1); // 獲取當前月(須要+1)
var days = formatTime(date.getDate()); // 獲取當前天
var hours = formatTime(date.getHours()); // 獲取當前小時
var minutes = formatTime(date.getMinutes()); // 獲取當前分鐘
var seconds = formatTime(date.getSeconds()); // 獲取當前秒
return '當前時間爲:'+year+'年'+month+'月'+days+'日'+hours+'時'+minutes+'分'+seconds+'秒'
}
},
mounted:function () {
this.timer = setInterval(()=>{
this.currentDate = new Date();
},1000)
},
beforeDestroy:function () {
window.clearInterval(this.timer);
}
});
</script>
複製代碼
咱們還能夠對過濾器進行傳參,咱們將代碼作一個小小的改動:
<div id="app">
{{currentDate | format('當前時間爲',':')}}
</div>
<script>
function formatTime(value) {
return value <10 ? '0'+value : value;
}
var vueApp = new Vue({
el:'#app',
data:{
currentDate: new Date()
},
filters:{
format:function (currentDate,arg1,arg2) {
var date = new Date(currentDate);
var year = date.getFullYear(); // 獲取當前年
var month = formatTime(date.getMonth()+1); // 獲取當前月(須要+1)
var days = formatTime(date.getDate()); // 獲取當前天
var hours = formatTime(date.getHours()); // 獲取當前小時
var minutes = formatTime(date.getMinutes()); // 獲取當前分鐘
var seconds = formatTime(date.getSeconds()); // 獲取當前秒
return arg1+arg2+year+'年'+month+'月'+days+'日'+hours+'時'+minutes+'分'+seconds+'秒'
}
},
mounted:function () {
this.timer = setInterval(()=>{
this.currentDate = new Date();
},1000)
},
beforeDestroy:function () {
window.clearInterval(this.timer);
}
});
</script>
複製代碼
咱們在過濾器中加入了參數,獲得了和以前同樣的結果。這裏面須要注意的是:過濾器對應的函數中第一個傳入的值是 「 | 」 前的data中的屬性值,在本例中即:currentDate ,而並不是是參數,傳入的參數是在函數的第二個傳遞值及之後的值。同時過濾器也可使用"串聯寫法" ,如:{{currentDate | filter1 | filter2 | filter3 }}
,過濾器的方法會依次執行,而且它們都被定義在 vue的屬性 filters 當中。
支持指令操做是vue框架的優勢之一,它是vue模板中最經常使用的一項功能,省去了複雜的DOM API,而且及其方便記憶和理解。接下來咱們先簡單瞭解一些指令操做:
v-text
v-text 的功能是解析文本 它的具體做用和文本插值{{}}是一毛同樣的
v-html
將內容解析成html
v-bind
動態更新HTML上的元素,例如id,class等等
v-on
用來綁定事件監聽
接下來咱們依舊經過示例,來簡單認識這幾個指令事件。
<style>
.active{
background: red;
height: 1em;
}
</style>
---------------------------------------------------------------
<div id="app">
v-text: <br>
{{apple}} <br>
<!--v-text 的做用和文本插值 是同樣的-->
<span v-text="apple"></span>
v-html: <br>
<span v-html="banana"></span> <br>
v-bind: <br>
<div v-bind:class="className"></div>
v-bind的簡寫格式: <br>
<div :class="className"></div>
v-on: <br>
<button v-on:click="plusOne">{{originalNum}}</button>
<br>
v-on的簡寫格式: <br>
<button @click="plusOne">{{originalNum}}</button>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
apple:'蘋果',
banana:'<span style="color: yellow;">香蕉</span>',
className:'active',
originalNum:0
},
methods:{
plusOne:function () {
this.originalNum = this.originalNum + 1;
}
}
});
</script>
複製代碼
部分html內容如上,對於 v-bind 和 v-on 兩個指令 都有響應的簡寫格式,如示例中:
<div v-bind:class="className"></div>
能夠簡寫爲:
<div :class="className"></div>
<button v-on:click="plusOne">{{originalNum}}</button>
能夠簡寫爲:
<button @click="plusOne">{{originalNum}}</button>
複製代碼
先看一個示例:咱們要實現一個功能 反轉字符串,對於字符串 '123,456,789' 咱們要將字符串變爲: '321,654,987' ,示例程序以下:
<div id="app">
{{text.split(',').map((e)=>{return e.split('').reverse().join('')}).join(',')}}
</div>
<script>
var app = new Vue({
el:'#app',
data:{
text:'123,456,789'
}
});
</script>
複製代碼
咱們看到這個程序內心必定一句媽賣批,程序雖然沒有什麼問題,也符合文本插值的語法,可是看起來就是以爲很頭疼,而且這樣寫的代碼也很差進行維護。咱們能夠將內容作一個優化,建立一個函數並將函數放在methods屬性當中:
<div id="app">
<!--將'123,456,789' 這串字符串 變爲 '321,654,987'-->
使人頭痛的代碼: <br>
{{text.split(',').map((e)=>{return e.split('').reverse().join('')}).join(',')}} <br>
methods屬性內的方法: <br>
{{reverseMethod()}} <br>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
text:'123,456,789'
},
methods:{
reverseMethod:function () {
// ['123',456,'789']
return this.text.split(',').map((e)=>{
return e.split('').reverse().join('');
}).join(',');
}
}
});
</script>
複製代碼
除了將方法定義在methods中並調用,咱們還可使用計算屬性:
<div id="app">
<!--將'123,456,789' 這串字符串 變爲 '321,654,987'-->
使人頭痛的代碼: <br>
{{text.split(',').map((e)=>{return e.split('').reverse().join('')}).join(',')}} <br>
methods屬性內的方法: <br>
{{reverseMethod()}} <br>
計算屬性: <br>
{{reverseText}}
</div>
<script>
var app = new Vue({
el:'#app',
data:{
text:'123,456,789'
},
methods:{
reverseMethod:function () {
// ['123',456,'789']
return this.text.split(',').map((e)=>{
return e.split('').reverse().join('');
}).join(',');
}
},
computed:{
reverseText:function () {
return this.text.split(',').map((e)=>{
return e.split('').reverse().join('')
}).join(',');
}
}
});
</script>
複製代碼
咱們將方法定義在了 vue示例的computed 屬性當中,乍一看 和 methods並無什麼區別,實際上 計算屬性能夠實現的東西 在methods方法中 均可以實現 ,可是兩者也是有差異的。具體的差異,咱們在看完另外一個示例後,再來介紹:
本示例的功能是對購物車的價格總和進行計算,具體代碼以下:
<div id="app">
{{prices}}
</div>
<script>
var app2 = new Vue({
el:'#app2',
data:{
msg:'兩個購物車的價格總和爲:'
}
});
var app = new Vue({
el:'#app',
data:{
// 購物車1
package1:[
{
name:'iphone',
price:6999,
count:2
},
{
name:'ipad',
price:3299,
count:2
}
],
// 購物車 2
package2:[
{
name:'XiaoMi',
price:999,
count:6
},
{
name:'ipod',
price:1099,
count:2
}
]
},
computed:{
prices:{
get:function () {
var prices = 0;
// 第一個購物車的價格總和
for(var i = 0;i<this.package1.length;i++){
prices += this.package1[i].price * this.package1[i].count;
}
// 第一個購物車與第二個購物車的價格總和
for(var j = 0; j<this.package2.length;j++){
prices += this.package2[j].price * this.package2[j].count;
}
return app2.msg+prices;
},
set:function (options) {
if(options.package === 'package1'){
for(var i = 0;i<this.package1.length;i++){
if(this.package1[i].name === options.name){
this.package1[i].price = options.price;
this.package1[i].count = options.count;
break;
}
}
}else if(options.package === 'package2'){
for(var i = 0;i<this.package2.length;i++){
if(this.package2[i].name === options.name){
this.package2[i].price = options.price;
this.package2[i].count = options.count;
break;
}
}
}
}
}
}
});
</script>
複製代碼
每個計算屬性都有一個getter和 setter方法,當咱們僅僅是調用了計算屬性的方法名時,實際上調用的是 該屬性的get 方法,當有必要設置一些參數時,咱們也能夠提供一個 set方法手動修改計算屬性。另外在本示例中,咱們能夠看到 計算屬性 prices不只依賴了當前vue對象 並且也依賴了其餘的實例,儘管 app2 並無掛載到DOM上,可是執行的結果代表 計算屬性能夠依賴於其餘的實例。 代碼執行的結果以下:
咱們首先來看一個示例:
<div id="app">
{{text}} <br>
{{getNow()}} <br>
{{now}} <br>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
text:666
},
methods:{
getNow:function () {
return Date.now();
}
},
computed:{
now:{
get:function () {
return Date.now(); // 獲取 1970年 至如今的時間戳
}
}
}
});
</script>
複製代碼
咱們在 methods 方法以及 計算屬性中都定義了獲取 1970年到如今爲止的時間戳的函數 ,代碼運行的結果以下:
v-bind 的做用只用一句話就能夠描述,那就是綁定活的屬性,咱們經過一個簡單的示例來回顧一下:
<div id="app">
<a v-bind:href="url">連接</a>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
url:'http://www.baidu.com'
}
});
</script>
複製代碼
頁面點擊鏈接後則會跳轉到baidu。
見示例:
<style>
.red{
background: red;
}
.blue{
background: blue;
}
</style>
--------------------------------------------------
<div id="app">
v-bind綁定對象: 對象的key是類名,對象的value是布爾值<br>
<button v-bind:class="{red:isRed,blue:isBlue}" v-on:click="transColor">clickMe</button>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
isRed:true,
isBlue:false,
},
methods:{
transColor:function () {
this.isRed = !this.isRed;
this.isBlue = !this.isBlue;
}
}
});
</script>
複製代碼
本示例實現的功能是一個按下去能轉換顏色的按鈕,同時v-bind:class使用的是對象語法,對象的key爲 類名 對象的value則是布爾值,若是值爲true則綁定這個類名,若是值爲false則和此類名無關聯。
見示例:
<style>
.red{
width: 100px;
height: 100px;
background: red;
}
</style>
-----------------------------------------------
<div id="app">
v-bind綁定計算屬性: 計算屬性返回的也是對象 key爲類名 ; value爲 布爾值 <br>
<div v-bind:class="computedClass"></div>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
isRed:true,
},
computed:{
computedClass:function () {
return {
red:'isRed'
}
}
}
});
</script>
複製代碼
示例中 v-bind:class綁定了計算屬性,可是即使爲計算屬性,返回的結果也是對象,對象中key爲類名,value爲布爾值,同上 當value值爲真時,元素攜帶這個類,當value值爲false時,元素則不攜帶這個類
見示例:
<style>
.first{
font-size: 32px;
color: red;
}
.second{
background: #000;
}
</style>
---------------------------------------
<div id="app">
綁定class數組語法:數組中的成員爲data中的屬性,這些屬性直接對應類名 <br>
<div v-bind:class="[classOne,classTwo]">VUE is cool!</div>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
classOne:'first',
classTwo:'second'
}
});
</script>
複製代碼
v-bind綁定class數組的語法相比於前面而言更加簡單,數組中的成員爲data中的屬性,這些屬性直接對應類名,經過示例應該不難看懂~
除了綁定class較爲經常使用,v-bind也能夠綁定內聯樣式
<div id="app">
綁定內聯樣式:對象語法,key 表明style的屬性,value表明屬性對應的值 br>
<div v-bind:style="{'color':color,'fontSize':fontSize}">VUE is cool!</div>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
color:'red',
fontSize:'32px'
}
});
</script>
複製代碼
除了這種對象語法以外,綁定內聯樣式也支持"數組"語法,可是聽說這種語法比較蠢,由於誰也不會把樣式分開寫,因此我就不在這裏列出來了。須要注意的是 css屬性名稱 使用駝峯命名,或者是短橫線分隔命名,可是這裏面仍是推薦駝峯式寫法~~~~