摘要:本文是小羊根據(jù)文檔進(jìn)行解讀的第一篇文章,主要內(nèi)容涵蓋的基礎(chǔ)部分的知識(shí)的,文章順序基本按照官方文檔的順序,每個(gè)知識(shí)點(diǎn)現(xiàn)附上代碼,然后根據(jù)代碼給予個(gè)人的一些理解,最后還放上在線編輯的代碼以供練習(xí)和測(cè)試之用在最后,我參考上的一篇技博,對(duì)進(jìn)行初入的
本文是小羊根據(jù)Vue.js文檔進(jìn)行解讀的第一篇文章,主要內(nèi)容涵蓋Vue.js的基礎(chǔ)部分的知識(shí)的,文章順序基本按照官方文檔的順序,每個(gè)知識(shí)點(diǎn)現(xiàn)附上代碼,然后根據(jù)代碼給予個(gè)人的一些理解,最后還放上在線編輯的代碼以供練習(xí)和測(cè)試之用;
在最后,我參考SegmentFault上的一篇技博,對(duì)Vue進(jìn)行初入的實(shí)戰(zhàn),目的是將新鮮學(xué)到的知識(shí)立即派上用場(chǎng);
如果你還是前端的小白,相信這篇文章可能會(huì)對(duì)產(chǎn)生一些幫助和引起思想的碰撞,因?yàn)榇蠹业膶W(xué)習(xí)歷程是相似的,遇到的困惑也有一定的共通性,如果文章出現(xiàn)謬誤之處,歡迎各位童鞋及時(shí)指正;
1. Vue.js是什么Vue.js(讀音 /vju?/, 類似于?view) 是一套構(gòu)建用戶界面的?漸進(jìn)式框架。與其他重量級(jí)框架不同的是Vue 的核心庫(kù)只關(guān)注視圖層。
Vue.js 的目標(biāo)是通過(guò)盡可能簡(jiǎn)單的 API 實(shí)現(xiàn)響應(yīng)的數(shù)據(jù)綁定和組合的視圖組件。
Vue.js是一種MVVM框架,其中html是view層,js是model層,通過(guò)vue.js(使用v-model這個(gè)指令)完成中間的底層邏輯,實(shí)現(xiàn)綁定的效果。改變其中的任何一層,另外一層都會(huì)改變;
2.Vue的基本語(yǔ)法通過(guò)構(gòu)造函數(shù)Vue創(chuàng)建一個(gè)Vue的根實(shí)例
--- var vm = new Vue({ //options el:"#el", data:{}, methods:{} }) --- //擴(kuò)展Vue構(gòu)造器 var MyComponent = Vue.extend({ //擴(kuò)展選項(xiàng) }) var vm = new MyComponent({})
解讀:
使用Vue構(gòu)造函數(shù)創(chuàng)建一個(gè)Vue實(shí)例,然后通過(guò)Vue實(shí)例的el接口實(shí)現(xiàn)和HTML元素的掛載;
構(gòu)造函數(shù)Vue需要傳入一個(gè)選項(xiàng)對(duì)象,可包含掛載元素、數(shù)據(jù)、方法和生命周期鉤子等;
構(gòu)造函數(shù)Vue可以通過(guò)extend方法實(shí)現(xiàn)擴(kuò)展,從而可以用預(yù)定義的選項(xiàng)創(chuàng)建可復(fù)用的組件構(gòu)造函數(shù),但是構(gòu)建組件的常用方法是使用Vue.component()接口去實(shí)現(xiàn);
Vue實(shí)例將代理data對(duì)象的所有屬性,也就是說(shuō)部署在data對(duì)象上的所有屬性和方法都將直接成為Vue實(shí)例的屬性和方法
{{message}}--- var app = new Vue({ el:"#app", data:{ message:"hello world!", sayHello:function(){ console.log(1) } } }) --- //如果想要獲取到app這一實(shí)例中選項(xiàng)的對(duì)象,Vue提供$進(jìn)行獲取 app.$el === document.getElementById("app")//true app.$data.message//hello world
【demo】
【TIP】
Vue實(shí)例所代理data對(duì)象上的屬性只有在實(shí)例創(chuàng)建的同時(shí)進(jìn)行初始化才具有響應(yīng)式更新,若在實(shí)例創(chuàng)建之后添加是不會(huì)觸發(fā)視圖更新的;
綁定文本和HTML
{{msg}}--- var app = new Vue({ el: "#app", data:{ msg: "hello world!", hi:"hi
" } })
解讀:
HTML部分實(shí)現(xiàn)數(shù)據(jù)的動(dòng)態(tài)綁定,這個(gè)數(shù)據(jù)是vue實(shí)例的屬性值;
JS部分的語(yǔ)法可以從jQuery角度去理解,相當(dāng)于創(chuàng)建一個(gè)Vue實(shí)例,這個(gè)實(shí)例指向#app,并在Vue提供的固定接口data上定義Vue實(shí)例的屬性;
使用{{message}}的mustache語(yǔ)法只能將數(shù)據(jù)解釋為純文本,為了輸出HTML,可以使用v-html指令;
綁定數(shù)據(jù)在元素的屬性
{{message}}--- var app = new Vue({ el: "#app", data:{ message: "hello world!", red: "color:red" } })
解讀:
定義在Vue實(shí)例的data接口上的數(shù)據(jù)的綁定靈活的,可以綁定在DOM節(jié)點(diǎn)內(nèi)部,也可以綁在屬性上;
綁定數(shù)據(jù)到節(jié)點(diǎn)屬性上時(shí),需要使用v-bind指令,這個(gè)元素節(jié)點(diǎn)的?title屬性和 Vue 實(shí)例的?message屬性綁定到一起,從而建立數(shù)據(jù)與該屬性值的綁定,也可以使用v-bind:href="url"的縮寫方式:href="url";
v-once指令能夠讓你執(zhí)行一次性的插值,當(dāng)數(shù)據(jù)改變時(shí),插值處的內(nèi)容不會(huì)更新;
【demo】
使用JS表達(dá)式處理數(shù)據(jù)
--- var app = new Vue({ el: "#app", data:{ num:10, message: "hello world!", seen:true } }){{num + 10 }}
{{message + "jirengu"}}
【demo】
使用過(guò)濾器來(lái)格式化數(shù)據(jù)
--- var app = new Vue({ el: "#app", data:{ message: "hello world!", seen:true, }, filters:{ capitalize:function(value){ if(!value) return "" value = value.toString() return value.charAt(0).toUpperCase() + value.slice(1) } } }){{message | capitalize}}
【demo】
條件指令控制DOM元素的顯示操作
--- var app = new Vue({ el: "#app", data:{ message: "hello world!", seen:true } }){{message}}
解讀:
v-if指令可以綁定一個(gè)屬性值為布爾型的屬性,當(dāng)值為真時(shí),元素將顯示,反之則消失;
循環(huán)指令實(shí)現(xiàn)數(shù)據(jù)的遍歷
--- var app = new Vue({ el: "#app", data:{ items:[ {text:"Vue"}, {text:"React"}, {text:"Angular"} ] } })
- {{ item.text }}
解讀:
v-for可以綁定數(shù)組型數(shù)據(jù)進(jìn)行綁定,并使用item in items形式,從而數(shù)據(jù)的遍歷操作;
【demo】
事件綁定指令可以實(shí)現(xiàn)事件監(jiān)聽
--- var app = new Vue({ el: "#app", data:{ message: "hello world!" }, methods:{ reverseMessage:function(){ this.message = this.message.split("").reverse().join("") } } }){{message}}
解讀:
v-on指令用于監(jiān)聽事件操作,click="reverseMessage"定義點(diǎn)擊事件后執(zhí)行的回調(diào)函數(shù);
v-on指令也可以采用縮寫方式:@click="method"
在Vue實(shí)例中,提供methods接口用于統(tǒng)一定義函數(shù);
【demo】
小結(jié)
本章涉及Vue的基礎(chǔ)的數(shù)據(jù)綁定操作,內(nèi)容包括:
{{message}}實(shí)現(xiàn)文本數(shù)據(jù)的綁定,并且文本數(shù)據(jù)可以使用JS表達(dá)式和過(guò)濾器進(jìn)行進(jìn)一步處理;
- v-html="hi"實(shí)現(xiàn)HTML數(shù)據(jù)的綁定;
v-bind:href="url"實(shí)現(xiàn)屬性數(shù)據(jù)的綁定;
v-if="seen"和v-for="item in items"指令實(shí)現(xiàn)流程控制;
v-on:click="method"指令實(shí)現(xiàn)事件監(jiān)聽
使用計(jì)算屬性完成一些數(shù)據(jù)計(jì)算操作
--- var app = new Vue({ el: "#app", data:{ message: "hello world!", }, computed:{ ReversedMessage:function(){ return this.message.split("").reverse().join("") } } })Original message : {{message}}
Reversed message : {{ReversedMessage}}
解讀:
Vue實(shí)例提供computed對(duì)象,我們可以在對(duì)象內(nèi)部定義需要進(jìn)行計(jì)算的屬性ReverseMessage,而提供的函數(shù)將作為屬性的getter,即獲取器;
上述的代碼使得app.ReverseMessage依賴于app.message;
與先前直接在{{message.split("").reverse().join("") }}使用表達(dá)式相比,它讓模板過(guò)重并且難以維護(hù)代碼;
計(jì)算屬性 VS Methods
--- var app = new Vue({ el: "#app", data:{ message: "hello world!", }, computed:{ ReversedMessage:function(){ return this.message.split("").reverse().join("") } }, methods:{ reversedMessage:function(){ return this.message.split("").reverse().join("") } } })Original message : {{message}}
Reversed message : {{ReversedMessage}}
Reversed message:{{reversedMessage()}}
解讀:
通過(guò)Vue實(shí)例的methods接口,我們?cè)谀0逯姓{(diào)用reversedMessage函數(shù)同樣實(shí)現(xiàn)需求;
methods與computed方法的區(qū)別在于:computed的數(shù)據(jù)依賴于app.message,只要message未變,則訪問(wèn)ReverseMessage計(jì)算屬性將立即返回之前的計(jì)算結(jié)果,而methods則每次重新渲染時(shí)總是執(zhí)行函數(shù);
如果有緩存需要,請(qǐng)使用computed方法,否則使用methods替代;
計(jì)算屬性的setter
Vue實(shí)例的computed對(duì)象默認(rèn)只有g(shù)etter,如果你要設(shè)置數(shù)據(jù),可以提供一個(gè)setter,即設(shè)置器;
--- var app = new Vue({ el: "#app", data:{ message: "hello world!", name:"Teren" }, computed:{ fullName:{ get:function(){ return this.name }, set:function(value){ this.name = value } } } })Hi,I"m{{fullName}}
綁定Class
--- //css .static{ width: 200px; height: 100px; background: #ccc; } .active{ color:red; } .error{ font-weight: 800; } --- var app = new Vue({ el: "#app", data:{ isActive:true, hasError:true, classObj:{ static:true, active:true, error:true, }, staticClass:"static", activeClass:"active", errorClass:"error", }, computed:{ style:function(){ return { active: this.isActive, static:true, error:this.hasError } } }, methods:{ changeColor:function(){ this.isActive = !this.isActive } } })Hello world!
こんにちは
你好
Olá
解讀:
通過(guò)v-bind:class="{}"或v-bind:class=[]方式為模板綁定class
通過(guò)v-bind:class="{active:isActive,error:hasError}"綁定class,首先要在css中設(shè)置.active和,error,然后在Vue實(shí)例的data對(duì)象中設(shè)置isActive和hasError的布爾值;也可以直接傳一個(gè)對(duì)象給class,即v-bind:class="classObj,再在data對(duì)象上直接賦值:
data:{ classObj:{ static:true, active:true, error:true, }
你也可以通過(guò)傳遞數(shù)組的方式為class賦值v-bind:class="[staticClass,activeClass,errorClass]",此時(shí)你要在data對(duì)象上為數(shù)組的元素的屬性賦值:
data:{ staticClass:"static", activeClass:"active", errorClass:"error", }
【TIP】無(wú)論是哪種方式,前提都是css中的class要先設(shè)定
【demo】
綁定style
--- var app = new Vue({ el: "#app", data:{ styleObj:{ fontWeight:800, color:"red" }, bgObj:{ width:"100px", height:"80px", background:"#ccc" } }, })Hello World!
你好
解讀:
綁定style到模板的方法有兩種,一是v-bind:style="styleObj",然后在data對(duì)象上定義styleObj;而是可以通過(guò)數(shù)組方式為style傳入多個(gè)樣式對(duì)象
【demo】
前面簡(jiǎn)單介紹了一下v-if、v-for和v-on指令,下面的部分將詳細(xì)介紹以上3個(gè)指令;
條件渲染
--- var app = new Vue({ el: "#app", data:{ ok:true, motto:true, }, })Hello World!
Hello Universal
Steve Jobs
motto:stay hungry ! stay foolish
Show Me
解讀:
通過(guò)v-if和v-else指令實(shí)現(xiàn)條件渲染,其中v-if="value"的valuey
要在data對(duì)象中賦布爾值,v-if支持語(yǔ)法
v-show="value"是另一種條件渲染的方法;
【TIP】 v-if和v-show的區(qū)別
v-if是真實(shí)的條件渲染,當(dāng)進(jìn)行條件切換時(shí),它會(huì)銷毀和重建條件塊的內(nèi)容,并且它支持語(yǔ)法;
v-show的條件切換時(shí)基于css的display屬性,所以不會(huì)銷毀和重建條件塊的內(nèi)容;
當(dāng)你頻繁需要切換條件時(shí),推薦使用v-show;否則使用v-if;
【demo】
列表渲染
- {{car.name}}
- {{index}}---{{food}}---{{delicious}}
- {{index}}.{{key}}.{{value}}
{{n}}{{n}}
解讀:
v-for指令能夠讓我們循環(huán)渲染列表型數(shù)據(jù),數(shù)據(jù)放在data對(duì)象中,類型可以如下:
data:{ //數(shù)字?jǐn)?shù)組 numbers:[1,2,3,4,5,6,7,8,9,10], counts:[1,2,3,4,5] //字符串?dāng)?shù)組 foods:[ "tomato", "potato", "ice cream" ], //對(duì)象數(shù)組 cars:[ {name:"Benz"}, {name:"BMW"} ], //對(duì)象 object :{ name:"Benz", age:"18" }, }
根據(jù)不同類型的數(shù)據(jù),v-for指令在模板中具體采用的語(yǔ)法如下:
//數(shù)據(jù)為數(shù)字?jǐn)?shù)組{{n}}--- //數(shù)據(jù)為字符數(shù)組
在?v-for塊中,我們擁有對(duì)父作用域?qū)傩缘耐耆L問(wèn)權(quán)限;
【demo】
簡(jiǎn)單的事件監(jiān)聽——直接在指令上處理數(shù)據(jù)
--- var app = new Vue({ el: "#app", data:{ counter: 0, } }){{counter}}
復(fù)雜的事件監(jiān)聽——在methods對(duì)象定義回調(diào)函數(shù)
--- var app = new Vue({ el: "#app", data:{ vue:"hello Vue.js" }, methods:{ greet:function(event){ console.log(this.vue) } } }){{vue}
事件修飾符——調(diào)用事件對(duì)象函數(shù)的快捷方式
1//等價(jià)于event.preventDefault()2//等價(jià)于event.stopPropagation()3//等價(jià)于事件回調(diào)函數(shù)采用捕獲階段監(jiān)聽事件4//等價(jià)于event.target
按鍵修飾符——按鍵事件的快捷方式
常見按鍵別名包括: - enter - tab - delete - esc - space - up - down - left - right
【demo】
文本控件
--- var app = new Vue({ el:"#app", data:{ message:"Hello World!" }, }){{message}}
解讀:
通過(guò)v-model指令可以實(shí)現(xiàn)數(shù)據(jù)的雙向綁定,即View層的數(shù)據(jù)變化可以直接改變Model層的數(shù)據(jù),而Model層的數(shù)據(jù)改變也可以直接反映在View層;
上述代碼v-model="message"使得input的value屬性和message屬性綁定,在輸入框輸入值,即改變value同時(shí)也改變message;
單選控件
{{picked}}--- var app = new Vue({ el:"#app", data:{ message:"Hello World!", picked:"man" }, })
解讀:
v-model指令綁定data對(duì)象的picked屬性,該屬性默認(rèn)指向type="radio"的input的value;
復(fù)選框
Checked Name:{{checked}}--- var app = new Vue({ el:"#app", data:{ message:"Hello World!", picked:"man", selected:"A", checked:[], }, })
【demo】
組件可以擴(kuò)展 HTML 元素,封裝可重用的代碼。在較高層面上,組件是自定義元素;
通過(guò)Vue.component()接口將大型應(yīng)用拆分為各個(gè)組件,從而使代碼更好具有維護(hù)性、復(fù)用性以及可讀性
注冊(cè)組件
--- Vue.component("my-component",{ template:" my-first-component" }) var app = new Vue({ el:"#app", data:{ } })
解讀:
注冊(cè)行為必須在創(chuàng)建實(shí)例之前;
component的template接口定義組件的html元素;
局部注冊(cè)組件
--- Vue.component("my-component",{ template:" my-first-component" }) var Child = { template: "Hello World
" } var app = new Vue({ el:"#app", components:{ "my-component":Child } })
解讀:
可以定義一個(gè)子組件,在實(shí)例的components接口中將子組件掛載到父組件上,子組件只在父組件的作用域下有效;
特殊DOM模板將會(huì)限制組件的渲染
像這些包含固定樣式的元素?,?
,?
,?