Vue
Vue基礎(chǔ)
Vue是基于M(數(shù)據(jù))V(視圖)VM(調(diào)度者)這種設(shè)計(jì)模式開(kāi)發(fā)出來(lái)的一個(gè)框架
MVC和MVVM之間的區(qū)別: MVC是單向通信 MVVM是雙向數(shù)據(jù)綁定
Vue基本的編碼步驟
- 引入Vue.js框架
<script src='./src/vue.js'></script>
- 在script標(biāo)簽部分創(chuàng)建一個(gè)Vue實(shí)例
var vm = new Vue({
el:'#app', // 通過(guò)選擇器找到一個(gè)讓vm實(shí)例監(jiān)管的區(qū)域
data:{
// 在data中定義的數(shù)據(jù)就是整個(gè)Vue實(shí)例可以用到的數(shù)據(jù)
msg:'hello'
}
})
- 在HTML結(jié)構(gòu)部分書(shū)寫(xiě)Vue代碼
<div id = 'app'>
{{msg}}
</div>
Vue指令
{{}}
:插值表達(dá)式,用于顯示data
中定義的數(shù)據(jù)v-text
:用于顯示data
中定義的普通文本數(shù)據(jù)
new Vue({
el:'#app',
data:{
msg:'普通文本數(shù)據(jù)'
}
})
<p v-text = 'msg'></p>
-
v-html
:用于顯示data
中定義的富文本數(shù)據(jù)(帶有HTML標(biāo)簽的文本)
new Vue({
el:'#app',
data:{
msg:'<p>富文本數(shù)據(jù)<p/>'
}
})
<div v-html = 'msg'></div>
-
v-bind
:動(dòng)態(tài)的給元素綁定屬性
new Vue({
el:'#app',
data:{
url:'http://www.baidu.com/'
}
})
<a v-bind:href = 'url'>百度</a>
-
v-for
:用于循環(huán)渲染元素進(jìn)行顯示
<div v-for = '(item,index) in list' :key = 'index'>
<!-- 數(shù)組中的每一項(xiàng) -->
{{item}}
<!-- 當(dāng)前項(xiàng)的索引 -->
{{index}}
</div>
-
v-model
:用于對(duì)表單元素實(shí)現(xiàn)雙向數(shù)據(jù)綁定,即模型中數(shù)據(jù)發(fā)生變化可以直接更新視圖,視圖中數(shù)據(jù)發(fā)生變化也可以影響到模型
<!-- v-model 指令只能用于表單元素和組件 常見(jiàn)于input/textarea/select標(biāo)簽上 -->
<input v-model = 'name'></input>
-
v-on
:綁定事件
<button v-on:click = 'clickHandle'></button>
new Vue({
el:'#app',
// methods中專(zhuān)門(mén)用來(lái)定義方法
methods:{
clickHandle:function(){
console.log('點(diǎn)擊事件被觸發(fā)了')
}
}
})
-
v-if
:控制元素的顯示隱藏
通過(guò)添加和移除元素控制元素顯示隱藏
如果元素初始狀態(tài)是隱藏的,而且不涉及頻繁顯示隱藏切換,推薦使用v-if
<div v-if = 'isshow'></div>
new Vue({
el:'#app',
data:{
isshow:true
}
})
-
v-show
:控制元素的顯示隱藏
通過(guò)給元素設(shè)置
display:none
的樣式控制元素顯示隱藏
如果元素涉及頻繁顯示隱藏切換,推薦使用v-show,性能會(huì)比v-if好
<div v-show = 'isshow'></div>
new Vue({
el:'#app',
data:{
isshow:true
}
})
使用樣式
使用class樣式
- 數(shù)組
<h1 :class="['red', 'thin']">這是一個(gè)邪惡的H1</h1>
- 數(shù)組中使用三元表達(dá)式
<h1 :class="['red', 'thin', isactive?'active':'']">這是一個(gè)邪惡的H1</h1>
- 數(shù)組中嵌套對(duì)象
<h1 :class="['red', 'thin', {'active': isactive}]">這是一個(gè)邪惡的H1</h1>
- 直接使用對(duì)象
<h1 :class="{red:true, italic:true, active:true, thin:true}">這是一個(gè)邪惡的H1</h1>
使用內(nèi)聯(lián)樣式
- 直接在元素上通過(guò)
:style
的形式腌闯,書(shū)寫(xiě)樣式對(duì)象
<h1 :style="{color: 'red', 'font-size': '40px'}">這是一個(gè)善良的H1</h1>
- 將樣式對(duì)象杠愧,定義到
data
中,并直接引用到:style
中
- 在data上定義樣式:
data: {
h1StyleObj: { color: 'red', 'font-size': '40px', 'font-weight': '200' }
}
- 在元素中,通過(guò)屬性綁定的形式,將樣式對(duì)象應(yīng)用到元素中:
<h1 :style="h1StyleObj">這是一個(gè)善良的H1</h1>
- 在
:style
中通過(guò)數(shù)組,引用多個(gè)data
上的樣式對(duì)象
- 在data上定義樣式:
data: {
h1StyleObj: { color: 'red', 'font-size': '40px', 'font-weight': '200' },
h1StyleObj2: { fontStyle: 'italic' }
}
- 在元素中,通過(guò)屬性綁定的形式,將樣式對(duì)象應(yīng)用到元素中:
<h1 :style="[h1StyleObj, h1StyleObj2]">這是一個(gè)善良的H1</h1>
ref獲取DOM
通過(guò)給元素設(shè)置ref屬性,然后使用this.$refs.屬性值得方式可以獲取到DOM
<div ref = 'dv'></div>
<button @click = 'getdv'>獲取div元素</button>
new Vue({
el:'#app',
methods:{
getdv(){
console.log(this.$refs.dv)
}
}
})
自定義指令
指令能夠幫助開(kāi)發(fā)者操作DOM,當(dāng)系統(tǒng)指令不能夠滿足需求時(shí),就可以使用自定義指令進(jìn)行DOM操作;將操作DOM的方式封裝成指令后首先可以重復(fù)使用,其次封裝成指令的過(guò)程是vue內(nèi)部提供的方法,這些方法在性能上比直接操作DOM元素要高犁罩。
Vue.directive('mycolor',{
// 指令的鉤子函數(shù)
inserted(el,binding){
// el 是指令所在的元素對(duì)象
// bingding是一個(gè)對(duì)象
// binding.value // red 指令等號(hào)后面表達(dá)式的值 也就是變量的值
// binding.expression // 指令等號(hào)后面的表達(dá)式 本質(zhì)就是一個(gè)變量
}
})
new Vue({
el:'#app',
data:{
color:'red'
}
})
<div v-mycolor = "color"></div>
自定義過(guò)濾器
在數(shù)據(jù)展示之前,對(duì)原始數(shù)據(jù)進(jìn)行處理并返回處理后的數(shù)據(jù)進(jìn)行展示,不改變?cè)紨?shù)據(jù)
過(guò)濾器只能用在插值表達(dá)式和屬性綁定(v-bind)中
Vue.filter('過(guò)濾器名稱(chēng)',function(data,arg){
// data是原始數(shù)據(jù),即管道符前面的數(shù)據(jù)
// arg 是使用過(guò)濾器時(shí)傳遞的參數(shù)
// 1. 對(duì)原始數(shù)據(jù)進(jìn)行邏輯處理
// 2. 處理完成后進(jìn)行return
return `處理完的數(shù)據(jù)`
})
<div>{{原始數(shù)據(jù) | 過(guò)濾器名稱(chēng)(參數(shù))}}</div>
計(jì)算屬性computed
用于定義一種可以隨著所依賴(lài)數(shù)據(jù)發(fā)生變化的屬性
new Vue({
el:'#app',
// data中定義普通屬性
data:{
msg:''
},
// compluted中定義的函數(shù)名就是計(jì)算屬性 屬性的值是該函數(shù)的返回值
// 計(jì)算屬性的值會(huì)隨著依賴(lài)數(shù)據(jù)的變化而變化
// 例如this.msg被修改 則comMsg的值也會(huì)重新計(jì)算
compluted:{
comMsg(){
return this.msg
}
}
})
監(jiān)聽(tīng)器 watch
監(jiān)聽(tīng)data中定義的數(shù)據(jù)的變化
new Vue({
el:'#app',
data:{
msg:'被監(jiān)聽(tīng)數(shù)據(jù)',
obj:{
name:'zxx'
}
},
watch:{
msg(newVal,oldVal){
// 根據(jù)數(shù)據(jù)變化做相關(guān)邏輯處理
// newVal 變化后的值
// oldVal 變化前的值
},
// 當(dāng)被監(jiān)聽(tīng)的數(shù)據(jù)是復(fù)雜數(shù)據(jù)類(lèi)型時(shí),一般需要用深度監(jiān)聽(tīng)才可以監(jiān)聽(tīng)到復(fù)雜數(shù)據(jù)類(lèi)型內(nèi)部的數(shù)據(jù)變化
obj:{
handler(newVal,oldVal){
},
deep:true
}
}
})
axios發(fā)送請(qǐng)求
axios是一個(gè)基于promise的請(qǐng)求庫(kù),可以在node環(huán)境和瀏覽器環(huán)境中使用齐蔽。
- 引入axios
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
- get請(qǐng)求
axios.get('url').then(function(res){
// res.data即后臺(tái)返回的數(shù)據(jù)
console.log(res.data)
})
- post請(qǐng)求
axios.post('url',{
username:'zxx',
password:'123456'
}).then(function(res){
// res.data即后臺(tái)返回的數(shù)據(jù)
console.log(res.data)
})
vue過(guò)渡動(dòng)畫(huà)
vue中的過(guò)渡動(dòng)畫(huà)只能作用于使用
v-if
、v-show
控制的元素已經(jīng)動(dòng)態(tài)組件中
使用css類(lèi)實(shí)現(xiàn)動(dòng)畫(huà)
1.使用transition
標(biāo)簽將需要實(shí)現(xiàn)動(dòng)畫(huà)的元素包裹起來(lái)
<button @click = 'isshow = !isshow'></button>
<transition>
<div v-if = 'isshow'>御劍乘風(fēng)來(lái)</div>
</transition>
- 使用css類(lèi)控制動(dòng)畫(huà)效果
/* 進(jìn)入動(dòng)畫(huà)就是一個(gè)元素從隱藏到顯示這個(gè)過(guò)程需要執(zhí)行的動(dòng)畫(huà) */
/* 離開(kāi)動(dòng)畫(huà)是一個(gè)元素從顯示到隱藏這個(gè)過(guò)程需要執(zhí)行的動(dòng)畫(huà) */
/* 元素執(zhí)行進(jìn)入動(dòng)畫(huà)之前的狀態(tài) */
.fade-enter {
transform: translateX(100px)
}
/* 元素執(zhí)行進(jìn)入動(dòng)畫(huà)的過(guò)程中持續(xù)添加到元素的狀態(tài) */
/* 在這個(gè)類(lèi)中通常都是書(shū)寫(xiě)元素需要執(zhí)行的動(dòng)畫(huà)效果 */
.fade-enter-active {
transition: all 0.2s ease
}
/* 元素執(zhí)行進(jìn)入動(dòng)畫(huà)結(jié)束狀態(tài) */
/* 在這個(gè)類(lèi)中通常是用來(lái)設(shè)置元素執(zhí)行動(dòng)畫(huà)完畢之后的樣式 */
.fade-enter-to {
transform: translateX(0)
}
/* 元素執(zhí)行離開(kāi)動(dòng)畫(huà)之前需要設(shè)定的樣式 */
.fade-leave {
transform: translateX(0)
}
/* 元素執(zhí)行離開(kāi)動(dòng)畫(huà)的過(guò)程中持續(xù)添加到元素身上 */
.fade-leave-active {
transition: all 0.5s ease
}
/* 元素中心離開(kāi)動(dòng)畫(huà)過(guò)程中持續(xù)添加到元素身上 */
.fade-leave-to {
transform: translateX(100px)
}
使用animate.css實(shí)現(xiàn)動(dòng)畫(huà)
1.使用transition
標(biāo)簽將需要實(shí)現(xiàn)動(dòng)畫(huà)的元素包裹起來(lái)
<button @click = 'isshow = !isshow'></button>
<transition>
<div v-if = 'isshow'>御劍乘風(fēng)來(lái)</div>
</transition>
- 使用animate.css提供的類(lèi)名設(shè)置動(dòng)畫(huà)
<transition
enter-active-class = 'animate fadeIn'
leave-active-class = 'animate fadeOut'
>
<div v-if = 'isshow'>御劍乘風(fēng)來(lái)</div>
</transition>
使用動(dòng)畫(huà)的鉤子函數(shù)實(shí)現(xiàn)
// 1. 將需要實(shí)現(xiàn)動(dòng)畫(huà)的元素使用transition標(biāo)簽包裹起來(lái)
<transition>
<div>我是需要過(guò)渡動(dòng)畫(huà)的元素</div>
</transition>
// 2. 在transition上注冊(cè)實(shí)現(xiàn)動(dòng)畫(huà)的鉤子函數(shù),入場(chǎng)動(dòng)畫(huà)三個(gè),出場(chǎng)動(dòng)畫(huà)三個(gè)
<transition
@before-enter = 'beforeEnter'
@enter = 'enter'
@after-enter = 'afterEnter'
@before-leave = 'beforeLeave'
@leave = 'leave'
@after-leave = 'afterLeave'
>
<div>我是需要過(guò)渡動(dòng)畫(huà)的元素</div>
</transition>
// 3. 在vue實(shí)例的methods中定義鉤子函數(shù)
new Vue({
el:'#app',
data:{},
methods:{
// 入場(chǎng)動(dòng)畫(huà)初始狀態(tài)設(shè)置
beforeEnter(){
// 一般使用JS設(shè)置執(zhí)行動(dòng)畫(huà)元素的初始位置和其他樣式屬性
},
// 入場(chǎng)動(dòng)畫(huà)持續(xù)過(guò)程
enter(el,done){
// 1. 固定寫(xiě)法 迫使瀏覽器重繪 刷新動(dòng)畫(huà)
el.offsetWidth
// 2. 一般設(shè)置執(zhí)行動(dòng)畫(huà)元素最終的位置和其他樣式屬性
// 3. 固定寫(xiě)法 調(diào)用afterEnter函數(shù)
done()
},
// 入場(chǎng)動(dòng)畫(huà)結(jié)束狀態(tài)
afterEnter(){
// 設(shè)置動(dòng)畫(huà)元素回到初始狀態(tài)
},
// 出場(chǎng)動(dòng)畫(huà)初始狀態(tài)
beforeLeave(){
},
// 出場(chǎng)動(dòng)畫(huà)持續(xù)狀態(tài)
leave(){
},
// 出場(chǎng)動(dòng)畫(huà)結(jié)束狀態(tài)
afterLeave(){
}
}
})
組件
組件就是對(duì)視圖的封裝,方便重復(fù)使用
模塊是對(duì)功能邏輯的封裝
注意:
- 定義組件時(shí)如果使用的是駝峰命名,那么使用組件時(shí)需要將駝峰的大寫(xiě)字母轉(zhuǎn)成小寫(xiě),并且用-連接兩個(gè)單詞
Vue.component('myCom',{
template:'<div>我是一個(gè)駝峰命名的組件</div>'
})
// 使用
<my-com></my-com>
- 組件的
template
屬性中的模版內(nèi)部如果有多個(gè)元素,必須被包含在唯一的一個(gè)根元素中
<template>
<div>
<p>我是p元素</p>
<span>我是span元素</span>
</div>
</template>
- 子組件使用
components
屬性進(jìn)行定義,定義好的子組件只能在父組件的模板中使用
<template id='father'>
<div>
<son></son>
</div>
</template>
// 父組件
Vue.component('father',{
template:'#father',
components:{
// 子組件
son:{
template:'<div>我是son組件</div>'
}
}
})
組件的三種定義方式
-
vue.extend()
定義
// 1. 使用vue.extend()定義組件模板
var dv = Vue.extend({
template:'<div>我是一個(gè)組件</div>'
})
// 2. 使用Vue.component()注冊(cè)組件
Vue.component('com',dv)
// 3. 在Vue托管區(qū)域像使用普通HTML標(biāo)簽一樣使用組件
<com></com>
-
vue.component()
定義
// 1. 使用Vue.component定義組件
Vue.component('com',{
template:'<div><p>我是一個(gè)組件中的元素</p><span>我也是組件中的元素</span></div>'
})
// 2. 使用組件
<com></com>
- 使用
template
標(biāo)簽定義模板
// 1. 使用Vue.component定義組件床估,并且使用選擇器選擇模板
Vue.component('com',{
template:'#temp'
})
// 2. 使用template標(biāo)簽定義模板,并且給template標(biāo)簽添加id
<template id='tmpl'>
<div>
<p>我是p元素</p>
<span>我是span元素</span>
</div>
</template>
// 3. 使用組件
<com></com>
is屬性和component實(shí)現(xiàn)組件切換
// comname 是哪個(gè)組件名,則component就會(huì)被渲染成哪個(gè)組件
// component 就是一個(gè)占位標(biāo)簽
<component :is='comname'></component>
new Vue({
el:'#app',
comname:'login'
})
父子組件傳值
父向子傳值
// 1. 先在父組件中定義好要傳遞的數(shù)據(jù)
new Vue({
el:'#app'
data:{
msg:'我是要傳遞給子組件的數(shù)據(jù)'
},
components:{
son:{
template:'<div>我是子組件{{message}}</div>',
props:['message']
}
}
})
// 2. 在父組件中使用子組件的時(shí)候,用綁定屬性的方式將父組件中的數(shù)據(jù)傳遞給子組件
<div id='app'>
<son v-bind:message = 'msg'></son>
</div>
// 3. 在子組件中定義一個(gè)props屬性,該屬性是一個(gè)數(shù)組,數(shù)組中定義用于接收傳過(guò)來(lái)的變量含滴。這個(gè)變量
// 和第二步綁定的這個(gè)屬性同名
son:{
template:'<div>我是子組件</div>',
props:['message']
}
子向父?jìng)髦?/h4>
發(fā)布訂閱者 設(shè)計(jì)模式
// 1. 定義好父子組件,定義好子組件需要傳遞給父組件的數(shù)據(jù)
new Vue({
el:'#app'
components:{
son:{
template:'<div>我是子組件{{message}}</div>',
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è)事件,事件名稱(chēng)和子組件觸發(fā)的方法名同名
<div id='app'>
<son @func = 'getmsg'></son>
</div>
// 4. 在父組件的methods中定義一個(gè)事件處理函數(shù)
methods:{
getmsg:function(data){
// data就是子組件傳過(guò)來(lái)的數(shù)據(jù)
}
}
非父子組件傳值
使用event bus(事件總線):利用一個(gè)共享的vue實(shí)例對(duì)象來(lái)進(jìn)行數(shù)據(jù)的傳遞. 同時(shí)采用的是 發(fā)布-訂閱者模式
// componentA componentB進(jìn)行數(shù)據(jù)傳遞(B->A)
// **定義一個(gè)公有的Vue實(shí)例,保證兩個(gè)組件都能夠使用,一般在一個(gè)單獨(dú)的js文件中導(dǎo)出一個(gè)Vue實(shí)例,
然后在componentA和componentB組件中導(dǎo)入該實(shí)例進(jìn)行使用**
export default var vm = new Vue();
// componentB:(B組件時(shí)需要傳遞數(shù)據(jù)的組件)
// 1. 進(jìn)行事件的發(fā)布(注冊(cè))
vm.$emit('事件名稱(chēng)','需要傳遞的數(shù)據(jù)')
// 2. 事件的觸發(fā)(用于發(fā)布事件)
send(){
this.$emit('事件名稱(chēng)','需要傳遞的數(shù)據(jù)')
}
// componentA:(A組件是接收數(shù)據(jù)的組件)
// 1. 訂閱事件
vm.$on('事件名稱(chēng)',function(data){
// 此處的data就是 發(fā)布組件中傳遞過(guò)來(lái)的數(shù)據(jù)
})
生命周期鉤子函數(shù)
回調(diào)函數(shù):一個(gè)函數(shù)被當(dāng)做參數(shù)進(jìn)行傳遞的時(shí)候,稱(chēng)作這個(gè)函數(shù)為回調(diào)函數(shù)
構(gòu)造函數(shù):一個(gè)函數(shù)被new 關(guān)鍵字引導(dǎo)執(zhí)行的時(shí)候,稱(chēng)作這個(gè)函數(shù)為構(gòu)造函數(shù)
鉤子函數(shù): 一個(gè)應(yīng)用程序或者框架內(nèi)部提前定義好的一批函數(shù),這些函數(shù)會(huì)在特定的時(shí)間段自動(dòng)執(zhí)行
生命周期: 一個(gè)程序會(huì)存在初始化 - 運(yùn)行 - 銷(xiāo)毀等階段,這些階段統(tǒng)稱(chē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í)例銷(xiāo)毀之前,實(shí)例上面的各種屬性和方法都還可以正常訪問(wèn),通常可以在這里手動(dòng)回收一些頁(yè)面沒(méi)有被釋放的變量,比如清楚定時(shí)器的操作丐巫。
beforeDestroy(){},
// 實(shí)例已經(jīng)從內(nèi)存中被銷(xiāo)毀
destroyed(){}
})
路由
后端路由:監(jiān)聽(tīng)不同的URI(地址),做不同的請(qǐng)求處理
前端路由:是專(zhuān)門(mén)為SPA(單頁(yè)應(yīng)用程序)服務(wù),也是監(jiān)聽(tīng)不同的地址,做頁(yè)面的切換
基本使用步驟
1. 創(chuàng)建路由對(duì)象并配置路由規(guī)則
// 1.1 創(chuàng)建組件模板對(duì)象
var login = {
template:'<div>登錄</div>'
}
var register = {
template:'<div>注冊(cè)</div>'
}
// 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. 使用<router-view>進(jìn)行占位
<div id='app'>
<router-view></router-view>
<div>
3. 使用<router-link>設(shè)置跳轉(zhuǎn)路徑
<router-link to='/login'>登錄</router-link>
路由傳參
query傳參
// 1. 在跳轉(zhuǎn)路徑后面使用查詢(xún)字符串拼接參數(shù)
<router-link to = '/login?name=zs$age=18'>登錄</router-link>
// 2. 在路由對(duì)應(yīng)的組件內(nèi)部使用`this.$route.query`獲取參數(shù)
this.$route.query.name // zs
this.$route.query.id // 18
params傳參
// 1. 更改路由規(guī)則用于匹配參數(shù)
new VueRouter({
routes:[
// :id用于匹配/login/13后面的參數(shù)13
{path:'/login/:id',component:login}
]
})
// 2. 在跳轉(zhuǎn)路徑后面使用/拼接參數(shù)
<router-link to = '/login/13'>登錄</router-link>
// 3. 在路由對(duì)應(yīng)組件內(nèi)部使用`this.$route.params`獲取參數(shù)
var login = {
template:'<div>登錄組件{{this.$route.params.id}}</div>',
created(){
console.log(this.$route.params.id) // 獲取到的就是13
}
}
嵌套路由
// 1. 在父路由內(nèi)部使用children屬性配置子路由規(guī)則,子路由規(guī)則對(duì)象中的path屬性不要 '/'
// 2. 在父路由規(guī)則對(duì)應(yīng)的組件模板中添加router-view用于顯示子路由規(guī)則對(duì)應(yīng)的組件
// 3. 在<router-link>中設(shè)置跳轉(zhuǎn)路徑(將父路由和子路由的path拼接)
webpack的學(xué)習(xí)
什么是webpack? 一個(gè)基于Node的前端構(gòu)建工具,可以實(shí)現(xiàn)對(duì)項(xiàng)目的打包(構(gòu)建),主要解決文件(模塊)之間的依賴(lài),高級(jí)代碼的轉(zhuǎn)譯,文件(模塊)的合并和壓縮等問(wèn)題蛙吏。
基本使用
-
webpack3.~
版本安裝使用
// 1. 全局安裝webpack
npm i webpack@3.10.0 -g
// 2. 使用
webpack 入口文件 輸出文件
webpack ./src/main.js ./dist/build.js
-
webpack4.~
版本安裝使用
// 1. 全局安裝webpack
npm i webpack -g
npm i webpack-cli -g
// 2. 使用
webpack 入口文件 -o 輸出文件 --mode development/production
webpack ./src/main.js -o ./dist/build.js --mode development
webpack配置文件使用
webpack4.x不需要定義入口和輸出參數(shù),默認(rèn)src/main.js
為入口文件,dist/index.js
為輸出文件鞋吉。
但是需要配置模式參數(shù)mod
// 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' // 輸出文件名稱(chēng)
}
// mode:"development" // webpack4.x配置此選項(xiàng)
}
// 2. 執(zhí)行打包命令
webpack
webpack-dev-server的使用
幫助在項(xiàng)目根目錄搭建一個(gè)服務(wù)器,該服務(wù)器可以幫我們托管代碼,同時(shí)監(jiān)聽(tīng)所有文件的變化然后自動(dòng)執(zhí)行webpack編譯命令以及自動(dòng)刷新瀏覽器
命令行方式
--hot
: 熱更新,可以局部更新文件
--open
: 自動(dòng)打開(kāi)瀏覽器
--port
: 配置端口號(hào)
--inline
: 刷新瀏覽器
// 1. 局部安裝webpack-dev-server和webpack
npm i webpack-dev-server webpack --save-dev
// 2. 在package.json的scripts節(jié)點(diǎn)中添加啟動(dòng)命令
"scripts":{
"dev":"webpack-dev-server --inline --open --hot--port 8888"
}
// 3. 在項(xiàng)目根目錄運(yùn)行項(xiàng)目
npm run dev
配置文件方式
// 1. 在webpack.config.js配置文件中添加如下配置
devServer:{
open: true,
port: 8888,
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文件
// 1. 安裝html-webpack-plugin
npm i html-webpack-plugin --save-dev
// 2. 在webpack.config.js中的plugins節(jié)點(diǎn)中配置插件
// 2.1 導(dǎo)入html-webpack-plugin
const htmlWebpackPlugin = require('html-webpack-plugin')
// 2.2 配置插件
plugins:[
new htmlWebpackPlugin({
template:path.join(__dirname,'./src/index.html'),// 需要生成的HTML的模板文件
filename:'index.html' // 生成的HTML文件的名稱(chēng)
})
]
css-loader
處理CSS文件
解析處理文件后綴名為.css的文件
// 1. 安裝style-loader css-loader
npm 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的文件
// 1. 安裝less less-loader
npm 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的文件
// 1. 安裝node-sass sass-loader
npm 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)、音視頻等資源文件
// 1. 安裝file-loader ulr-loader
npm 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)的文件名稱(chēng)以8位hash值和原來(lái)的名稱(chēng)進(jìn)行拼接,文件擴(kuò)展名不變
}
]
}
babel
的使用
解析webpack默認(rèn)不能處理的JS
// 1. 安裝babel-core babel-loader babel-plugin-transform-runtime
npm i babel-core babel-loader babel-plugin-transform-runtime --save-dev
// 2. 安裝babel-preset-env babel-preset-stage-0
npm 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文件,書(shū)寫(xiě)如下配置
{
"presets":["env","stage-0"],
"plugins":["transform-runtime"]
}
webpack中使用Vue
// 1. 安裝vue vue-loader vue-template-compiler
npm i vue --save
npm 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ū)域
<div id="app"></div>
// 4. 新建App.vue組件
<template>
<div>vue組件</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
// 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
// 1. 安裝vue-router
npm i vue-router --save
// 2. 在main.js中導(dǎo)入vue-router并實(shí)例化路由添加路由規(guī)則
import VueRouter from 'vue-router'
Vue.use(VueRouter) // 保證在vue的組件中可以使用vue-router提供的組件 如<router-view> <router-link>
const router = new VueRouter({
routes: [
{
path: '/login', component: login
}
]
})
// 3. 將實(shí)例化的router綁定到Vue
new Vue({
el: '#app',
render: c => c(App),
router // 將router實(shí)例綁定到Vue上 以保證vue實(shí)例中可以訪問(wèn)$route $router等屬性
})
// 4. 在App.vue中添加路由占位router-view標(biāo)簽
<router-link to = "/login">登錄<router-link>
<router-view></router-view>
--save和--save-dev
// 項(xiàng)目開(kāi)發(fā)期間需要安裝的依賴(lài)
// --save-dev 會(huì)將安裝的包名以及版本號(hào)記錄到package.json文件中的devDependencies節(jié)點(diǎn)中
npm install webpack --save-dev 等價(jià)于 npm install webpack -D
// 項(xiàng)目上線后需要安裝的依賴(lài)
// --save 會(huì)將安裝的包名以及版本號(hào)記錄到package.json文件中的dependencies節(jié)點(diǎn)中
npm i webpack --save 等價(jià)于 npm i webpack -S
npm i 會(huì)將所有在package.json文件中的devDependencies節(jié)點(diǎn)和dependencies節(jié)點(diǎn)內(nèi)所有的依賴(lài)包全部安裝一遍
npm i --save-dev 只會(huì)下載devDependencies中的所有依賴(lài)包
npm i --save 只會(huì)下載dependencies中的所有依賴(lài)包
// 為什么安裝包的時(shí)候要區(qū)分 --save 和 --save-dev
// 1. 使項(xiàng)目的閱讀更加友好谓着,便于理解項(xiàng)目結(jié)構(gòu)
// 2. 安裝對(duì)應(yīng)階段的包時(shí)更加方便
vue-cli腳手架的使用
// 1. 安裝vue-cli腳手架
npm i vue-cli -g
// 2. 初始化項(xiàng)目模板
vue init webpack 項(xiàng)目名稱(chēng)
eslint(語(yǔ)法規(guī)范化插件) 不要安裝 當(dāng)安裝之后只能按照ESLint中規(guī)定的語(yǔ)法格式去書(shū)寫(xiě)代碼
e2e(測(cè)試框架) 不要安裝
unit test(單元測(cè)試框架) 不要安裝
// 3. 進(jìn)入項(xiàng)目安裝所有依賴(lài)
npm i
// 4. 運(yùn)行
npm run dev
config/index.js中 17/18行改端口號(hào)和自動(dòng)打開(kāi)瀏覽器
Vuex的使用
Vuex是一個(gè)狀態(tài)管理庫(kù),或者說(shuō)是專(zhuān)為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ù)赊锚。
初始化公共狀態(tài)
1. 安裝vuex
npm i vuex --save
2. 入口文件中實(shí)例化Store
import Vuex from 'vuex'
Vue.use(Vuex)
var store = new Vuex.Store({
// 1. 用于定義狀態(tài)(公共數(shù)據(jù)),類(lèi)似于Vue實(shí)例中的data方法
state:{
msg:'初始化的數(shù)據(jù)'
},
// 2. 用于修改狀態(tài),類(lèi)似于Vue實(shí)例中methods
mutations:{
change(state,arg){
// 更改狀態(tài)
state.msg = arg
}
},
// 3. 用于獲取數(shù)據(jù)(獲取數(shù)據(jù)之前可以進(jìn)行一些操作),類(lèi)似于Vue實(shí)例中的過(guò)濾器和計(jì)算屬性
// getters 主要會(huì)用在跨組件傳值
// getters 中定義的方法內(nèi)部依賴(là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)
1. 使用state中的數(shù)據(jù)
JavaScript: this.$store.state.msg
HTML: $store.state.msg
2. 使用getters中的數(shù)據(jù)
JavaScript: this.$store.getters.fixmsg
HTML: $store.getters.msg
變更狀態(tài)(修改數(shù)據(jù))
狀態(tài)的變更必須使用mutations中提供的方法進(jìn)行修改
1. 提交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
中,然后在組件中就可以直接以屬性和方法的方式去使用數(shù)據(jù)和方法舷蒲。
import { 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']
}
})
發(fā)布訂閱者 設(shè)計(jì)模式
// 1. 定義好父子組件,定義好子組件需要傳遞給父組件的數(shù)據(jù)
new Vue({
el:'#app'
components:{
son:{
template:'<div>我是子組件{{message}}</div>',
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è)事件,事件名稱(chēng)和子組件觸發(fā)的方法名同名
<div id='app'>
<son @func = 'getmsg'></son>
</div>
// 4. 在父組件的methods中定義一個(gè)事件處理函數(shù)
methods:{
getmsg:function(data){
// data就是子組件傳過(guò)來(lái)的數(shù)據(jù)
}
}
使用event bus(事件總線):利用一個(gè)共享的vue實(shí)例對(duì)象來(lái)進(jìn)行數(shù)據(jù)的傳遞. 同時(shí)采用的是 發(fā)布-訂閱者模式
// componentA componentB進(jìn)行數(shù)據(jù)傳遞(B->A)
// **定義一個(gè)公有的Vue實(shí)例,保證兩個(gè)組件都能夠使用,一般在一個(gè)單獨(dú)的js文件中導(dǎo)出一個(gè)Vue實(shí)例,
然后在componentA和componentB組件中導(dǎo)入該實(shí)例進(jìn)行使用**
export default var vm = new Vue();
// componentB:(B組件時(shí)需要傳遞數(shù)據(jù)的組件)
// 1. 進(jìn)行事件的發(fā)布(注冊(cè))
vm.$emit('事件名稱(chēng)','需要傳遞的數(shù)據(jù)')
// 2. 事件的觸發(fā)(用于發(fā)布事件)
send(){
this.$emit('事件名稱(chēng)','需要傳遞的數(shù)據(jù)')
}
// componentA:(A組件是接收數(shù)據(jù)的組件)
// 1. 訂閱事件
vm.$on('事件名稱(chēng)',function(data){
// 此處的data就是 發(fā)布組件中傳遞過(guò)來(lái)的數(shù)據(jù)
})
回調(diào)函數(shù):一個(gè)函數(shù)被當(dāng)做參數(shù)進(jìn)行傳遞的時(shí)候,稱(chēng)作這個(gè)函數(shù)為回調(diào)函數(shù)
構(gòu)造函數(shù):一個(gè)函數(shù)被new 關(guān)鍵字引導(dǎo)執(zhí)行的時(shí)候,稱(chēng)作這個(gè)函數(shù)為構(gòu)造函數(shù)
鉤子函數(shù): 一個(gè)應(yīng)用程序或者框架內(nèi)部提前定義好的一批函數(shù),這些函數(shù)會(huì)在特定的時(shí)間段自動(dòng)執(zhí)行
生命周期: 一個(gè)程序會(huì)存在初始化 - 運(yùn)行 - 銷(xiāo)毀等階段,這些階段統(tǒng)稱(chē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í)例銷(xiāo)毀之前,實(shí)例上面的各種屬性和方法都還可以正常訪問(wèn),通常可以在這里手動(dòng)回收一些頁(yè)面沒(méi)有被釋放的變量,比如清楚定時(shí)器的操作丐巫。
beforeDestroy(){},
// 實(shí)例已經(jīng)從內(nèi)存中被銷(xiāo)毀
destroyed(){}
})
后端路由:監(jiān)聽(tīng)不同的URI(地址),做不同的請(qǐng)求處理
前端路由:是專(zhuān)門(mén)為SPA(單頁(yè)應(yīng)用程序)服務(wù),也是監(jiān)聽(tīng)不同的地址,做頁(yè)面的切換
1. 創(chuàng)建路由對(duì)象并配置路由規(guī)則
// 1.1 創(chuàng)建組件模板對(duì)象
var login = {
template:'<div>登錄</div>'
}
var register = {
template:'<div>注冊(cè)</div>'
}
// 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. 使用<router-view>進(jìn)行占位
<div id='app'>
<router-view></router-view>
<div>
3. 使用<router-link>設(shè)置跳轉(zhuǎn)路徑
<router-link to='/login'>登錄</router-link>
// 1. 在跳轉(zhuǎn)路徑后面使用查詢(xún)字符串拼接參數(shù)
<router-link to = '/login?name=zs$age=18'>登錄</router-link>
// 2. 在路由對(duì)應(yīng)的組件內(nèi)部使用`this.$route.query`獲取參數(shù)
this.$route.query.name // zs
this.$route.query.id // 18
// 1. 更改路由規(guī)則用于匹配參數(shù)
new VueRouter({
routes:[
// :id用于匹配/login/13后面的參數(shù)13
{path:'/login/:id',component:login}
]
})
// 2. 在跳轉(zhuǎn)路徑后面使用/拼接參數(shù)
<router-link to = '/login/13'>登錄</router-link>
// 3. 在路由對(duì)應(yīng)組件內(nèi)部使用`this.$route.params`獲取參數(shù)
var login = {
template:'<div>登錄組件{{this.$route.params.id}}</div>',
created(){
console.log(this.$route.params.id) // 獲取到的就是13
}
}
// 1. 在父路由內(nèi)部使用children屬性配置子路由規(guī)則,子路由規(guī)則對(duì)象中的path屬性不要 '/'
// 2. 在父路由規(guī)則對(duì)應(yīng)的組件模板中添加router-view用于顯示子路由規(guī)則對(duì)應(yīng)的組件
// 3. 在<router-link>中設(shè)置跳轉(zhuǎn)路徑(將父路由和子路由的path拼接)
什么是webpack? 一個(gè)基于Node的前端構(gòu)建工具,可以實(shí)現(xiàn)對(duì)項(xiàng)目的打包(構(gòu)建),主要解決文件(模塊)之間的依賴(lài),高級(jí)代碼的轉(zhuǎn)譯,文件(模塊)的合并和壓縮等問(wèn)題蛙吏。
webpack3.~
版本安裝使用// 1. 全局安裝webpack
npm i webpack@3.10.0 -g
// 2. 使用
webpack 入口文件 輸出文件
webpack ./src/main.js ./dist/build.js
webpack4.~
版本安裝使用// 1. 全局安裝webpack
npm i webpack -g
npm i webpack-cli -g
// 2. 使用
webpack 入口文件 -o 輸出文件 --mode development/production
webpack ./src/main.js -o ./dist/build.js --mode development
webpack4.x不需要定義入口和輸出參數(shù),默認(rèn)src/main.js
為入口文件,dist/index.js
為輸出文件鞋吉。
但是需要配置模式參數(shù)mod
// 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' // 輸出文件名稱(chēng)
}
// mode:"development" // webpack4.x配置此選項(xiàng)
}
// 2. 執(zhí)行打包命令
webpack
幫助在項(xiàng)目根目錄搭建一個(gè)服務(wù)器,該服務(wù)器可以幫我們托管代碼,同時(shí)監(jiān)聽(tīng)所有文件的變化然后自動(dòng)執(zhí)行webpack編譯命令以及自動(dòng)刷新瀏覽器
--hot
: 熱更新,可以局部更新文件
--open
: 自動(dòng)打開(kāi)瀏覽器
--port
: 配置端口號(hào)
--inline
: 刷新瀏覽器
// 1. 局部安裝webpack-dev-server和webpack
npm i webpack-dev-server webpack --save-dev
// 2. 在package.json的scripts節(jié)點(diǎn)中添加啟動(dòng)命令
"scripts":{
"dev":"webpack-dev-server --inline --open --hot--port 8888"
}
// 3. 在項(xiàng)目根目錄運(yùn)行項(xiàng)目
npm run dev
// 1. 在webpack.config.js配置文件中添加如下配置
devServer:{
open: true,
port: 8888,
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文件
// 1. 安裝html-webpack-plugin
npm i html-webpack-plugin --save-dev
// 2. 在webpack.config.js中的plugins節(jié)點(diǎn)中配置插件
// 2.1 導(dǎo)入html-webpack-plugin
const htmlWebpackPlugin = require('html-webpack-plugin')
// 2.2 配置插件
plugins:[
new htmlWebpackPlugin({
template:path.join(__dirname,'./src/index.html'),// 需要生成的HTML的模板文件
filename:'index.html' // 生成的HTML文件的名稱(chēng)
})
]
css-loader
處理CSS文件解析處理文件后綴名為.css的文件
// 1. 安裝style-loader css-loader
npm 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的文件
// 1. 安裝less less-loader
npm 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的文件
// 1. 安裝node-sass sass-loader
npm 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)、音視頻等資源文件
// 1. 安裝file-loader ulr-loader
npm 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)的文件名稱(chēng)以8位hash值和原來(lái)的名稱(chēng)進(jìn)行拼接,文件擴(kuò)展名不變
}
]
}
babel
的使用解析webpack默認(rèn)不能處理的JS
// 1. 安裝babel-core babel-loader babel-plugin-transform-runtime
npm i babel-core babel-loader babel-plugin-transform-runtime --save-dev
// 2. 安裝babel-preset-env babel-preset-stage-0
npm 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文件,書(shū)寫(xiě)如下配置
{
"presets":["env","stage-0"],
"plugins":["transform-runtime"]
}
// 1. 安裝vue vue-loader vue-template-compiler
npm i vue --save
npm 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ū)域
<div id="app"></div>
// 4. 新建App.vue組件
<template>
<div>vue組件</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
// 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ū)域中
})
// 1. 安裝vue-router
npm i vue-router --save
// 2. 在main.js中導(dǎo)入vue-router并實(shí)例化路由添加路由規(guī)則
import VueRouter from 'vue-router'
Vue.use(VueRouter) // 保證在vue的組件中可以使用vue-router提供的組件 如<router-view> <router-link>
const router = new VueRouter({
routes: [
{
path: '/login', component: login
}
]
})
// 3. 將實(shí)例化的router綁定到Vue
new Vue({
el: '#app',
render: c => c(App),
router // 將router實(shí)例綁定到Vue上 以保證vue實(shí)例中可以訪問(wèn)$route $router等屬性
})
// 4. 在App.vue中添加路由占位router-view標(biāo)簽
<router-link to = "/login">登錄<router-link>
<router-view></router-view>
// 項(xiàng)目開(kāi)發(fā)期間需要安裝的依賴(lài)
// --save-dev 會(huì)將安裝的包名以及版本號(hào)記錄到package.json文件中的devDependencies節(jié)點(diǎn)中
npm install webpack --save-dev 等價(jià)于 npm install webpack -D
// 項(xiàng)目上線后需要安裝的依賴(lài)
// --save 會(huì)將安裝的包名以及版本號(hào)記錄到package.json文件中的dependencies節(jié)點(diǎn)中
npm i webpack --save 等價(jià)于 npm i webpack -S
npm i 會(huì)將所有在package.json文件中的devDependencies節(jié)點(diǎn)和dependencies節(jié)點(diǎn)內(nèi)所有的依賴(lài)包全部安裝一遍
npm i --save-dev 只會(huì)下載devDependencies中的所有依賴(lài)包
npm i --save 只會(huì)下載dependencies中的所有依賴(lài)包
// 為什么安裝包的時(shí)候要區(qū)分 --save 和 --save-dev
// 1. 使項(xiàng)目的閱讀更加友好谓着,便于理解項(xiàng)目結(jié)構(gòu)
// 2. 安裝對(duì)應(yīng)階段的包時(shí)更加方便
// 1. 安裝vue-cli腳手架
npm i vue-cli -g
// 2. 初始化項(xiàng)目模板
vue init webpack 項(xiàng)目名稱(chēng)
eslint(語(yǔ)法規(guī)范化插件) 不要安裝 當(dāng)安裝之后只能按照ESLint中規(guī)定的語(yǔ)法格式去書(shū)寫(xiě)代碼
e2e(測(cè)試框架) 不要安裝
unit test(單元測(cè)試框架) 不要安裝
// 3. 進(jìn)入項(xiàng)目安裝所有依賴(lài)
npm i
// 4. 運(yùn)行
npm run dev
config/index.js中 17/18行改端口號(hào)和自動(dòng)打開(kāi)瀏覽器
Vuex是一個(gè)狀態(tài)管理庫(kù),或者說(shuō)是專(zhuān)為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ù)赊锚。
1. 安裝vuex
npm i vuex --save
2. 入口文件中實(shí)例化Store
import Vuex from 'vuex'
Vue.use(Vuex)
var store = new Vuex.Store({
// 1. 用于定義狀態(tài)(公共數(shù)據(jù)),類(lèi)似于Vue實(shí)例中的data方法
state:{
msg:'初始化的數(shù)據(jù)'
},
// 2. 用于修改狀態(tài),類(lèi)似于Vue實(shí)例中methods
mutations:{
change(state,arg){
// 更改狀態(tài)
state.msg = arg
}
},
// 3. 用于獲取數(shù)據(jù)(獲取數(shù)據(jù)之前可以進(jìn)行一些操作),類(lèi)似于Vue實(shí)例中的過(guò)濾器和計(jì)算屬性
// getters 主要會(huì)用在跨組件傳值
// getters 中定義的方法內(nèi)部依賴(là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
})
1. 使用state中的數(shù)據(jù)
JavaScript: this.$store.state.msg
HTML: $store.state.msg
2. 使用getters中的數(shù)據(jù)
JavaScript: this.$store.getters.fixmsg
HTML: $store.getters.msg
狀態(tài)的變更必須使用mutations中提供的方法進(jìn)行修改
1. 提交mutations中的變更方法
this.$store.commit('change','我是被修改的數(shù)據(jù)')
2. 異步提交actions中的變更方法
this.$store.dispatch('asyncchange','我是被異步修改的數(shù)據(jù)')
輔助函數(shù)可以直接將state
,getters
中的數(shù)據(jù)映射到Vue組件中的計(jì)算屬性上,可以將mutations
,actions
中的方法映射到組件中的methods
中,然后在組件中就可以直接以屬性和方法的方式去使用數(shù)據(jù)和方法舷蒲。
import { 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']
}
})
更多文章訪問(wèn)個(gè)人博客:http://www.lfanliu.top