Vue筆記

## 框架和庫(kù)的區(qū)別?> 框架(framework):一套完整的軟件設(shè)計(jì)架構(gòu)和**解決方案**榜跌。> > 庫(kù)(library):對(duì)常用功能性函數(shù)的**封裝**厚者。> > 一般也可以認(rèn)為框架大而全,庫(kù)小而精。一個(gè)框架中可以包含或者集成多個(gè)庫(kù)局装。 + 框架:是一套完整的解決方案;對(duì)項(xiàng)目的侵入性較大,項(xiàng)目如果需要更換框架弹灭,則需要重新架構(gòu)整個(gè)項(xiàng)目。 + 庫(kù)(插件):提供某一個(gè)小功能揪垄,對(duì)項(xiàng)目的侵入性較小穷吮,如果某個(gè)庫(kù)無(wú)法完成某些需求,可以很容易切換到其它庫(kù)實(shí)現(xiàn)需求饥努。## 數(shù)組方法擴(kuò)展- `Array.prototype.forEach`:替代for循環(huán)對(duì)數(shù)組進(jìn)行循環(huán)遍歷```JavaScriptvar list = [1,2,3,4,5]list.forEach(function(v,i){ // v是當(dāng)前遍歷的這一個(gè)元素 i是這個(gè)元素的索引 console.log('當(dāng)前元素是' + v,'當(dāng)前元素的索引是' + i)})```- `Array.prototype.map`:對(duì)數(shù)組進(jìn)行遍歷,同時(shí)會(huì)返回一個(gè)新數(shù)組,新數(shù)組中的每一項(xiàng)都是回調(diào)函數(shù)中的返回值```JavaScriptvar list = [1,2,3,4,5]var newArr = list.map(function(v,i){ // v是當(dāng)前遍歷的這一個(gè)元素 i是這個(gè)元素的索引 console.log('當(dāng)前元素是' + v,'當(dāng)前元素的索引是' + i) return v * 2})console.log(newArr) // [2,4,6,8,10]```- `Array.prototype.findIndex`:對(duì)數(shù)組進(jìn)行遍歷,會(huì)返回一個(gè)滿足回調(diào)函數(shù)條件的元素的索引```JavaScriptvar list = [1,2,3,4,5]var index = list.findIndex(function(v,i){ // v是當(dāng)前遍歷的這一個(gè)元素 i是這個(gè)元素的索引 console.log('當(dāng)前元素是' + v,'當(dāng)前元素的索引是' + i) if(v == 4){ // 當(dāng)return true時(shí)終止循環(huán) 同時(shí)將該元素的索引返回給findIndex函數(shù) return true } // 簡(jiǎn)寫成 // return v == 4})console.log(index) // 3```- `Array.prototype.filter`:對(duì)數(shù)組進(jìn)行遍歷,返回一個(gè)新數(shù)組,新數(shù)組中的每一項(xiàng)都是滿足回調(diào)函數(shù)中條件的元素,當(dāng)滿足條件時(shí)需要`return true````JavaScriptvar list = [1,2,3,4,5]var newArr = list.filter(function(v,i){ // v是當(dāng)前遍歷的這一個(gè)元素 i是這個(gè)元素的索引 console.log('當(dāng)前元素是' + v,'當(dāng)前元素的索引是' + i) if(v%2 == 0){ return true } // 簡(jiǎn)寫成 // return v%2 == 0})console.log(newArr) // [2,4] ```- `Array.prototype.some`:對(duì)數(shù)組進(jìn)行遍歷,返回一個(gè)布爾值,判斷當(dāng)前數(shù)組中是否有一個(gè)元素符合回調(diào)函數(shù)中的條件(特點(diǎn):只要一個(gè)元素滿足條件,最終返回結(jié)果就是true)```JavaScriptvar list = [1,2,3,4,5]var flag = list.some(function(v,i){ // v是當(dāng)前遍歷的這一個(gè)元素 i是這個(gè)元素的索引 console.log('當(dāng)前元素是' + v,'當(dāng)前元素的索引是' + i) if(v % 2 == 0){ // return true時(shí)則終止繼續(xù)循環(huán) return true }})console.log(flag) // true// 注意: 由于遍歷的數(shù)組第二個(gè)元素就滿足了條件 所以循環(huán)到第二個(gè)元素時(shí) 就停止循環(huán)了```- `Array.prototype.every`:對(duì)數(shù)組進(jìn)行遍歷,返回一個(gè)布爾值,判斷當(dāng)前數(shù)組中是否每一個(gè)元素都符合回調(diào)函數(shù)中的條件(特點(diǎn):只要一個(gè)元素不滿足條件,最終返回結(jié)果就是false)```JavaScriptvar list = [1,2,4,6,8]var flag = list.every(function(v,i){ // v是當(dāng)前遍歷的這一個(gè)元素 i是這個(gè)元素的索引 console.log('當(dāng)前元素是' + v,'當(dāng)前元素的索引是' + i) if(v % 2 == 0){ // return true時(shí)則終止繼續(xù)循環(huán) return true }})console.log(flag) // false// 注意: 由于遍歷的數(shù)組第一個(gè)元素就不滿足條件 實(shí)際上循環(huán)一次就停止了```## Vue基礎(chǔ)> MVC:對(duì)項(xiàng)目的整體把控,M代表的是數(shù)據(jù)庫(kù)中的數(shù)據(jù),V代表的是前端的視圖層捡鱼,C用于處理M和V之間進(jìn)行交互的業(yè)務(wù)邏輯(業(yè)務(wù)邏輯需要程序員自己控制,自己編寫)> MVVM:主要用于一些前端的框架,對(duì)MVC三層架構(gòu)中的視圖層再次進(jìn)行層次劃分酷愧,M是當(dāng)前一個(gè)視圖中需要用到的數(shù)據(jù),V就是當(dāng)前視圖,VM負(fù)責(zé)M和V之間的數(shù)據(jù)調(diào)度,內(nèi)部已經(jīng)幫你完成了數(shù)據(jù)的綁定和交互> MVC和MVVM之間的區(qū)別:MVC數(shù)據(jù)流通是單向的,MVVM是雙向數(shù)據(jù)綁定> 雙向數(shù)據(jù)綁定的意思就是模型中的數(shù)據(jù)可以之間更新到視圖上,視圖中的數(shù)據(jù)發(fā)生改變也可以直接更新到模型中能夠做到雙向數(shù)據(jù)綁定(通信)的原因:就是因?yàn)橛蠽M的存在驾诈,VM內(nèi)部的實(shí)現(xiàn)一般是框架已經(jīng)處理完成,不需要程序員進(jìn)行控制- 雙向數(shù)據(jù)綁定原理: `Object.defineProperty`存取器> 使用`Object.defineProperty`提供的set方法可以在給對(duì)象賦值時(shí),觸發(fā)額外操作,即在set函數(shù)內(nèi)部去處理視圖的更新```JavaScript// 使用 Object.defineProperty 可以給對(duì)象賦值var obj = {};Object.defineProperty(obj,'name',{ value:'zxx'})console.log(obj.name)var obj = {};var initValue = 'zxx'Object.defineProperty(obj,'name',{ get:function(){ console.log('我被讀取了') return initValue }, set:function(v){ console.log('我被賦值了') initValue = v }})obj.name = 'lxy'console.log(obj.name)```### Vue基本編碼步驟1. 引入vue.js文件2. 定義一個(gè)vue的管理范圍



vue1.0里面vue的管理區(qū)域的id可以定義在HTML以及body標(biāo)簽上? ? ? ? vue2.0里面不允許這樣來(lái)做3. 定義一個(gè)vue的對(duì)象? ? ? ? var vm = new Vue({? ? ? ? ? ? el:'#app',? ? ? ? ? ? // data定義vue實(shí)例的所有屬性? ? ? ? ? ? data:{? ? ? ? ? ? ? ? // 定義將來(lái)要在vue管理區(qū)域中使用的數(shù)據(jù)? ? ? ? ? ? ? ? name:"zs"? ? ? ? ? ? },? ? ? ? ? ? // methods定義vue實(shí)例所有的方法? ? ? ? ? ? methods:{? ? ? ? ? ? ? ? fn:function(){? ? ? ? ? ? ? ? ? ? this.name = 'ls'? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? })### Vue系統(tǒng)指令- `{{}}`:插值表達(dá)式```? ? 作用:將vue對(duì)象中的數(shù)據(jù)以及表達(dá)式顯示到vue托管區(qū)域中? ? {{這里書寫vue對(duì)象中data里面的數(shù)據(jù)或者表達(dá)式}}```- `v-cloak`:解決表達(dá)式閃爍問(wèn)題```1. 定義一個(gè)樣式 ? [v-cloak]{

? ? ? display:none

? }

2. 使用

{{name}}

原理:當(dāng)vue.js文件還沒(méi)有加載出來(lái)時(shí) 使用[v-cloak]樣式作用于當(dāng)前指令所在標(biāo)簽,當(dāng)vue.js能夠起作用時(shí),會(huì)自動(dòng)刪除v-cloak指令```? ? ? ? - `v-text`:輸出文本數(shù)據(jù)``````- `v-html`:輸出HTML結(jié)構(gòu)數(shù)據(jù)```

data:{name:'zs'}```- `v-bind`:動(dòng)態(tài)給標(biāo)簽或者組件綁定屬性```

// 使用:簡(jiǎn)寫v-bind

// 變量和常量組合跳轉(zhuǎn)data:{cls: 'red blue',id: 1}```? - `v-on`:綁定事件```

// 簡(jiǎn)寫

methods: { // 這個(gè) methods屬性中定義了當(dāng)前Vue實(shí)例所有可用的方法? ? ? ? show: function () {? ? ? ? ? alert('Hello')? ? ? ? } }```- `v-model`:雙向數(shù)據(jù)綁定```// 可以使用的標(biāo)簽:input textarea select 組件// name會(huì)和表單元素的value進(jìn)行關(guān)聯(lián) value值變化 name值變化 反過(guò)來(lái)name值發(fā)生變化 value值也會(huì)發(fā)生變化```- `v-for`:循環(huán)輸出HTML元素```

{{item.name}}

```- `v-if`:根據(jù)表達(dá)式值的真假?zèng)Q定元素的顯示隱藏```// isShow為true顯示div 為false隱藏div// v-if是直接操作DOM 即隱藏時(shí)會(huì)將該div從DOM結(jié)構(gòu)中移除

```- `v-show`: 根據(jù)表達(dá)式值的真假?zèng)Q定元素的顯示隱藏```// isShow為true顯示div 為false隱藏div// v-show是操作div的樣式 顯示時(shí)添加 style = 'display:block'; 隱藏時(shí)添加style = 'display:none'

v-if 是刪除DOM元素 效率比較低 會(huì)造成頁(yè)面的結(jié)構(gòu)重新繪制v-show 是控制樣式 只會(huì)改變當(dāng)前這一個(gè)元素的樣式 不會(huì)造成頁(yè)面結(jié)構(gòu)的重新繪制```### 在Vue中使用樣式#### 使用class樣式1. 數(shù)組```

這是一個(gè)邪惡的H1

```2. 數(shù)組中使用三元表達(dá)式```

這是一個(gè)邪惡的H1

```3. 數(shù)組中嵌套對(duì)象```

這是一個(gè)邪惡的H1

```4. 直接使用對(duì)象```

這是一個(gè)邪惡的H1

```#### 使用內(nèi)聯(lián)樣式1. 直接在元素上通過(guò) `:style` 的形式,書寫樣式對(duì)象```

這是一個(gè)善良的H1

```2. 將樣式對(duì)象溶浴,定義到 `data` 中乍迄,并直接引用到 `:style` 中 + 在data上定義樣式:```data: {? ? ? ? h1StyleObj: { color: 'red', 'font-size': '40px', 'font-weight': '200' }}``` + 在元素中,通過(guò)屬性綁定的形式士败,將樣式對(duì)象應(yīng)用到元素中:```

這是一個(gè)善良的H1

```3. 在 `:style` 中通過(guò)數(shù)組闯两,引用多個(gè) `data` 上的樣式對(duì)象 + 在data上定義樣式:```data: {? ? ? ? h1StyleObj: { color: 'red', 'font-size': '40px', 'font-weight': '200' },? ? ? ? h1StyleObj2: { fontStyle: 'italic' }}``` + 在元素中,通過(guò)屬性綁定的形式谅将,將樣式對(duì)象應(yīng)用到元素中:```

這是一個(gè)善良的H1

```### 過(guò)濾器> `過(guò)濾器`:對(duì)需要展示的數(shù)據(jù)進(jìn)行加工處理后再展示到界面漾狼,并不會(huì)改變?cè)瓟?shù)據(jù)- 全局過(guò)濾器:當(dāng)前頁(yè)面所有Vue實(shí)例的托管區(qū)域都可以使用```JavaScriptVue.filter('過(guò)濾器名稱',function(value,arg){? ? // value就是需要處理的原始數(shù)據(jù) arg是使用過(guò)濾器時(shí)傳遞的參數(shù)? ? // 對(duì)數(shù)據(jù)處理的業(yè)務(wù)邏輯? ? return 處理完畢的數(shù)據(jù)})使用方法:原始數(shù)據(jù) | 過(guò)濾器名稱(參數(shù))```- 私有過(guò)濾器:只有當(dāng)前定義過(guò)濾器的Vue實(shí)例所托管的區(qū)域可以使用```JavaScriptnew Vue({? ? el:'#app',? ? // 私有過(guò)濾器? ? filters:{? ? ? ? '過(guò)濾器的名稱':function(value){? ? ? ? ? ? return 處理完畢的數(shù)據(jù)? ? ? ? }? ? }})```### 自定義指令> `指令`: 其實(shí)就是Vue給我們提供的操作DOM元素的一些方法- 全局指令```JavaScriptVue.directive('指令名稱',{? ? // 指令第一次綁定到元素身上時(shí)執(zhí)行(在內(nèi)存中綁定到了DOM對(duì)象上邊)? ? bind:function(el,binding,VNode){? ? ? ? // el: 指令所在的DOM元素對(duì)象? ? ? ? // binging.value 指令等號(hào)右邊表達(dá)式的值? ? ? ? // binging.expression 指令等號(hào)右邊表達(dá)式? ? ? ? // VNode.context 當(dāng)前指令所在托管區(qū)域?qū)τ诘腣ue實(shí)例對(duì)象? ? },? ? // 當(dāng)前指令所在元素插入到父節(jié)點(diǎn)時(shí)調(diào)用(不保證DOM已經(jīng)渲染完畢)? ? inserted:function(){},? ? // 指令綁定的值發(fā)生變化時(shí)會(huì)去執(zhí)行? ? update:function(){},? ? // 指令所在的組件值更新完畢時(shí)調(diào)用? ? componentUpdated:function(){},? ? // 自定義指令從當(dāng)前元素解綁時(shí)調(diào)用? ? unbind:function(){}})```- 私有指令```JavaScriptnew Vue({? ? el:'#app',? ? // 私有指令? ? directives:{? ? ? ? '指令名稱':{? ? ? ? ? ? bind:function(el,binding){? ? ? ? ? ? }? ? ? ? }? ? },? ? // 私有過(guò)濾器? ? filters:{? ? ? ? '過(guò)濾器的名稱':function(value){? ? ? ? ? ? return 處理完畢的數(shù)據(jù)? ? ? ? }? ? }})```## 生命周期鉤子函數(shù)> 回調(diào)函數(shù):一個(gè)函數(shù)被當(dāng)做參數(shù)進(jìn)行傳遞的時(shí)候,稱作這個(gè)函數(shù)為回調(diào)函數(shù)> 構(gòu)造函數(shù):一個(gè)函數(shù)被new 關(guān)鍵字引導(dǎo)執(zhí)行的時(shí)候,稱作這個(gè)函數(shù)為構(gòu)造函數(shù)> 鉤子函數(shù): 一個(gè)應(yīng)用程序或者框架內(nèi)部提前定義好的一批函數(shù),這些函數(shù)會(huì)在特定的時(shí)間段自動(dòng)執(zhí)行>> 生命周期: 一個(gè)程序會(huì)存在初始化 - 運(yùn)行 - 銷毀等階段,這些階段統(tǒng)稱為該程序的生命周期```new Vue({? ? el:'#app',? ? data:{},? ? methods:{},? ? beforeCreated(){},? ? // data中的數(shù)據(jù)和methods中的方法已經(jīng)初始化完畢會(huì)去自動(dòng)執(zhí)行created方法? ? created(){? ? ? ? // 用于發(fā)生數(shù)據(jù)請(qǐng)求,也可以初始化一些數(shù)據(jù)? ? },? ? beforeMount(){},? ? // 真實(shí)DOM已經(jīng)渲染完畢會(huì)執(zhí)行mounted函數(shù)? ? mounted(){? ? ? ? // 操作真實(shí)DOM? ? }? ? beforeUpdate(){},? ? // data中的發(fā)生了變化而且被重新渲染到了界面上時(shí)才會(huì)執(zhí)行? ? updated(){? ? ? ? // 數(shù)據(jù)更新后重新操作DOM? ? },? ? // 實(shí)例銷毀之前,實(shí)例上面的各種屬性和方法都還可以正常訪問(wèn),通常可以在這里手動(dòng)回收一些頁(yè)面沒(méi)有被釋放的變量,比如清楚定時(shí)器的操作戏自。? ? beforeDestroy(){},? ? // 實(shí)例已經(jīng)從內(nèi)存中被銷毀? ? destroyed(){}})```## vue-resource發(fā)生ajax請(qǐng)求> vue.studyit.io```javascript// get請(qǐng)求this.$http.get('url').then(function(res){? ? // res.body 里面就是請(qǐng)求回來(lái)的數(shù)據(jù)})// post 請(qǐng)求 application/x-www-form-urlencode -> name=zs&age=18// application/json => {'name':'zs','age':18}this.$http.post('url',{name:'zs',age:18},{emulateJSON:true}).then(function(res){? ? // res.body})// jsonp請(qǐng)求this.$http.jsonp('url').then(function(res){? ? // res.body})```- **JSONP**:JSON數(shù)據(jù)格式的一種使用方式,用于解決跨域問(wèn)題- **跨域**: 由于瀏覽器同源策略的限制,不同源的URL不能互相通信,這種現(xiàn)象叫做跨域- **同源策略**: 兩個(gè)域名只有 **協(xié)議** **主機(jī)地址** **端口號(hào)**完全一致時(shí)才能相互通信訪問(wèn)- **JSONP實(shí)現(xiàn)原理**:利用script標(biāo)簽的src屬性發(fā)送請(qǐng)求不受同源策略的限制這個(gè)機(jī)制去實(shí)現(xiàn)跨域資源共享(script標(biāo)簽?zāi)軌蚩缬蛟L問(wèn)是歷史遺留問(wèn)題,并不安全)? ? 1. 動(dòng)態(tài)創(chuàng)建一個(gè)script標(biāo)簽,并且將需要請(qǐng)求的URL地址設(shè)置給script標(biāo)簽的src屬性,同時(shí)在URL地址后面拼接上一個(gè)回調(diào)函數(shù)名稱```? ? ? ? function getJson(data){? ? ? ? ? ? console.log(data)? ? ? ? }// getJson就是在前端本地定義好的一個(gè)方法的方法名 ```? ? ? 2. 后臺(tái)接收到該請(qǐng)求后,先根據(jù)參數(shù)判斷是否是JSONP請(qǐng)求,如果是,則將客戶端請(qǐng)求的數(shù)據(jù)整理好,和前端發(fā)送過(guò)來(lái)的方法名一起拼接成一個(gè)函數(shù)調(diào)用的字符串,客戶端需要的數(shù)據(jù)就是這個(gè)函數(shù)調(diào)用時(shí)傳的參數(shù)```? ? ? ? // 假設(shè)要發(fā)送給前端的數(shù)據(jù)是 'ok'? ? ? ? 'getJson('ok')'? ? ? ? // 響應(yīng)給前端? ? ? ? res.end('getJson('ok')') ```? ? ? 3. 由于后臺(tái)響應(yīng)回來(lái)的數(shù)據(jù)是一個(gè)字符串,而且是函數(shù)調(diào)用,所以前端拿到響應(yīng)回來(lái)的數(shù)據(jù)相當(dāng)于調(diào)用了該方法,那么前端定義好的方法會(huì)自動(dòng)執(zhí)行,而且方法內(nèi)的形參可以接收到實(shí)參值,也就是后臺(tái)拼接的數(shù)據(jù)```? ? ? ? function getJson(data){? ? ? ? ? ? console.log(data) // ok? ? ? ? }```? ? 4. 數(shù)據(jù)拿到之后,一般這個(gè)動(dòng)態(tài)創(chuàng)建的script標(biāo)簽會(huì)被刪除掉## vue過(guò)渡動(dòng)畫### 原生css類實(shí)現(xiàn)```JavaScript// 1. 將需要實(shí)現(xiàn)動(dòng)畫的元素使用transition標(biāo)簽包裹起來(lái)? ?

我是需要過(guò)渡動(dòng)畫的元素
// 2. 使用系統(tǒng)提供的類名書寫動(dòng)畫樣式// v-enter: 動(dòng)畫進(jìn)入時(shí)候的初始狀態(tài)// v-leave-to: 動(dòng)畫離開(kāi)時(shí)候的結(jié)束狀態(tài)v-enter,v-leave-to {}// v-enter-active: 動(dòng)畫進(jìn)入期間持續(xù)狀態(tài)// v-enter-active: 動(dòng)畫離開(kāi)期間持續(xù)狀態(tài) v-enter-active,v-leave-active {}// 動(dòng)畫離開(kāi)時(shí)候的初始狀態(tài)// 動(dòng)畫進(jìn)入時(shí)候的結(jié)束狀態(tài)v-leave,v-enter-to {}// 3. 也可以使用transition上面的name屬性指定v-前綴```### animatie.css類庫(kù)實(shí)現(xiàn)```JavaScript// 1. 將需要實(shí)現(xiàn)動(dòng)畫的元素使用transition標(biāo)簽包裹起來(lái)? ?
我是需要過(guò)渡動(dòng)畫的元素
// 2. 在transition上設(shè)置動(dòng)畫類名? ?
我是需要過(guò)渡動(dòng)畫的元素
```### 動(dòng)畫鉤子函數(shù)實(shí)現(xiàn)```javascript// 1. 將需要實(shí)現(xiàn)動(dòng)畫的元素使用transition標(biāo)簽包裹起來(lái)? ?
我是需要過(guò)渡動(dòng)畫的元素
// 2. 在transition上注冊(cè)實(shí)現(xiàn)動(dòng)畫的鉤子函數(shù),入場(chǎng)動(dòng)畫三個(gè),出場(chǎng)動(dòng)畫三個(gè)? ?
我是需要過(guò)渡動(dòng)畫的元素
// 3. 在vue實(shí)例的methods中定義鉤子函數(shù)new Vue({? ? el:'#app',? ? data:{},? ? methods:{? ? ? ? // 入場(chǎng)動(dòng)畫初始狀態(tài)設(shè)置? ? ? ? beforeEnter(){? ? ? ? ? ? // 一般使用JS設(shè)置執(zhí)行動(dòng)畫元素的初始位置和其他樣式屬性? ? ? ? },? ? ? ? // 入場(chǎng)動(dòng)畫持續(xù)過(guò)程? ? ? ? enter(el,done){? ? ? ? ? ? // 1. 固定寫法 迫使瀏覽器重繪 刷新動(dòng)畫? ? ? ? ? ? el.offsetWidth? ? ? ? ? ? // 2. 一般設(shè)置執(zhí)行動(dòng)畫元素最終的位置和其他樣式屬性? ? ? ? ? ? // 3. 固定寫法 調(diào)用afterEnter函數(shù)? ? ? ? ? ? done()? ? ? ? },? ? ? ? // 入場(chǎng)動(dòng)畫結(jié)束狀態(tài)? ? ? ? afterEnter(){? ? ? ? ? ? // 設(shè)置動(dòng)畫元素回到初始狀態(tài)? ? ? ? },? ? ? ? // 出場(chǎng)動(dòng)畫初始狀態(tài)? ? ? ? beforeLeave(){? ? ? ? },? ? ? ? // 出場(chǎng)動(dòng)畫持續(xù)狀態(tài)? ? ? ? leave(){? ? ? ? },? ? ? ? // 出場(chǎng)動(dòng)畫結(jié)束狀態(tài)? ? ? ? afterLeave(){? ? ? ? }? ? }})```### transition-group列表渲染> 如果需要渲染的元素是一個(gè)列表,則不能使用transition包裹元素,需要使用transition-group- `appear`屬性可以使默認(rèn)出現(xiàn)的元素出現(xiàn)過(guò)渡動(dòng)畫- `tag`屬性可以指定`transition-group`標(biāo)簽被渲染成一個(gè)什么元素,默認(rèn)情況下`transition-group`會(huì)被渲染成`span````? ?
```## 組件> http://blog.gdfengshuo.com/example/work/#/login> https://github.com/UniverseKing/awesome-github-vue> **注意**:> 1. 定義組件時(shí)如果使用的是駝峰命名,那么使用組件時(shí)需要將駝峰的大寫字母轉(zhuǎn)成小寫,并且用-連接兩個(gè)單詞 ```javascriptVue.component('myCom',{? ? template:'
我是一個(gè)駝峰命名的組件
'})// 使用```> 2. 組件的`template`屬性中的模版內(nèi)部如果有多個(gè)元素,必須被包含在唯一的一個(gè)根元素中```javascript? ?
? ? ? ?

我是p元素

? ? ? ? 我是span元素? ?
```> 3. 私有組件(子組件)使用`components`屬性進(jìn)行定義,定義好的私有組件只能在父組件的模板中使用```javascript? ?
? ? ? ? ? ?
// 父組件Vue.component('father',{? ? template:'#father',? ? components:{? ? ? ? // 子組件? ? ? ? son:{? ? ? ? ? ? template:'
我是son組件
'? ? ? ? }? ? }})```### 全局組件的三種定義方式-? `vue.extend()`定義```javascript// 1. 使用vue.extend()定義組件模板var dv = Vue.extend({? ? template:'
我是一個(gè)組件
'})// 2. 使用Vue.component()注冊(cè)組件Vue.component('com',dv)// 3. 在Vue托管區(qū)域像使用普通HTML標(biāo)簽一樣使用組件```-? `vue.component()`定義```javascript// 1. 使用Vue.component定義組件Vue.component('com',{? ? template:'

我是一個(gè)組件中的元素

我也是組件中的元素
'})// 2. 使用組件```- 使用`template`標(biāo)簽定義模板```javascript// 1. 使用Vue.component定義組件邦投,并且使用選擇器選擇模板Vue.component('com',{? ? template:'#temp'}) // 2. 使用template標(biāo)簽定義模板,并且給template標(biāo)簽添加id? ?
? ? ? ?

我是p元素

? ? ? ? 我是span元素? ?
// 3. 使用組件```### 私有組件的定義方式> 私有組件使用`components`屬性進(jìn)行定義,該屬性可以定義在Vue實(shí)例內(nèi)部,也可以定義在組件內(nèi)部,私有組件一般也是其他組件的子組件```javascript// Vue實(shí)例的私有組件new Vue({? ? el:'#app',? ? data:{},? ? methods:{},? ? components:{? ? ? ? 'login': {? ? ? ? ? ? template:'
我是一個(gè)私有組件,只能使用在當(dāng)前#appVue實(shí)例托管區(qū)域內(nèi)部
'? ? ? ? }? ? }})// 組件的私有組件(子組件)? ?
? ? ? ? 我是賬號(hào)組件,我有兩個(gè)子組件login和register? ? ? ? ? ? ? ? ? ?
Vue.component('account',{? ? tempalte:'#account',? ? components:{? ? ? ? 'login':{? ? ? ? ? ? template:'
我是登錄組件,我的父組件是account
',? ? ? ? ? ? components:{? ? ? ? ? ? ? ? 'com':{? ? ? ? ? ? ? ? ? ? template:'
123
'? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? },? ? ? ? 'register':{? ? ? ? ? ? template:'
我是注冊(cè)組件,我的父組件是account
'? ? ? ? }? ? }})```### is屬性和component實(shí)現(xiàn)組件切換```// comname 是哪個(gè)組件名,則component就會(huì)被渲染成哪個(gè)組件// component 就是一個(gè)占位標(biāo)簽 new Vue({? ? el:'#app',? ? comname:'login'})```### 父子組件傳值#### 父向子傳值```javascript// 1. 先在父組件中定義好要傳遞的數(shù)據(jù)new Vue({? ? el:'#app'? ? data:{? ? ? ? msg:'我是要傳遞給子組件的數(shù)據(jù)'? ? },? ? components:{? ? ? ? son:{? ? ? ? ? ? template:'
我是子組件{{message}}
',? ? ? ? ? ? props:['message']? ? ? ? }? ? }})// 2. 在父組件中使用子組件的時(shí)候,用綁定屬性的方式將父組件中的數(shù)據(jù)傳遞給子組件
? ?
// 3. 在子組件中定義一個(gè)props屬性,該屬性是一個(gè)數(shù)組,數(shù)組中定義用于接收傳過(guò)來(lái)的變量。這個(gè)變量// 和第二步綁定的這個(gè)屬性同名son:{? ? template:'
我是子組件
',? ? props:['message']}```#### 子向父?jìng)髦?gt; 發(fā)布訂閱者 設(shè)計(jì)模式```javascript// 1. 定義好父子組件,定義好子組件需要傳遞給父組件的數(shù)據(jù)new Vue({? ? el:'#app'? ? components:{? ? ? ? son:{? ? ? ? ? ? template:'
我是子組件{{message}}
',? ? ? ? ? ? data:function(){? ? ? ? ? ? ? ? return {? ? ? ? ? ? ? ? ? ? msg:'傳給父組件的數(shù)據(jù)'? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? }? ? }})// 2. 在子組件中使用this.$emit觸發(fā)一個(gè)自定義的方法名,然后傳遞數(shù)據(jù)// 第一個(gè)參數(shù)就是自定義的方法名// 第二個(gè)參數(shù)就是需要傳遞給父組件的數(shù)據(jù)this.$emit('func',this.msg)// 3. 在父組件中使用子組件時(shí),綁定一個(gè)事件,事件名稱和子組件觸發(fā)的方法名同名
? ?
// 4. 在父組件的methods中定義一個(gè)事件處理函數(shù)methods:{? ? getmsg:function(data){? ? ? ? // data就是子組件傳過(guò)來(lái)的數(shù)據(jù)? ? }}```### ref獲取DOM和組件對(duì)象```javascript// 1. 在DOM元素或者組件上面綁定ref屬性
我是一個(gè)div
// 2. 使用this.$refs.屬性值獲取對(duì)象引用this.$refs.mydiv // DOM對(duì)象this.$refs.mycom // 組件對(duì)象```## vur-router路由> **后端路由**: 服務(wù)端對(duì)前端請(qǐng)求的URL地址的監(jiān)聽(tīng),一個(gè)路由地址對(duì)應(yīng)一個(gè)資源> **前端路由**: 瀏覽器對(duì)前端頁(yè)面實(shí)現(xiàn)的跳轉(zhuǎn)方式,一般只在單頁(yè)應(yīng)用(SPA)程序中出現(xiàn)> router? route routes? 的區(qū)別是?- router: 是Vue實(shí)例內(nèi)部的一個(gè)屬性,是專門用來(lái)掛載vue-router對(duì)象的- route: 表示routers內(nèi)部的每一個(gè)路由對(duì)象的引用- routes: 是Vue-Router實(shí)例內(nèi)部的一個(gè)屬性,是用來(lái)保存所有的路由規(guī)則### 基本使用步驟```javascript1. 創(chuàng)建路由對(duì)象并配置路由規(guī)則// 1.1 創(chuàng)建組件模板對(duì)象var login = {? ? template:'
登錄
'}var register = {? ? template:'
注冊(cè)
'}// 1.2 創(chuàng)建路由對(duì)象并配置路由規(guī)則var router1 = new VueRouter({? ? // routes用來(lái)存放路由規(guī)則,每個(gè)路由規(guī)則都是一個(gè)對(duì)象? ? routes:[? ? ? ? // path: 頁(yè)面#后面的地址? ? ? ? // component 需要顯示的組件對(duì)象? ? ? ? {path:'/',redirect:'/login'},? ? ? ? {path:'/login',component:login},? ? ? ? {path:'/register',component:register}? ? ]})// 1.3 將創(chuàng)建處理的路由對(duì)象和Vue進(jìn)行綁定new Vue({? ? el:'#app',? ? // 將vuerouter對(duì)象注冊(cè)到Vue內(nèi)部,以保證在托管區(qū)域中科院使用VueRouter內(nèi)部提供的組件以及其他屬性和方法? ? router:router1})2. 使用進(jìn)行占位
? ? ?
3. 使用設(shè)置跳轉(zhuǎn)路徑登錄```### redirect重定向> 在路由規(guī)則中配置`redirect`屬性可以使路由進(jìn)行內(nèi)部切換,當(dāng)訪問(wèn)`path`中的路徑時(shí),會(huì)默認(rèn)跳轉(zhuǎn)到`redirect`中指定的路徑去擅笔。```JavaScript{path:'/',redirect:'/login'} // 當(dāng)訪問(wèn)根路徑時(shí),會(huì)默認(rèn)跳轉(zhuǎn)到login路徑中```### linkActiveClass路由高亮> `linkActiveClass` 用來(lái)設(shè)置被激活路由的樣式類,默認(rèn)類名是`router-link-active````JavaScriptnew VueRouter({? ? linkActiveClass:'mylink' // 被選中的路由對(duì)應(yīng)的標(biāo)簽上面會(huì)有一個(gè)類名叫mylink})```### 路由傳參#### query傳參```JavaScript// 1. 在跳轉(zhuǎn)路徑后面使用查詢字符串拼接參數(shù)登錄// 2. 在路由對(duì)應(yīng)的組件內(nèi)部使用`this.$route.query`獲取參數(shù)this.$route.query.name // zsthis.$route.query.id // 18```#### params傳參```JavaScript// 1. 更改路由規(guī)則用于匹配參數(shù)new VueRouter({? ? routes:[? ? ? ? // :id用于匹配/login/13后面的參數(shù)13? ? ? ? {path:'/login/:id',component:login}? ? ]})// 2. 在跳轉(zhuǎn)路徑后面使用/拼接參數(shù)登錄// 3. 在路由對(duì)應(yīng)組件內(nèi)部使用`this.$route.params`獲取參數(shù)var login = {? ? template:'
登錄組件{{this.$route.params.id}}
',? ? created(){? ? ? ? console.log(this.$route.params.id) // 獲取到的就是13? ? }}```### 嵌套路由```JavaScript// 1. 在父路由內(nèi)部使用children屬性配置子路由規(guī)則,子路由規(guī)則對(duì)象中的path屬性不要 '/' // 2. 在父路由規(guī)則對(duì)應(yīng)的組件模板中添加router-view用于顯示子路由規(guī)則對(duì)應(yīng)的組件// 3. 在中設(shè)置跳轉(zhuǎn)路徑(將父路由和子路由的path拼接)```### 路由命名視圖> 給``添加name屬性,用于指定顯示哪一個(gè)組件```JavaScript// 1. 將路由規(guī)則對(duì)象中的component改為components,表示一個(gè)路由規(guī)則下可以顯示多個(gè)組件,每一個(gè)組件用一個(gè)名稱對(duì)應(yīng)起來(lái),默認(rèn)顯示的組件用default對(duì)應(yīng)new VueRouter({? ? routes:[? ? ? ? // components對(duì)象內(nèi)部按照 名稱 - 組件對(duì)象的方式定義? ? ? ? {path:'/',components:{? ? ? ? ? ? 'default': header,? ? ? ? ? ? 'left': leftBox,? ? ? ? ? ? 'main': mainBox? ? ? ? }}? ? ]})// 2. 給添加name屬性指定顯示哪一個(gè)組件? // 不指定默認(rèn)顯示default對(duì)應(yīng)的組件 // 顯示leftBox組件 // 顯示mainBox組件```## watch的使用> `watch`: 用于監(jiān)聽(tīng)data中定義的數(shù)據(jù)的變化,只要被監(jiān)聽(tīng)的數(shù)據(jù)發(fā)生了變化,就會(huì)執(zhí)行對(duì)應(yīng)的處理函數(shù)### watch監(jiān)視數(shù)據(jù)變化```new Vue({? ? el:'#app',? ? data:{? ? ? ? msg:'hello'? ? },? ? watch:{? ? ? ? 'msg': function(newVal,oldVal){? ? ? ? ? ? // newVal 表示變化后的值 oldVal 表示變化前的值? ? ? ? ? ? // 只要data中定義的msg發(fā)生了改變,就會(huì)執(zhí)行這個(gè)函數(shù)? ? ? ? }? ? }})```### watch監(jiān)視路由變化> 通過(guò)監(jiān)聽(tīng)`$route.path`可以監(jiān)視到路由地址的變化```javascriptnew Vue({? ? el:'#app',? ? watch:{? ? ? ? '$route.path': function(newVal,oldVal){? ? ? ? ? // newVal 新跳轉(zhuǎn)的路由地址? ? ? ? ? // oldVal 跳轉(zhuǎn)之前的路由地址? ? ? ? }? ? }})```## computed計(jì)算屬性> `computed`:計(jì)算屬性,是指在computed對(duì)象中定義屬性,屬性的值是該屬性后面函數(shù)的返回值,而且函數(shù)內(nèi)部如果用到了data中定義的其他數(shù)據(jù),只要這些數(shù)據(jù)發(fā)生了變化,都會(huì)重新觸發(fā)函數(shù)的執(zhí)行,計(jì)算屬性的值也會(huì)發(fā)生變化志衣。```javascriptnew Vue({? ? el:'#app',? ? data:{? ? ? ? msg:'hello'? ? },? ? computed:{? ? ? ? 'info': function(){? ? ? ? ? ? // 只要msg發(fā)生了變化,會(huì)重新觸發(fā)該函數(shù)的執(zhí)行? ? ? ? ? ? // info的值就是函數(shù)的返回值? ? ? ? ? return this.msg + 'world'? ? ? ? }? ? },? ? methods:{},? ? watch:{}})```### watch 和 computed計(jì)算屬性的區(qū)別> watch可以對(duì)data中申明過(guò)的數(shù)據(jù)進(jìn)行監(jiān)視,只要被監(jiān)視的數(shù)據(jù)發(fā)生了變化,就會(huì)觸發(fā)對(duì)應(yīng)函數(shù)> computed定義計(jì)算屬性,定義的屬性和在data中定義的使用方式一樣,但是computed中的屬性值是對(duì)應(yīng)函數(shù)的返回值,只要函數(shù)中依賴的其他數(shù)據(jù)發(fā)生了變化,會(huì)重新計(jì)算返回值### data、props猛们、computed的區(qū)別> data中的相當(dāng)于申明變量,可以直接賦值也可以隨后賦值> props中數(shù)據(jù)是從其他組件傳遞得到> computed中的數(shù)據(jù)是通過(guò)計(jì)算得到,是屬性對(duì)應(yīng)函數(shù)的返回值,計(jì)算結(jié)果會(huì)被緩存- npm: node package manager node包管理工具- nrm: node registry manager node 鏡像地址管理工具- nvm: node version manager node 版本管理工具## webpack的學(xué)習(xí)> 什么是webpack? 一個(gè)基于Node的前端構(gòu)建工具,可以實(shí)現(xiàn)對(duì)項(xiàng)目的打包(構(gòu)建),主要解決文件(模塊)之間的依賴,高級(jí)代碼的轉(zhuǎn)譯,文件(模塊)的合并和壓縮等問(wèn)題念脯。### 基本使用 - `webpack3.~`版本安裝使用```JavaScript// 1. 全局安裝webpacknpm i webpack@3.10.0 -g// 2. 使用webpack 入口文件 輸出文件webpack ./src/main.js ./dist/build.js```- `webpack4.~`版本安裝使用```JavaScript// 1. 全局安裝webpacknpm i webpack? -gnpm i webpack-cli -g// 2. 使用webpack 入口文件 -o 輸出文件 --mode development/productionwebpack ./src/main.js -o ./dist/build.js --mode development```### webpack配置文件使用```javascript// 1. 在項(xiàng)目根目錄新建webpack.config.js,并設(shè)置 打包的入口文件 和 輸出文件module.exports = {? ? // 入口文件(絕對(duì)路徑)? ? entry: path.join(__dirname,'./src/main.js'),? ? // 輸出文件? ? output: {? ? ? ? path: path.join(__dirname,'./dist'), // 輸出文件目錄? ? ? ? filename: 'build.js' // 輸出文件名稱? ? }}// 2. 執(zhí)行打包命令webpack```### webpack-dev-server的使用> #### 命令行方式> `--hot`: 熱更新,可以局部更新文件> `--open`: 自動(dòng)打開(kāi)瀏覽器> `--port`: 配置端口號(hào)> `--contentBase`: 指定服務(wù)器目錄```javascript// 1. 局部安裝webpack-dev-server和webpacknpm i webpack-dev-server webpack --save-dev// 2. 在package.json的scripts節(jié)點(diǎn)中添加啟動(dòng)命令"scripts":{? ? "dev":"webpack-dev-server --open --hot --contentBase --port 8888"}// 3. 在項(xiàng)目根目錄運(yùn)行項(xiàng)目npm run dev```#### 配置文件方式```javascript// 1. 在webpack.config.js配置文件中添加如下配置devServer:{? ? open: true,? ? port: 8888,? ? contentBase: 'src',? ? hot: true}// 2. 如果設(shè)置了 hot:true 這個(gè)屬性,則需要配置熱更新插件// 2.0 引入webpack模塊const webpack = require('webpack')// 2.1 配置熱更新插件plugins: [? ? new webpack.HotModuleReplacementPlugin()]// 3. package.json中配置啟動(dòng)命令"scripts":{? ? "dev":"webpack-dev-server"}```### `html-webpack-plugin`的使用> 可以根據(jù)指定的HTML模板文件生成一個(gè)HTML頁(yè)面,并且在HTML頁(yè)面中自動(dòng)引入打包好的js文件```javascript// 1. 安裝html-webpack-pluginnpm i html-webpack-plugin --save-dev// 2. 在webpack.config.js中的plugins節(jié)點(diǎn)中配置插件// 2.1 導(dǎo)入html-webpack-pluginconst htmlWebpackPlugin = require('html-webpack-plugin')// 2.2 配置插件plugins:[? ? new htmlWebpackPlugin({? ? ? ? template:path.join(__dirname,'./src/index.html'),// 需要生成的HTML的模板文件? ? ? ? filename:'index.html' // 生成的HTML文件的名稱? ? })]```### `css-loader`處理CSS文件> 解析處理文件后綴名為.css的文件```javascript// 1. 安裝style-loader css-loadernpm i style-loader css-loader --save-dev// 2. 在webpack.config.js中的moudle節(jié)點(diǎn)中配置解析規(guī)則module:{? ? rules:[? ? ? ? {? ? ? ? ? ? test:/\.css$/,? ? ? ? ? ? use:['style-loader','css-loader']? ? ? ? }? ? ]}```### `less-loader`處理less文件> 解析處理文件后綴名為.less的文件```javascript// 1. 安裝less less-loadernpm i less less-loader --save-dev// 2. 在webpack.config.js中的moudle節(jié)點(diǎn)中配置解析規(guī)則module:{? ? rules:[? ? ? ? {? ? ? ? ? ? test:/\.less$/,? ? ? ? ? ? use:['style-loader','css-loader','less-loader']? ? ? ? }? ? ]}```### `scss-loader`處理scss文件> 解析處理文件后綴名為.scss的文件```javascript// 1. 安裝node-sass sass-loadernpm i node-sass sass-loader --save-dev// 2. 在webpack.config.js中的moudle節(jié)點(diǎn)中配置解析規(guī)則module:{? ? rules:[? ? ? ? {? ? ? ? ? ? test:/\.scss$/,? ? ? ? ? ? use:['style-loader','css-loader','sass-loader']? ? ? ? }? ? ]}```### `url-loader`處理圖片等資源文件> 解析處理項(xiàng)目中引入的圖片、字體圖標(biāo)弯淘、音視頻等資源文件```javascript// 1. 安裝file-loader ulr-loadernpm i file-loader ulr-loader --save-dev// 2. 在webpack.config.js中的moudle節(jié)點(diǎn)中配置解析規(guī)則module:{? ? rules:[? ? ? ? {? ? ? ? ? ? test:/\.(png|jpg|gif)/,? ? ? ? ? ? use:'url-loader?limit=20000&name=[hash:8]-[name].[ext]'? ? ? ? ? ? // 當(dāng)需要打包的文件小于limit的值,會(huì)將圖片轉(zhuǎn)換成base64字符串在build.js中進(jìn)行引用? ? ? ? ? ? // 當(dāng)需要打包的文件大于limit的值,會(huì)將圖片打包到輸出目錄中? ? ? ? ? ? //一般比較小的圖片才需要被轉(zhuǎn)成base64,所以該值不宜太大? ? ? ? ? ? // name=[hash:8]-[name].[ext]表示將來(lái)打包出來(lái)的文件名稱以8位hash值和原來(lái)的名稱進(jìn)行拼接,文件擴(kuò)展名不變? ? ? ? }? ? ]}```### `babel`的使用> 解析webpack默認(rèn)不能處理的JS```JavaScript// 1. 安裝babel-core babel-loader babel-plugin-transform-runtimenpm i babel-core babel-loader babel-plugin-transform-runtime --save-dev// 2. 安裝babel-preset-env babel-preset-stage-0npm i babel-preset-env babel-preset-stage-0 --save-dev// 3. 在webpack.config.js中的moudle節(jié)點(diǎn)中配置解析規(guī)則module:{? ? rules:[? ? ? ? {? ? ? ? ? ? test:/\.js$/,? ? ? ? ? ? use:'babel-loader',? ? ? ? ? ? exclude:/node_modules/ //排除掉node_modules文件夾,讓babel-loader不去解析node_modules文件夾中的js文件? ? ? ? }? ? ]}// 4. 在項(xiàng)目根目錄新建.babelrc文件,書寫如下配置{? ? "presets":["env","stage-0"],? ? "plugins":["transform-runtime"]}```## webpack中使用Vue```JavaScript// 1. 安裝vue vue-loader vue-template-compilernpm i vue --savenpm i vue-loader vue-template-compiler --save-dev// 2. webpack.config.js中配置解析規(guī)則module: {? ? rules: [? ? ? ? {? ? ? ? ? ? test:/\.vue$/,use:'vue-loader'? ? ? ? }? ? ]}// 3. 在index.html中加入一個(gè)需要Vue托管的區(qū)域
// 4. 新建App.vue組件? ?
vue組件
export default {}// 5. main.js中導(dǎo)入vue的包,渲染App.vue組件import Vue from 'vue'import App from './App.vue'new Vue({? ? el:'#app',? ? render:c=>c(App) //將App組件渲染到id為app的區(qū)域中})```## webpack 中集成vue-router```JavaScript// 1. 安裝vue-routernpm i vue-router --save// 2. 在main.js中導(dǎo)入vue-router并實(shí)例化路由添加路由規(guī)則import VueRouter from 'vue-router'Vue.use(VueRouter) // 保證在vue的組件中可以使用vue-router提供的組件 如const router = new VueRouter({? ? routes: [? ? ? ? {? ? ? ? ? ? path: '/login', component: login? ? ? ? }? ? ]})// 3. 將實(shí)例化的router綁定到Vuenew Vue({? ? el: '#app',? ? render: c => c(App),? ? router // 將router實(shí)例綁定到Vue上 以保證vue實(shí)例中可以訪問(wèn)$route $router等屬性})// 4. 在App.vue中添加路由占位router-view標(biāo)簽登錄```--- ## --save和--save-dev```// 項(xiàng)目開(kāi)發(fā)期間需要安裝的依賴// --save-dev 會(huì)將安裝的包名以及版本號(hào)記錄到package.json文件中的devDependencies節(jié)點(diǎn)中npm install webpack --save-dev 等價(jià)于 npm install webpack -D// 項(xiàng)目上線后需要安裝的依賴// --save 會(huì)將安裝的包名以及版本號(hào)記錄到package.json文件中的dependencies節(jié)點(diǎn)中npm i webpack --save 等價(jià)于 npm i webpack -Snpm i 會(huì)將所有在package.json文件中的devDependencies節(jié)點(diǎn)和dependencies節(jié)點(diǎn)內(nèi)所有的依賴包全部安裝一遍npm i --save-dev 只會(huì)下載devDependencies中的所有依賴包npm i --save 只會(huì)下載dependencies中的所有依賴包// 為什么安裝包的時(shí)候要區(qū)分 --save 和 --save-dev// 1. 使項(xiàng)目的閱讀更加友好绿店,便于理解項(xiàng)目結(jié)構(gòu)// 2. 安裝對(duì)應(yīng)階段的包時(shí)更加方便npm i cnpm -gcnpm ```## VSCode用戶代碼片段```json"Print to vue": {"prefix": "vuec","body": ["","? ? ? ? ? ","",

"export default{",

"? ? $2? ? ? ? ",

"}",

"","",

"$3? ? ? ? ? ? ",

""],"description": "create a vue template"}```## yarn的使用```// 1. 使用npm全局安裝yarnnpm i yarn -g// 2. 初始化命令yarn init -y// 3. 安裝包yarn add package-name // 會(huì)將安裝的包記錄到dependencies節(jié)點(diǎn)里面yarn add package-name --dev // 會(huì)將安裝的包記錄到devDependencies節(jié)點(diǎn)里面yarn global add package-name // 安裝全局包// 4. 刪除包yarn remove package-name// 5. 執(zhí)行命令yarn run devyarn global bin 查看全局包安裝的路徑```## vue-cli腳手架的使用```// 1. 安裝vue-cli腳手架npm i vue-cli -g// 2. 初始化項(xiàng)目模板vue init webpack 項(xiàng)目名稱eslint(語(yǔ)法規(guī)范化插件) 不要安裝? 當(dāng)安裝之后只能按照ESLint中規(guī)定的語(yǔ)法格式去書寫代碼e2e(測(cè)試框架) 不要安裝unit test(單元測(cè)試框架) 不要安裝// 3. 進(jìn)入項(xiàng)目安裝所有依賴npm i// 4. 運(yùn)行npm run devconfig/index.js中 17/18行改端口號(hào)和自動(dòng)打開(kāi)瀏覽器```## 將項(xiàng)目提交到碼云```// 1. 在項(xiàng)目文件夾初始化gitgit init// 2. 將代碼提交到暫存區(qū)git add .// 3. 提交代碼git commit -m '描述信息'// 4. 關(guān)聯(lián)遠(yuǎn)程分支git remote add origin https://gitee.com/UniverseKing/tes.git// 5. 推送到遠(yuǎn)程分支git push -u origin master// 6. 查看文件信息git status// 7. 查看loggit log --oenline// 8. 切換版本記錄git reset --hard 版本號(hào)```## vue-loader深度作用選擇器> 如果希望在父組件中去改變子組件中的樣式,有時(shí)候通過(guò)普通子類選擇器無(wú)法實(shí)現(xiàn),主要是由于添加了`scoped`屬性導(dǎo)致,`vue-loader`中提供了[深度作用選擇器](https://vue-loader.vuejs.org/zh-cn/features/scoped-css.html)可以實(shí)現(xiàn)> 這種問(wèn)題主要出現(xiàn)在使用第三方組件時(shí),需要改第三方組件的樣式時(shí)```CSS/*假設(shè).content是父組件中的類 img是子組件中的標(biāo)簽*//*css中使用>>>*/.content >>> img {}/*scss或者less中使用/deep/*/.content /deep/ img {}```## Promise> `Promise` 是異步編程的一種解決方案.簡(jiǎn)單說(shuō)就是一個(gè)容器,里面保存著某個(gè)未來(lái)才會(huì)結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果。從語(yǔ)法上說(shuō)假勿,`Promise` 是一個(gè)對(duì)象借嗽,可以從該對(duì)象獲取異步操作的消息。```Promise有幾種狀態(tài)?Promise有三種狀態(tài)promsie實(shí)例一被創(chuàng)建? 默認(rèn)就是pending狀態(tài)(表示異步操作進(jìn)行中)如果異步操作成功 狀態(tài)會(huì)從 pending 變成 fulfilled(表示異步操作成功)如果異步操作失敗 狀態(tài)會(huì)從 pending 變成 rejected(表示異步操作失敗)```### 基本用法```js// 1. 創(chuàng)建promise實(shí)例,在實(shí)例中執(zhí)行異步操作(比如發(fā)送網(wǎng)絡(luò)請(qǐng)求)// 2. 異步操作成功時(shí),調(diào)用reslove函數(shù)傳遞數(shù)據(jù)// 3. 異步操作失敗時(shí),調(diào)用reject函數(shù)傳遞錯(cuò)誤信息const promise = new Promise(function(resolve, reject) {// 異步操作// ... if (/* 異步操作成功 */){resolve(value);} else {reject(error);}});// 4. 使用promise實(shí)例then方法接收reslove或reject返回的數(shù)據(jù)promise.then(function(value) {// 此處數(shù)據(jù)即為reslove回來(lái)的數(shù)據(jù)? // success}, function(error) {// 此處數(shù)據(jù)即為reject回來(lái)的數(shù)據(jù)// failure});```### 網(wǎng)絡(luò)請(qǐng)求案例```js// 1. 定義一個(gè)使用promise封裝的請(qǐng)求函數(shù),函數(shù)內(nèi)部返回一個(gè)promise實(shí)例function fetch(){// 函數(shù)內(nèi)部返回一個(gè)promise實(shí)例return new Promise(function(reslove,reject){// 發(fā)送異步請(qǐng)求axios.get('http://www.lovegf.cn:8090/api/getlunbo').then(function(res){// 請(qǐng)求正常if(res.status == 1){reslove(res.data)}else{reject(res.error)}})})}// 2. 調(diào)用函數(shù)發(fā)送請(qǐng)求,通過(guò)Promise.prototype.then方法獲取resolve或reject出來(lái)的數(shù)據(jù)fetch().then(function(res){// res為reslove函數(shù)傳出的數(shù)據(jù)},function(err){// err為reject函數(shù)傳出的錯(cuò)誤})```### 解決回調(diào)地獄> 假設(shè)有三個(gè)請(qǐng)求A转培、B恶导、C,B請(qǐng)求需要依賴A請(qǐng)求的數(shù)據(jù),C請(qǐng)求需要依賴B請(qǐng)求的數(shù)據(jù).> > 傳統(tǒng)回調(diào)函數(shù)式寫法如下:```jsfunction dependices_fetch(){// A請(qǐng)求axios.get('A').then(function(res){if(res.status == 1){// B請(qǐng)求axios.get('B').then(function(res){if(res.status == 1){// C請(qǐng)求axios.get('C').then(function(res){// 請(qǐng)求完畢,執(zhí)行后續(xù)邏輯})}})}})}```> 這種代碼雖然能夠滿足業(yè)務(wù),但是代碼組織結(jié)構(gòu)非常不便于閱讀> > 通過(guò)Promise可以封裝代碼,使用鏈?zhǔn)椒绞浇鉀Q這種多個(gè)異步依賴的回調(diào)> > 如下:```jsfunction fetch(url){return new Promise(function(reslove,reject){axios.get(url).then(function(res){if(res.status == 1){reslove(res.data)}else{reject(res.error)}})})}//then方法內(nèi)部返回的promise實(shí)例reslove或reject出來(lái)的對(duì)象會(huì)在下一個(gè)then方法內(nèi)部得到fetch('A').then(function(res){// A 請(qǐng)求正常return fetch('B')// 這里返回一個(gè)新的promise實(shí)例,在后面的then中可以得到該實(shí)例reslove或reject出來(lái)的對(duì)象}).then(function(res){// B 請(qǐng)求正常return fetch('C')}).then(function(res){// C 請(qǐng)求正常// 請(qǐng)求完畢})```### 多個(gè)異步請(qǐng)求結(jié)果組合問(wèn)題> 假設(shè)有A、B浸须、C三個(gè)異步請(qǐng)求,需要三個(gè)請(qǐng)求的數(shù)據(jù)都回來(lái)之后,將數(shù)據(jù)整合后再渲染頁(yè)面,這種需求可以使用`Promise.all()`> > Promise.all方法用于將多個(gè) Promise 實(shí)例惨寿,包裝成一個(gè)新的 Promise 實(shí)例。```jsfunction fetch(url){return new Promise(function(reslove,reject){axios.get(url).then(function(res){if(res.status == 1){reslove(res.data)}else{reject(res.error)}})})}const p1 = fetch('A')const p2 = fetch('B')const p3 = fetch('C')const p = Promise.all([p1, p2, p3]);p.then(function(res){// res是一個(gè)數(shù)組,存放著p1,p2,p3的返回值})```## async 和 await 的使用> async 和 await 是ES7中新提供的兩個(gè)操作異步函數(shù)的關(guān)鍵字,本質(zhì)是對(duì)Promise進(jìn)一步的封裝> await 只能用在 async 定義的函數(shù)內(nèi)部,await 可以等待異步操作,并同步的得到異步操作的返回值```JavaScript// 1. 基于Promise的異步操作函數(shù)const fs = require('fs')function getFileByPath(fpath) {? ? return new Promise(function (resolve, reject) {? ? ? ? fs.readFile(fpath, 'utf-8', (err, dataStr) => {? ? ? ? ? ? if (err) return reject(err)? ? ? ? ? ? resolve(dataStr)? ? ? ? })? ? })}// 2. 基于 await 的異步依賴問(wèn)題(異步操作3依賴異步操作2,異步操作2依賴異步操作1)// 2.1 先使用async定義異步操作const start = async function(){// 2.2 在async內(nèi)部使用await 同步操作? ? ? ? const n1 = await getFileByPath('./1.txt')? ? const n2 = await getFileByPath('./2.txt')? ? const n3 = await getFileByPath('./3.txt')? ? // n3會(huì)等待n2 n2 會(huì)等待n1}```## axios 使用```JavaScript1. 安裝axiosnpm i axios qs --save2. 在main.js中導(dǎo)入axios,并將axios 掛載到Vue的原型中improt axios from 'axios'Vue.prototype.$axios = axios 3. get請(qǐng)求this.$axios.get('url').then(function(res){? ? // 注意:? ? // 1. 響應(yīng)的數(shù)據(jù)在res.data中? ? // 2. 在回調(diào)函數(shù)內(nèi)部的this 不是Vue實(shí)例(通常會(huì)將這個(gè)回調(diào)函數(shù)改成箭頭函數(shù))})4. post 請(qǐng)求// 注意:當(dāng)后臺(tái)要求傳遞的參數(shù)數(shù)據(jù)格式是 application/x-www-form-urlencode// 需要對(duì)參數(shù)進(jìn)行序列化// 使用qs模塊序列化qs.stringify({name:'zs',age:18})// 如果后臺(tái)要求的參數(shù)格式 是json格式 appliction/json 不需要序列化this.$axios.post('url',qs.stringify({name:'zs',age:18})).then(res=>{})5. 全局配置// 5.1 設(shè)置全局的請(qǐng)求根域名axios.defaults.baseURL = 'http://vue.studyit.io/';// 5.2 通過(guò)設(shè)置請(qǐng)求攔截器 配置post參數(shù)序列化axios.interceptors.request.use(function (config) {? ? // 統(tǒng)一處理post請(qǐng)求的參數(shù) 為application/x-www-form-urlencode? ? if (config.method == 'post') {? ? ? ? config.data = qs.stringify(config.data)? ? }? ? return config;});```## Vue插件開(kāi)發(fā)```JavaScript1. 單獨(dú)新建一個(gè)JS文件,在這個(gè)文件中導(dǎo)入需要制作成Vue插件的模塊import axios from 'axios'2. 在該模塊身上定義一個(gè)install函數(shù),可以接受兩個(gè)參數(shù),第一個(gè)用于接收Vue構(gòu)造函數(shù)第二個(gè)用于配置插件的一些選項(xiàng)axios.install = function(Vue,config){? ? // 1. 注冊(cè)全局組件? ? // 2. 將屬性掛載到原型中}3. 導(dǎo)出制作好的Vue插件模塊export default axios4. 使用插件// 能夠使用Vue.use的前提就是傳入的對(duì)象一定要有install方法// 調(diào)用Vue.use()的時(shí)候 會(huì)自動(dòng)去調(diào)用 傳入對(duì)象的 install方法import axios from '插件路徑'Vue.use(axios) // 會(huì)自動(dòng)調(diào)用axios的install方法```## 去除webpack打包后的嚴(yán)格模式> 在使用babel-loader的時(shí)候,會(huì)將所有轉(zhuǎn)換的代碼加上嚴(yán)格模式```JavaScript// 方法一: .babelrc文件中忽略不需要使用嚴(yán)格模式轉(zhuǎn)換的文件路徑 "ignore": [? ? "./src/js/mui/mui.min.js"? ]// 方法二: babel-loader配置中排除掉不需要嚴(yán)格模式轉(zhuǎn)換的文件{? ? test: /\.js$/,? ? use: 'babel-loader',? ? exclude: /mui\.min\.js/}// 方法三: babel-plugin-transform-remove-strict-mode 移除整個(gè)項(xiàng)目打包編譯時(shí)的嚴(yán)格模式// https://www.npmjs.com/package/babel-plugin-transform-remove-strict-mode1. 安裝babel-plugin-transform-remove-strict-modenpm install babel-plugin-transform-remove-strict-mode --save-dev2. babelrc中添加{? "plugins": ["transform-remove-strict-mode"]}```## 路由模式> 通過(guò)給`vue-router`配置`mode`屬性,可以指定URL路徑的顯示方式> `mode`屬性默認(rèn)值是`hash`,此時(shí)URL中有#,如:`http://localhost:8888/#/home`,實(shí)現(xiàn)方式即`window.location.hash`> 如果`mode`設(shè)置成`history`,此時(shí)URL路徑?jīng)]有#,如:`http://localhost:8888/home`,實(shí)現(xiàn)方式為`window.history`,這種方式同一個(gè)URL不能再其他頁(yè)面打開(kāi),需要服務(wù)端配置```JavaScriptnew VueRouter({? ? mode:'hash',? ? routes:[? ? ]})```## Vuex的使用> Vuex是一個(gè)狀態(tài)管理庫(kù),或者說(shuō)是專為Vue應(yīng)用程序開(kāi)發(fā)設(shè)計(jì)的狀態(tài)管理模式,它采用集中式存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài)删窒,并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測(cè)的方式發(fā)生變化裂垦。> 注:所謂狀態(tài),可以理解成項(xiàng)目中各個(gè)組件需要用到的數(shù)據(jù)。> Demo:https://gitee.com/UniverseKing/vuex-study### 初始化公共狀態(tài)``` JavaScript1. 安裝vuexnpm i vuex --save2. 入口文件中實(shí)例化Storeimport Vuex from 'vuex'Vue.use(Vuex)var store = new Vuex.Store({? // 1. 用于定義狀態(tài)(公共數(shù)據(jù)),類似于Vue實(shí)例中的data方法? state:{? ? ? msg:'初始化的數(shù)據(jù)'? },? // 2. 用于修改狀態(tài),類似于Vue實(shí)例中methods? mutations:{? ? ? change(state,arg){? ? ? ? ? // 更改狀態(tài)? ? ? ? ? state.msg = arg? ? ? }? },? // 3. 用于獲取數(shù)據(jù)(獲取數(shù)據(jù)之前可以進(jìn)行一些操作),類似于Vue實(shí)例中的過(guò)濾器和計(jì)算屬性? // getters 主要會(huì)用在跨組件傳值? // getters 中定義的方法內(nèi)部依賴的數(shù)據(jù)發(fā)生變化會(huì)自動(dòng)重新調(diào)用函數(shù)計(jì)算返回值? getters:{? ? ? fixmsg(state){? ? ? ? ? return `${state.msg}----處理后的數(shù)據(jù)`? ? ? }? },? // 4. actions和mutations都是定義對(duì)數(shù)據(jù)進(jìn)行操作的方法,mutations中都是同步方法,mutations中定義異步方法? // Action 提交的是 mutation肌索,而不是直接變更狀態(tài)蕉拢。所以需要修改狀態(tài)還是需要使用mutations中定義的方法? // 從網(wǎng)絡(luò)請(qǐng)求回來(lái)的數(shù)據(jù)需要保存到store? // 發(fā)送網(wǎng)絡(luò)請(qǐng)求的方法可以定義到actions中? // actions主要用于處理異步方法? actions:{? ? ? asyncchange(context,arg){? ? ? ? ? // 異步方法? ? ? ? ? setTimeout(() => {? ? ? ? ? ? ? context.commit('change',arg)? ? ? ? ? }, 3000)? ? ? }? }})3. 注入到Vue實(shí)例中new Vue({? ? el:'#app',? ? store})```### 使用狀態(tài)``` JavaScript1. 使用state中的數(shù)據(jù)JavaScript: this.$store.state.msgHTML: $store.state.msg2. 使用getters中的數(shù)據(jù)JavaScript: this.$store.getters.fixmsgHTML: $store.getters.msg```### 變更狀態(tài)(修改數(shù)據(jù))> 狀態(tài)的變更必須使用mutations中提供的方法進(jìn)行修改``` JavaScript1. 提交mutations中的變更方法this.$store.commit('change','我是被修改的數(shù)據(jù)')2. 異步提交actions中的變更方法this.$store.dispatch('asyncchange','我是被異步修改的數(shù)據(jù)')```### 使用輔助函數(shù)> 輔助函數(shù)可以直接將`state`,`getters`中的數(shù)據(jù)映射到Vue組件中的計(jì)算屬性上,可以將`mutations`,`actions`中的方法映射到組件中的`methods`中``` JavaScriptimport { mapState } from 'vuex'import { mapGetters } from 'vuex' import { mapMutations } from 'vuex'import { mapActions } from 'vuex'new Vue({? ? computed:mapGetters([? ? ? ? 'count'? ? ])})// ==>等價(jià)于new Vue({? ? computed:{? ? ? ? count(){? ? ? ? ? ? return this.$store.state['count']? ? ? ? }})```## vue-cli配置代理解決開(kāi)發(fā)階段跨域問(wèn)題```JavaScript// webpack.config.js配置文件導(dǎo)出對(duì)象中加入 devServer:{? ? // 代理跨域? ? proxy: {? ? ? '/api': {? ? ? ? target: 'http://vue.studyit.io/api', // 需要被代理的api根域名? ? ? ? changeOrigin: true, // 是否跨域? ? ? ? pathRewrite: {? ? ? ? ? '^/api': '' // 重寫(target中只有根域名時(shí)不需要配置此選項(xiàng))? ? ? ? }? ? ? }? ? }? }---------------------------// vue-cli中config/index.js中proxyTable: {? ? '/api': {? ? ? ? target: 'http://vue.studyit.io/api',? ? ? ? changeOrigin: true,? ? ? ? pathRewrite: {? ? ? ? ? '^/api': ''? ? ? ? }? ? }},```## webpack打包優(yōu)化> 目前項(xiàng)目中所有資源都會(huì)被打包到最終生成的一個(gè)build.js中,而build.js又被引用到index.html中,當(dāng)打開(kāi)index.html時(shí),首先需要從互聯(lián)網(wǎng)下載build.js,只有build.js全部下載完畢,瀏覽器的解析引擎才會(huì)開(kāi)始執(zhí)行該js代碼進(jìn)行代碼解析,當(dāng)解析引擎將代碼解析完畢后再交給渲染引擎開(kāi)始進(jìn)行渲染,所有工作幾乎都是同步執(zhí)行,當(dāng)build.js體積非常大時(shí),往往應(yīng)用的首頁(yè)加載速度比較慢,而且會(huì)看到白屏效果.可以從以下三方面進(jìn)行優(yōu)化首頁(yè)加載速度過(guò)慢問(wèn)題:1. 下載文件速度慢2. 解析JS比較慢3. 渲染比較慢### 服務(wù)端渲染(SSR)> SEO優(yōu)化> 在服務(wù)端先將JS進(jìn)行解析,解析完成之后生成HTML片段,再將HTML返回給前端,前端直接執(zhí)行渲染界面### 抽取CSS> 將項(xiàng)目中所有CSS抽取到單獨(dú)的文件中進(jìn)行加載,減小了build.js的體積,只要build.js下載完成即可開(kāi)始解析代碼> https://github.com/webpack-contrib/extract-text-webpack-plugin```JavaScript1. 安裝插件npm install extract-text-webpack-plugin --save-dev2. webpack.config.js中引入插件var ExtractTextPlugin = require('extract-text-webpack-plugin');3. 修改css-loader配置{? ? test: /\.css$/,? ? use: ExtractTextPlugin.extract({? ? ? ? fallback: "style-loader",? ? ? ? use: "css-loader"? ? })},{? ? test: /\.less$/,? ? use: ExtractTextPlugin.extract({? ? ? ? fallback: 'style-loader',? ? ? ? use: ['css-loader', 'sass-loader']? ? })}, // 處理 less 文件的 loader{? ? test: /\.scss$/,? ? use: ExtractTextPlugin.extract({? ? ? ? fallback: 'style-loader',? ? ? ? use: ['css-loader', 'sass-loader']? ? })}4. plugin配置中使用插件new ExtractTextPlugin('app.css')```### 分離第三方包> 將項(xiàng)目中引用的第三方JS代碼抽取到一個(gè)單獨(dú)的文件,也可以減少build.js的體積,還是只需要build.js下載完畢瀏覽器解析引擎即可開(kāi)始進(jìn)行解析,然后瀏覽器同時(shí)再去下載其他JS和CSS> 一般將發(fā)布階段所需要依賴的包全部進(jìn)行分離,即`package.json`中`dependencies`中的所有包進(jìn)行分離```JavaScript 1. 引入webpack和路徑處理模塊var webpack = require('webpack');var path = require('path');2. 修改入口文件entry: {? ? app: path.resolve(__dirname, 'src/main.js'),? ? // 需要分離的第三方包名寫在數(shù)組中? ? vendors: ['vue', 'vue-resource', 'vue-router', 'vuex', 'mint-ui', 'moment', 'vue-preview']},3. plugin中配置插件// 分離第三方包插件new webpack.optimize.CommonsChunkPlugin({? ? name: 'vendors',? ? filename: 'vendors.js' // 分離出來(lái)的js文件的名稱})```### 組件按需加載> vue-router提供的路由懶加載可以按需加載組件。> 特點(diǎn): 當(dāng)沒(méi)有訪問(wèn)到某個(gè)頁(yè)面路由時(shí),不去加載對(duì)應(yīng)的組件代碼,節(jié)約數(shù)據(jù)請(qǐng)求量,加快首頁(yè)DOM渲染速度```將import home from './components/Home.vue' 這種導(dǎo)入方式換成const home = () => import('../components/Home.vue');```## 路由導(dǎo)航鉤子函數(shù)> 在跳轉(zhuǎn)路由時(shí),進(jìn)行攔截,一般用于權(quán)限驗(yàn)證或登錄等操作> https://router.vuejs.org/zh-cn/advanced/navigation-guards.html### 路由獨(dú)享守衛(wèi)```JavaScriptconst router = new VueRouter({? routes: [? ? {? ? ? path: '/home',? ? ? component: HomeContainer,? ? ? // 進(jìn)入路由之前進(jìn)行攔截? ? ? beforeEnter: (to, from, next) => {? ? ? ? // from 從哪個(gè)路由來(lái)? ? ? ? // to 到哪個(gè)路由去? ? ? ? // 釋放守衛(wèi) 進(jìn)入下一個(gè)環(huán)節(jié)? ? ? }? ? }? ]})```### 全局守衛(wèi)```JavaScriptrouter.beforeEach((to, from, next) => {? })```## Cmder使用> window系統(tǒng)下增強(qiáng)型命令行工具,免安裝,解壓即用```JavaScript// 1. 將cmder.exe加入環(huán)境變量1. window + R 輸入 sysdm.cpl2. 選中 高級(jí) - 環(huán)境變量 - 系統(tǒng)變量 - Path3. 將cmder.exe所在目錄添加到Path中// 2. 天假右鍵菜單在cmder.exe所在目錄打開(kāi)命令行窗口 輸入 Cmder.exe /REGISTER ALL```## HBuilder打包> HBuilder打包 是將前端開(kāi)發(fā)的HTML/CSS/JS文件進(jìn)行打包,打包成可以直接安裝在手機(jī)上面的App,不借助瀏覽器就可以直接運(yùn)行```JavaScript1. 使用webpack將項(xiàng)目進(jìn)行打包,打包好的文件會(huì)在dist目錄webpack -p2. 打開(kāi)Hbuilder,新建移動(dòng)App項(xiàng)目,然后刪掉css/js/imgs文件夾和index.html文件3. 將使用webpack打包的dist目錄里面的文件全部拷貝到新建的移動(dòng)項(xiàng)目目錄中4. 選中HTML文件,點(diǎn)擊HBuilder導(dǎo)航上面的`發(fā)行`-`打原生安裝包`,直接下一步,選安卓公共證書-`打包`5. 在項(xiàng)目的`unpackage\release`中可以得到打包完畢的apk文件```## cordova打包> 直接在本地進(jìn)行打包> 需要電腦配置Java環(huán)境和Android環(huán)境 `gradle````JavaScript// 1. 安裝全局cordovanpm i cordova -g// 2. 創(chuàng)建cordova項(xiàng)目cordova create cordova_project// 3. 添加需要打包的平臺(tái)cordova platform add android// 4. 運(yùn)行或者打包c(diǎn)ordova run androidcordova build android```## vue-cli打包完成后1. 錯(cuò)誤信息:`postcss-svgo: Error in parsing SVG: Unquoted attribute value`? ? - 需要修改mui.css中的 **圖片引用** 單引號(hào)全部改成雙引號(hào)2. 提示必須使用服務(wù)器的方式打開(kāi),即使用localhost方式打開(kāi)? ? ? ? // 1. 安裝http-server? ? ? ? npm i http-server -g? ? ? ? // 2. 使用hs -o命令打開(kāi)index.html文件? ? ? ? hs -o3. 如果打包完成后希望直接用file協(xié)議打開(kāi),需要修改config/index.js 中的build下的`assetsPublicPath: '/'`換成`assetsPublicPath: './'`## Parcel使用```JavaScriptnpm i parcel-bundler -gparcel index.html```----> 項(xiàng)目地址:https://gitee.com/UniverseKing/vue_cms> [Vue組件](https://github.com/UniverseKing/awesome-github-vue#%E5%BA%94%E7%94%A8%E5%AE%9E%E4%BE%8B)## MVC 和 MVVM 區(qū)別> MVC從后臺(tái)業(yè)務(wù)邏輯對(duì)項(xiàng)目進(jìn)行分層開(kāi)發(fā) 數(shù)據(jù)流通是單向的,所有的數(shù)據(jù)流通都需要C進(jìn)行控制> MVVM是前端框架的一種設(shè)計(jì)模式,核心是雙向數(shù)據(jù)綁定,M和V可以直接進(jìn)行通信,VM只負(fù)責(zé)數(shù)據(jù)的綁定## 你平時(shí)開(kāi)發(fā)項(xiàng)目,有沒(méi)有遇到比較難的問(wèn)題,是怎么解決的?- vue-loader 深度作用選擇器(父組件中不能給v-html渲染出來(lái)的標(biāo)簽添加樣式)- babel-loader在編譯代碼時(shí),會(huì)給所有的代碼加上嚴(yán)格模式,不能使用call,callee,arguments..## 項(xiàng)目接口:> http://www.escook.cn:3000/> http://www.lovegf.cn:8899/## 真機(jī)調(diào)試```1. 手機(jī)開(kāi)一個(gè)WiFi熱點(diǎn)2. 使用電腦連接手機(jī)的WiFi熱點(diǎn)3. 在電腦上打開(kāi)CMD命令行 輸入ipconfig命令 查看的IP地址是 無(wú)線局域網(wǎng)下面的ipv4地址4. 在項(xiàng)目中使用--host IP地址 重啟項(xiàng)目5. 在手機(jī)中訪問(wèn)項(xiàng)目的IP地址```

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末驶社,一起剝皮案震驚了整個(gè)濱河市企量,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌亡电,老刑警劉巖届巩,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異份乒,居然都是意外死亡恕汇,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門或辖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)瘾英,“玉大人,你說(shuō)我怎么就攤上這事颂暇∪鼻矗” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵耳鸯,是天一觀的道長(zhǎng)湿蛔。 經(jīng)常有香客問(wèn)我,道長(zhǎng)县爬,這世上最難降的妖魔是什么阳啥? 我笑而不...
    開(kāi)封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮财喳,結(jié)果婚禮上察迟,老公的妹妹穿的比我還像新娘斩狱。我一直安慰自己,他們只是感情好扎瓶,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布所踊。 她就那樣靜靜地躺著,像睡著了一般概荷。 火紅的嫁衣襯著肌膚如雪污筷。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天乍赫,我揣著相機(jī)與錄音,去河邊找鬼陆蟆。 笑死雷厂,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的叠殷。 我是一名探鬼主播改鲫,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼林束!你這毒婦竟也來(lái)了像棘?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤壶冒,失蹤者是張志新(化名)和其女友劉穎缕题,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體胖腾,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡烟零,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了咸作。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锨阿。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖记罚,靈堂內(nèi)的尸體忽然破棺而出墅诡,到底是詐尸還是另有隱情,我是刑警寧澤桐智,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布末早,位于F島的核電站,受9級(jí)特大地震影響酵使,放射性物質(zhì)發(fā)生泄漏荐吉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一口渔、第九天 我趴在偏房一處隱蔽的房頂上張望样屠。 院中可真熱鬧,春花似錦、人聲如沸痪欲。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)业踢。三九已至栗柒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間知举,已是汗流浹背瞬沦。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留雇锡,地道東北人逛钻。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像锰提,于是被迫代替她去往敵國(guó)和親曙痘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1.基本綁定: new Vue( { el:'#elID', data:{ ...
    寒劍飄零閱讀 525評(píng)論 0 1
  • VUE介紹 Vue的特點(diǎn)構(gòu)建用戶界面立肘,只關(guān)注View層簡(jiǎn)單易學(xué)边坤,簡(jiǎn)潔、輕量谅年、快速漸進(jìn)式框架 框架VS庫(kù)庫(kù)茧痒,是一封裝...
    多多醬_DuoDuo_閱讀 2,687評(píng)論 1 17
  • Vue筆記六:Vue項(xiàng)目的性能優(yōu)化之路 我最近也經(jīng)常面試外包同事。面試的時(shí)候融蹂,總會(huì)有個(gè)問(wèn)題文黎,“你說(shuō)一下性能優(yōu)化的手...
    brandonxiang閱讀 6,805評(píng)論 5 22
  • 最近出現(xiàn)了一個(gè)好玩的App耸峭,是果殼網(wǎng)旗下在行的分答,用戶可以在上面自我介紹或描述擅長(zhǎng)領(lǐng)域淋纲,設(shè)置付費(fèi)問(wèn)答的價(jià)格劳闹,其他...
    大禹小漁閱讀 543評(píng)論 1 2
  • 【彭姐原創(chuàng)感悟013】 人真的有時(shí)候很賤,想給自己一點(diǎn)寬松的享受洽瞬,結(jié)果還不受用本涕。 昨天我開(kāi)始按我計(jì)劃的...
    739921988403閱讀 239評(píng)論 0 0