此筆記是我在拉勾學(xué)習(xí)課程過程中的總結(jié)菌瘫,文字原創(chuàng)洋闽,筆記里很多技巧和知識是老師總結(jié)的,如果有侵權(quán)突梦,請聯(lián)系本人诫舅!
組件化開發(fā)、Vue Router宫患、VueCLI
Vue.js組件
用于將每個區(qū)域進(jìn)行封裝刊懈,將結(jié)構(gòu)、樣式娃闲、邏輯代碼封裝為整體虚汛。
提高功能復(fù)用性和可維護(hù)性。
組件使用時為自定義的html標(biāo)簽皇帮,通過組件作名為自定義標(biāo)簽名
組件的注冊
全局注冊
全局注冊的組件可以用于任意實例或組件中Vue.component('組件名'卷哩,{選項對象})
注:
全局注冊必須在根Vue實例之前創(chuàng)建,需要在根實例之內(nèi)使用
<div id="app">
<p>這是p標(biāo)簽</p>
<my-compoment></my-compoment>
</div>
<script src="lib/vue.js"></script>
<script>
// 全局組件
Vue.component('my-compoment',{
template: '<div>這是第一個我們自己的組件</div>'
});
// 根實例
new Vue({
el:'#app',
data: {
}
});
</script>
組件基礎(chǔ)
組件是可服用的Vue實例属拾,可以與 new Vue接收相同的選項将谊,例如data,methods以及生命周期鉤子等。
但是 el 這種跟實例特有的選項不行
組件命名規(guī)則:
· kebab-case:"my-component"
· PascalCase:"MyComponent"
注意:
無論哪種命名方式,dom 中只有kebab-case方法命名可用-
template選項
· 用于設(shè)置組件結(jié)構(gòu)电抚,最終被引入根實例或者其他組件中· template只能有一個根元素,不可在根元素同級設(shè)置根元素
-
data選項
· data用于存儲數(shù)據(jù)栋齿,但是組件的data必須為函數(shù),數(shù)據(jù)設(shè)置在返回值對象中
· 這種實現(xiàn)方式是為了確保每個組件實例可以維護(hù)一份被返回的對象獨立的拷貝襟诸,不會相互影響
局部注冊
- 只用于當(dāng)前實例或組件中
new Vue({
el: '#app',
data: {
},
// 組件
components: {
// 組件a
'my-com-a': {
template:`
<div>
<h3>{{title}}</h3>
<p>{{content}}</p>
</div>
`,
data () {
return {
title:'組件 A 標(biāo)題',
content:'組件 A 內(nèi)容'
}
}
},
// 組件b
'my-com-b': {
template:`
<div>
<h3>{{title}}</h3>
<p>{{content}}</p>
</div>
`,
data () {
return {
title:'組件 B 標(biāo)題',
content:'組件 B 內(nèi)容'
}
}
}
}
});
- 單獨配置組件的選項對象
<div id="app">
<my-com-a></my-com-a>
<my-com-b></my-com-b>
</div>
<script src="lib/vue.js"></script>
<script>
// 組件a的選項對象
var MyComponentA = {
// 組件a
template:`
<div>
<h3>{{title}}</h3>
<p>{{content}}</p>
</div>
`,
data () {
return {
title:'組件 A 標(biāo)題',
content:'組件 A 內(nèi)容'
}
}
};
var MyComponentB = {
template:`
<div>
<h3>{{title}}</h3>
<p>{{content}}</p>
</div>
`,
data () {
return {
title:'組件 B 標(biāo)題',
content:'組件 B 內(nèi)容'
}
}
}
new Vue({
el: '#app',
data: {
},
// 組件
components: {
//組件a
'my-com-a': MyComponentA, //兩種書寫方式均可瓦堵,但是第二種跟更簡潔
// 組件b
MyComponentB
}
});
</script>
組件通信
父組件向子組件傳值
通過子組件的 props 選項接收父組件的傳值。
props不要與data存在同名屬性
<!-- 通過 v-for 遍歷數(shù)據(jù) items歌亲,創(chuàng)建組件并生成內(nèi)容 -->
<div id="app">
<!-- 這里的key是綁定給v-for來幫助渲染的 -->
<demo-item
v-for="item in items"
:key="item.title"
:item-title="item.title"
:item-content="item.content"
></demo-item>
</div>
<script src="lib/vue.js"></script>
<script>
Vue.component('demoItem',{
props: ["itemTitle", "itemContent"],
template: `
<div>
<h3>{{ itemTitle }}</h3>
<p>{{ itemContent }}</p>
</div>
`
})
new Vue({
el: '#app',
data: {
// 給子組件準(zhǔn)備的數(shù)據(jù)
items:[
{
title:'這是標(biāo)題1',
content:'這是內(nèi)容1'
},
{
title:'這是標(biāo)題2',
content:'這是內(nèi)容2'
},
{
title:'這是標(biāo)題3',
content:'這是內(nèi)容3'
}
]
}
})
</script>
- props命名規(guī)則:建議使用駝峰命名菇用,父組件綁定時用烤串命名
<my-component
:item-title="item.title"
:item-content="item.content"></my-component>
</div>
<script src="lib/vue.js"></script>
<script>
Vue.component('my-component',{
props:['itemTitle','itemContent'],
- 單向數(shù)據(jù)流
父子組件間所有的prop都是單項下行綁定的,(只能向子組件傳应结,不能反向影響父組件)
如果子組件要處理prop數(shù)據(jù)刨疼,應(yīng)當(dāng)存儲在data中后操作。
如果prop為數(shù)組或?qū)ο蠖炝洌剑瑐鬟f進(jìn)來的是引用,子組件操作將影響到父組件的狀態(tài)扮休。
<div id="app">
<my-component
:initial-title="title"
></my-component>
</div>
<script src="lib/vue.js"></script>
<script>
Vue.component('my-component',{
props:["initialTitle"],//接收父組件的data迎卤,傳給data()處理
template: `
<div>
{{ title }}
<button @click="fn">按鈕</button>
</div>
`,
data () {
return{
title: this.initialTitle//處理完了給賦值表達(dá)式
}
},
method: {
fn () {
// this.title = "這是新標(biāo)題";//父組件數(shù)據(jù)變化,引起子組件數(shù)據(jù)變化
// this.initialTitle = "這是新標(biāo)題";//子組件數(shù)據(jù)變化玷坠,不引起父組件變化
this.obj.name = 'jack';//根元素和原來數(shù)據(jù)都會發(fā)生變化
}
}
})
new Vue({
el: '#app',
data: {
title:'這是示例內(nèi)容',
obj : {
name:'william',
age:18
}
}
});
</script>
props類型
· 如果需要prop類型檢查蜗搔,就需要進(jìn)行規(guī)則設(shè)置劲藐,如設(shè)置成一個對象解構(gòu),通過 鍵值對 對應(yīng)樟凄。
· props中的某一個prop可以同時制定多種類型聘芜,可以寫成數(shù)組類型props驗證
· 當(dāng)prop需要設(shè)置多種規(guī)則時,可以將prop設(shè)置為選項對象
· 之前類型檢測可以通過type選項設(shè)置
· required 用于設(shè)置數(shù)據(jù)為必填項
· default 用于給可選項設(shè)置默認(rèn)值缝龄,當(dāng)父組件未傳值時生效汰现。
· default為數(shù)組或?qū)ο螅仨殲楣S函數(shù)返回的形式
· validator 用于傳入prop設(shè)置校驗函數(shù)叔壤,return值為 false 時發(fā)出警告
· 驗證函數(shù)中無法使用實例data瞎饲、methods功能,無法使用this
<div id="app">
<my-component
:par-str="str"
:par-num="num"
:par-num2="2000"
:par-arr="arr"
par-content="lagou: hello world"
></my-component>
</div>
<script src="lib/vue.js"></script>
<script>
Vue.component('MyComponent', {
props: {
parStr: {
// 當(dāng)prop需要設(shè)置多種規(guī)則時炼绘,可以將prop設(shè)置為選項對象
// 之前類型檢測可以通過type選項設(shè)置
type: String
},
parData: {
type: [Array, Object]
},
parNum: {
type: Number,
//required表示此處必須傳值嗅战,不傳報錯
required: true
},
parNum2: {
type: Number,
// 默認(rèn)值為100,如果傳值了俺亮,就為傳的值
default: 100
},
parArr: {
type: Array,
// 如果傳的值是數(shù)組或?qū)ο笸院矗仨殲楣S函數(shù)返回的形式
default () {
return [1, 2, 3];
}
},
parContent: {
type: String,
// 用于傳入prop設(shè)置校驗函數(shù),return值為false時發(fā)出警告铅辞,value是傳入的值厌漂,是html元素中設(shè)置的對應(yīng)項的值
//驗證函數(shù)中無法使用實例data、methods功能斟珊,無法使用this
validator (value) {
console.log(this);
return value.startsWith('lagou');
}
}
},
template: `<div></div>`
})
new Vue({
el: '#app',
data: {
str: '示例內(nèi)容',
num: 100,
arr: [10, 20, 30],
obj: {
content1: '內(nèi)容1',
content2: '內(nèi)容2'
}
}
});
</script>
當(dāng)父組件給子組件設(shè)置了屬性,但此屬性在props中不存在富纸,會自動綁定到子組件的根元素上
如果根元素已經(jīng)存在了對應(yīng)屬性囤踩,則會被組件內(nèi)屬性替換,class和style例外晓褪,會進(jìn)行合并堵漱。
如果不希望繼承父組件屬性,可以設(shè)置inheritAttrs:false,但是只適用于普通屬性涣仿,class與style不受影響
<div id="app">
<!-- 自定義屬性也可以綁定 -->
<my-component
:class="colorRed"
style="background-color:red;"
:title="'示例標(biāo)題內(nèi)容'"
data-index = "3"
></my-component>
</div>
<script src="lib/vue.js"></script>
<script>
Vue.component('my-component', {
// 如果不希望繼承父組件屬性勤庐,可以設(shè)置inheritAttrs:false
inheritAttr:false,
//class和style屬性會合并,其他屬性會被組件內(nèi)屬性代替
template:`
<div data-index="6"
title="舊的title"
class="abc"
style="width: 200px;">
<p>這是組件內(nèi)容</p></div>
`
})
new Vue({
el: '#app',
data: {
}
});
</script>
子組件向父組件傳值
- 子組件數(shù)據(jù)變化時好港,通過$emit()觸發(fā)自定義事件愉镰,自定義事件名稱需要用 kebab-case
- 父組件監(jiān)聽子組件事件,并設(shè)置處理程序
<h3>購物車</h3>
<!-- @count-increase接收一個值或者一個功能函數(shù) -->
<div id="app">
<product-item
v-for="item in product"
:key="product.id"
:title="product.title"
@count-increase="totalCount++"
></product-item>
<div>購物車總數(shù):{{ totalCount }}</div>
</div>
<script src="lib/vue.js"></script>
<script>
Vue.component('product-item',{
props:['title'],
template:`
<div>
<span>商品名稱:{{title}}钧汹,商品個數(shù):{{count}}</span>
<button @click="Increase">+1</button>
</div>
`,
data() {
return {
count:0
}
},
methods:{
Increase() {
//$emit向父級傳遞數(shù)據(jù)
this.$emit('count-increase')
this.count++;
}
}
})
new Vue({
el: '#app',
data: {
product: [
{ id:1, title:'橘子一斤' },
{ id:2,title:"香蕉一斤"},
{id:3,title:"蘋果一斤"}
],
totalCount:0
}
});
</script>
- 自定義事件傳值
子組件觸發(fā)事件向父組件傳值丈探,父組件在監(jiān)聽事件時接收子組件傳遞的數(shù)據(jù)
<div id="app">
<h3>購物車</h3>
<product-item
v-for="product in products"
:key="product.id"
:title="product.title"
@count-change="onCountChange"
></product-item>
<p>商品總個數(shù)為:{{ totalCount }}</p>
</div>
<script src="lib/vue.js"></script>
<script>
// 子組件
Vue.component('ProductItem', {
props: ['title'],
template: `
<div>
<span>商品名稱: {{ title }}, 商品個數(shù): {{ count }}</span>
<button @click="countIns1">+1</button>
<button @click="countIns5">+5</button>
</div>
`,
data () {
return {
count: 0
}
},
methods: {
countIns1 () {
this.$emit('count-change', 1);
this.count++;
},
countIns5 () {
this.$emit('count-change', 5);
this.count += 5;
}
}
});
// 父組件
new Vue({
el: '#app',
data: {
products: [
{
id: 1,
title: '蘋果一斤'
},
{
id: 2,
title: '香蕉一根'
},
{
id: 3,
title: '橙子一個'
}
],
totalCount: 0
},
methods: {
onCountChange(productZongshu) {//這是模板傳回來的參數(shù)
// console.log(productZongshu);
this.totalCount += productZongshu;
}
}
});
</script>
- 組件與v-model
v-model用于組件時,需要通過props與自定義事件實現(xiàn)
<div id="app">
<p>輸入的內(nèi)容是:{{ inputValue }}</p>
<com-input v-model="inputValue"></com-input>
</div>
<script src="lib/vue.js"></script>
<script>
var ComInput = {
props:['value'],
template:`
<input
type="text"
:value="value"
@input='onInput'>`,
methods: {
onInput (event) {
this.$emit('input', event.target.value)
}
}
}
// 根實例
new Vue({
el: '#app',
data: {
inputValue:''
},
components: {
ComInput
}
});
</script>
非父子組件傳值
- 兄弟組件傳值拔莱,通過父組件中轉(zhuǎn)
<div id="app">
<!-- 父組件接收子組件a的數(shù)據(jù) -->
<com-a
@value-change="value = $event"
></com-a>
<!-- 父組件將數(shù)據(jù)傳遞給子組件b -->
<com-b
:value = "value"
></com-b>
</div>
<script src="lib/vue.js"></script>
<script>
// 子組件a: 發(fā)送數(shù)據(jù)
Vue.component('com-a',{
template:`
<div>
組件a的內(nèi)容:{{ value }}
<button @click="$emit('value-change',value)"></button>
</div>
`,
// 通過數(shù)據(jù)聲明碗降,向外部傳遞數(shù)據(jù)
data () {
return {
value:'這是組件a中的內(nèi)容'
}
}
});
// 子組件b:接收數(shù)據(jù)
Vue.component('com-b',{
props:['value'],
template:`
<div>
組件b接收的數(shù)據(jù):{{ value }}
</div>
`
});
// 根實例(父組件)
new Vue({
el: '#app',
data: {
// 用于數(shù)據(jù)中專
value:''
}
})
</script>
-
EventBus
EventBus(事件總線)是一個獨立的事件中心隘竭,用于管理不同組件之間的傳值。
EventBus通過一個新的Vue實例來管理組件傳值操作讼渊,組件通過給實例注冊事件动看、調(diào)用事件實現(xiàn)數(shù)據(jù)傳遞。
操作步驟:
發(fā)送數(shù)據(jù)的組件觸發(fā)bus事件爪幻,接收的組件給bus注冊對應(yīng)事件
給bus注冊對應(yīng)事件通過$on()操作菱皆。
// 商品組件
Vue.component('product-item',{
template:`
<div>
<span>商品名稱:蘋果,商品個數(shù):{{ count }}</span>
<button
@click="countIns"
>+1</button>
</div>`,
data() {
return {
count:0
}
},
methods: {
countIns () {
// 給bus觸發(fā)自定義事件笔咽,傳遞數(shù)據(jù)
bus.$emit('countChange', 1)
this.count++;
}
}
})
// 計數(shù)組件
Vue.component('product-total',{
template:`
<p>商品總數(shù)是:{{ totalCount }}</p>
`,
data () {
return {
totalCount:0
}
},
created () {
// 給 bus 注冊事件搔预,并接受數(shù)據(jù),接受函數(shù)名叶组,并調(diào)用回調(diào)函數(shù)
bus.$on('countChange', (productCount) => {
this.totalCount += productCount;
})
// 實例創(chuàng)建完畢拯田,可以使用 data 等功能
}
})
-
其他通信
了解即可 $root $refs不建議在功能中使用,會操作其他組件內(nèi)部數(shù)據(jù),出現(xiàn)問題時甩十,不容易找出問題所在
$root 用于訪問當(dāng)前樹根實例船庇,設(shè)置簡單的Vue應(yīng)用
<div id="app">
<com-a></com-a>
</div>
<script src="lib/vue.js"></script>
<script>
// 根實例的子組件A的子組件B
var ComB = {
template: `
<div>
組件B: {{ $root.count }}
<button @click="clickFn">按鈕</button>
</div>
`,
methods: {
clickFn () {
this.$root.count = 200;
}
}
};
// 子組件A
var ComA = {
template: `
<div>
組件A: {{ $root.count }}
<button @click="clickFn">按鈕</button>
<com-b></com-b>
</div>
`,
methods: {
clickFn () {
this.$root.count = 100;
}
},
components: {
ComB
}
};
// 根實例
new Vue({
el: '#app',
data: {
count: 0
},
components: {
ComA
}
});
</script>
- $refs用于獲取設(shè)置了ref屬性的HTML標(biāo)簽或子組件。
基本操作方式:
給普通HTML標(biāo)簽設(shè)置ref屬性侣监,$refs可以獲取DOM對象 訪問含有ref屬性的元素
給組件設(shè)置 ref 屬性鸭轮,獲取的是DOM對象結(jié)構(gòu),渲染可以通過 $refs 獲取子組件實例
<div id="app">
<!-- 給 HTML 標(biāo)簽設(shè)置 ref 屬性 -->
<input type="text" ref="inp">
<button @click="fn">按鈕</button>
<!-- 給子組件設(shè)置 ref 屬性 -->
<com-a ref="comA"></com-a>
</div>
<script src="lib/vue.js"></script>
<script>
var ComA = {
template: `<div>組件A的內(nèi)容:{{ value }}</div>`,
data () {
return {
value: '示例內(nèi)容'
}
}
}
var vm = new Vue({
el: '#app',
methods: {
fn () {
// 點擊后修改 HTML 標(biāo)簽焦點狀態(tài)
this.$refs.inp.focus();
this.$refs.comA.value = '新的內(nèi)容';
}
},
components: {
ComA
},
mounted () {
console.log(this.$refs);
this.$refs.comA.value = "修改后的內(nèi)容";
},
});
</script>
組件插槽
單個插槽
用來像HTML一樣在標(biāo)簽之間書寫內(nèi)容
- 通過<slot>進(jìn)行插槽設(shè)置橄霉。需要注意模板內(nèi)容渲染位置:
父組件的數(shù)據(jù)都是在父組件中編譯執(zhí)行的窃爷,
子組件的數(shù)據(jù)都是在子組件中編譯執(zhí)行的。
插槽可以設(shè)置默認(rèn)值姓蜂,成為后備內(nèi)容
<div id="app">
<com-a>這是組件的內(nèi)容</com-a>
<com-a>
這是第二個組件的內(nèi)容:
<span>這是span的內(nèi)容</span>
</com-a>
<com-a>
這里是父組件的視圖模板按厘,只能使用父組件的數(shù)據(jù):
{{ parValue }}
</com-a>
</div>
<script src="lib/vue.js"></script>
<script>
Vue.component('ComA', {
//插槽中沒有內(nèi)容時,會采用<slot>中間的默認(rèn)內(nèi)容
template: `
<div>
<h3>組件標(biāo)題</h3>
<slot>
這是插槽的默認(rèn)內(nèi)容
</slot>
</div>
`,
data() {
return {
value: '子組件的數(shù)據(jù)'
}
}
});
new Vue({
el: '#app',
data: {
parValue: '這是父組件的數(shù)據(jù)'
}
})
</script>
具名插槽
- 組建中有多個位置需要設(shè)置插槽钱慢,根據(jù)需要逮京,給<slot>設(shè)置name,成為具名插槽束莫。
插入一張slot圖片
<div id="app">
<com-a>
<!-- 這里記得是對象書寫形式懒棉,不是屬性書寫方式 -->
<template v-slot:header>
<h3>組件頭部內(nèi)容</h3>
</template>
<!-- <template #default>
<p>組件主體內(nèi)容1</p>
<p>組件主體內(nèi)容2</p>
</template> -->
<p>組件主體內(nèi)容1</p>
<p>組件主體內(nèi)容2</p>
<!-- #footer是v-slot:footer的簡寫方式 -->
<template #footer>
<p>組件底部內(nèi)容</p>
</template>
</com-a>
</div>
<script src="lib/vue.js"></script>
<script>
// 子組件
Vue.component('ComA',{
template:`
<div>
<header>
// 這里正常書寫name='header'
<slot name='header'></slot>
</header>
<main>
<slot></slot>
</main>
<footer >
<slot name="footer"></slot>
</footer>
</div>
`
});
new Vue({
el: '#app',
data: {
}
});
</script>
作用域插槽
用于讓插槽可以使用子組件的數(shù)據(jù),
組件需要使用的數(shù)據(jù)通過v-bind綁定給<slot>,
這種用于給插槽傳遞數(shù)據(jù)的屬性成為插槽prop組件綁定數(shù)據(jù)后览绿,通過v-slot接受數(shù)據(jù)
可以通過es6的解構(gòu)操作進(jìn)行數(shù)據(jù)接收 <com-a v-slot:default="{ value }">
<div id="app">
<!-- 多個插槽作用域插槽的書寫方式 -->
<com-a>
<template v-slot:default="dataObj">
{{ dataObj.value }}
{{ dataObj.num }}
</template>
<template v-slot:footer="dataObj">
{{ dataObj.value }}
</template>
</com-a>
<!-- 只具有默認(rèn)插槽的作用域插槽的書寫方式 -->
<!-- <com-b v-slot="dataObj"> -->
<com-b v-slot="dataObj">
{{ value }}
</com-b>
<!-- 通過es6 的解構(gòu)操作接收作用域插槽的數(shù)據(jù) -->
<com-b #default="{value,num}">
{{value}}
{{num}}
</com-b>
</div>
<script src="lib/vue.js"></script>
<script>
// 子組件b
var ComB = {
template:`
<div>
<p>組件b的內(nèi)容:</p>
<slot
:value="value"
:num="num"
></slot>
<slot name = "footer"
:value="value"></slot>
</div>
`,
data() {
return {//返回的就是 dataObj 數(shù)據(jù)對象
value :'這是組件a內(nèi)的數(shù)據(jù)',
num:200
}
}
}
// 子組件a
var ComA = {
template:`
<div>
<p>組件a的內(nèi)容:</p>
<slot
v-bind:value="value"
:num="num"
></slot>
<slot name = "footer"
:value="value"></slot>
</div>
`,
data() {
return {//返回的就是 dataObj 數(shù)據(jù)對象
value :'這是組件a內(nèi)的數(shù)據(jù)',
num:100
}
}
}
new Vue({
el: '#app',
components: {
ComA,ComB
}
});
</script>
內(nèi)置組件
動態(tài)組件
組件切換處理操作
<component> 用于將一個‘元組件’渲染為動態(tài)組件策严,以 is 屬性決定渲染哪個組件
用于實現(xiàn)多個組件的快速切換,例如選項卡效果
is 屬性會在每次切換組件時挟裂,創(chuàng)建一個新的組件實例
<div id="app">
<!-- 按鈕代表選項卡的標(biāo)題功能 -->
<button
v-for="title in titles"
:key="title"
@click="currentCom = title"
>{{ title }}</button>
<!-- component 設(shè)置動態(tài)組件 -->
<component :is="currentCom"></component>
</div>
<script src="lib/vue.js"></script>
<script>
// 這是要切換的子組件的選項對象
var comA = {
template:`<p>這是組件a的內(nèi)容:<input type="text"></p>`
};
var comB = {
template:`<p>這是組件b的內(nèi)容:<input type="text"></p>`
};
var comC = {
template:`<p>這是組件c的內(nèi)容:<input type="text"></p>`
};
new Vue({
el: '#app',
data:{
// 所有組件名稱
titles: ["comA","comB","comC"],
// 當(dāng)前組件名稱
currentCom:'comA'
},
components: {
// 注冊組件
comA,comB,comC
}
});
</script>
keep-alive組件
組件動態(tài)切換的緩存處理
- 主要用于保留組件狀態(tài)或避免組件重新渲染
利用 <keep-alive max="2">
<component :is="currentCom"></component>
</keep-alive>
包裹享钞,保證組件切換中進(jìn)行緩存,不會被移除
keep-alive需要記住的屬性:
- include屬性用于指定哪些組件會被緩存,具有多種設(shè)置方式
<!-- <keep-alive include="ComA,ComB,ComC"> -->
<!-- <keep-alive :include="['ComA', 'ComB', 'ComC']"> -->
<!-- <keep-alive :include="/Com[ABC]/"> -->
- exclude 指定哪些組件不會被緩存
<!-- <keep-alive exclude="ComD"> -->
<!-- <keep-alive :exclude="['ComD']"> -->
<!-- <keep-alive :exclude="/ComD/"> -->
- max 屬性用于設(shè)置最大緩存?zhèn)€數(shù):
距離最近的max個被緩存
<div id="app">
<button
v-for="title in titles"
:key="title"
@click="currentCom = title"
>
{{title}}
</button>
<keep-alive max="2">
<!-- 動態(tài)組件 -->
<component :is="currentCom"></component>
</keep-alive>
</div>
過渡組件
控制切換效果和動畫效果
transition組件
-
用于給元素進(jìn)入或離開過渡
· 條件渲染 v-if
· 條件展示 v-show
· 動態(tài)組件<component>
· 組件根節(jié)點
提供了6個class栗竖,用于設(shè)置過渡的具體效果
進(jìn)入類名: v-enter(入場前的樣式)
v-enter-to(入場完畢之后樣式)一般不做設(shè)置
v-enter-active(入場過渡)
離開類名:v-leave(離場前)一般不做設(shè)置
v-leave-to(離場后)
v-leave-active(離場過渡)
屬性
給組件設(shè)置name屬性暑脆,用于給多個元素、組件設(shè)置不同的過渡效果狐肢,這時需要將 v- 改為對應(yīng)的 name- 形式
通過 appear 屬性添吗,可以讓組件在初始渲染時實現(xiàn)過渡
<style>
/* 第一組過渡效果設(shè)置 */
.v-enter, .v-leave-to {
opacity: 0;
}
.v-enter-active, .v-leave-active {
transition: opacity .5s;
}
/* 第二組過渡效果設(shè)置 */
.demo-enter, .demo-leave-to {
opacity: 0;
transform: translateX(200px);
}
.demo-enter-active, .demo-leave-active {
transition: all .5s;
}
</style>
</head>
<body>
<div id="app">
<button @click="show = !show">切換1</button>
<!-- 沒有設(shè)置name命名的 transition 組件,style中類名以 v-開頭 -->
<transition appear>
<p v-if="show">這是要切換的元素1</p>
</transition>
<button @click="showDemo = !showDemo">切換2</button>
<!-- 設(shè)置了name 的transition 組件份名,類名需要將 v- 修改為 demo- -->
<!-- 通過 appear 屬性碟联,可以讓組件在初始渲染時實現(xiàn)過渡 -->
<transition
name="demo"
appear>
<p v-if="showDemo">這是要切換的元素2</p>
</transition>
</div>
<script src="./lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
show: true,
showDemo: true
}
});
自定義過渡類名
自定義類名比普通類名優(yōu)先級高,才能替代第三方動畫庫
-
用于自定義過渡類名的屬性
· enter-class 入場初始狀態(tài)· enter-active-class 入場過程
· enter-to-class 入場最終效果
· leave-class 入場初始狀態(tài)
· leave-active-class 入場過程
· leave-to-class 入場最終效果
-
用于初始過渡類名的屬性:
· appear-class· appear-to-class
· appear-active-class
.test {
transition: all 3s;
}
</style>
</head>
<body>
<div id="app">
<button @click="show = !show">切換</button>
<!-- 自定義類名的優(yōu)先級更高 -->
<transition
enter-active-class="test"
leave-active-class="test"
>
<p v-if="show">這是 p 標(biāo)簽</p>
</transition>
</div>
-
Animate.css 是一個第三方動畫庫僵腺,通過設(shè)置類名給元素添加效果
注意點
· animate__ 前綴與compat版本· 基礎(chǔ)類名 animate__animated 設(shè)置
<link
rel="stylesheet"
/>
<!-- 不需要添加 animate__ 的兼容版本鲤孵,但是官方建議使用完整版本 -->
<!-- "https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.0.0/animate.compat.css" -->
</head>
<body>
<div id="app">
<button @click="show = !show">按鈕</button>
<!-- 通過自定義過渡類名設(shè)置,給組件添加第三方動畫庫的類名效果 -->
<transition
enter-active-class="animate__bounceInDown"
leave-active-class="animate__bounceOutDown"
>
<!-- 必須給要使用動畫的元素設(shè)置基礎(chǔ)類名 animate__animated -->
<p
v-if="show"
class="animate__animated"
>hello world</p>
</transition>
</div>
transition-group組件
-
<transition-group> 用于給列表統(tǒng)一設(shè)置過渡動畫
· tag 屬性用于設(shè)置容器元素辰如,默認(rèn)為<span>
· 過渡應(yīng)用于內(nèi)部元素普监,不是容器
· 子節(jié)點必須有獨立的key,動畫才能正常工作
· 當(dāng)列表元素變更導(dǎo)致元素位移琉兜,可以通過 .v-move 類名設(shè)置移動效果
<style>
ul {
position: relative;
}
.v-enter, .v-leave-to {
opacity: 0;
transform: translateX(100px);
}
.v-enter-active, .v-leave-active {
transition: all .5s;
}
/* 讓元素在離場的過程中脫離標(biāo)準(zhǔn)流 */
.v-leave-active {
position: absolute;
}
.v-move {
transition: all .5s;
}
</style>
</head>
<body>
<div id="app">
<input type="text"
v-model="newTitle"
@keyup.enter="addItem"
>
<transition-group
tag="ul"
>
<li
v-for="item in items"
:key="item.id"
@click="removeItem(item)"
>
{{ item.title }}
</li>
</transition-group>
</div>
<script src="./lib/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
items: [
{ id: 1, title: '示例內(nèi)容1'},
{ id: 2, title: '示例內(nèi)容2'},
{ id: 3, title: '示例內(nèi)容3'},
{ id: 4, title: '示例內(nèi)容4'},
{ id: 5, title: '示例內(nèi)容5'},
],
newTitle: '',
latestId: 5
},
methods: {
addItem () {
this.items.push({
id: this.latestId + 1,
title: this.newTitle
});
this.latestId++;
this.newTitle = '';
},
removeItem (item) {
var i = this.items.indexOf(item);
this.items.splice(i, 1);
}
}
});
</script>
Vue Router
Vue Router是Vue.js的官方插件凯正,用來快速實現(xiàn)單頁應(yīng)用
單頁應(yīng)用
SPA(Single Page Application)單頁面應(yīng)用程序,簡稱單頁應(yīng)用豌蟋。指的是網(wǎng)站的 “所有” 功能都在單個頁面
中進(jìn)行呈現(xiàn)廊散。
- 后臺管理系統(tǒng)、移動端梧疲、小程序等適合單頁面應(yīng)用允睹。
優(yōu)點:
· 前后端分離開發(fā),提高開發(fā)效率
· 業(yè)務(wù)場景切換時幌氮,局部更新結(jié)構(gòu)
· 用戶體驗好擂找,接近本地應(yīng)用
缺點:
· 不利于SEO
· 初次加載速度慢
· 頁面復(fù)雜度高
前端路由
-
URL 與內(nèi)容之間的映射關(guān)系
前端路由的必備條件: URL、內(nèi)容浩销、映射關(guān)系
實現(xiàn)方式
Hash方式實現(xiàn)前端路由
通過hashchange 事件監(jiān)聽hash變化,進(jìn)行網(wǎng)頁內(nèi)容更新
通過 onhashchange 事件監(jiān)聽 hash 變化听哭,進(jìn)行網(wǎng)頁內(nèi)容更新
- 封裝hash函數(shù)以備復(fù)用
總結(jié):
· hash兼容性好
· 地址中具有 # 慢洋,不太美觀
· 前進(jìn)后退功能較繁瑣
<div>
<a href="#/">首頁</a>
<a href="#/category">分類頁</a>
<a href="#/user">用戶頁</a>
</div>
<div id="container">
這是首頁功能
</div>
<script>
// 準(zhǔn)備對象,用于封裝 hash 功能
var router = {
// 路由存儲位置:保存了 url 與 內(nèi)容處理函數(shù)的對應(yīng)關(guān)系
routes: {},
// 定義路由規(guī)則的方法
route: function (path, callback) {//path相當(dāng)于鍵陆盘,callback相當(dāng)于值
this.routes[path] = callback;
},
// 初始化路由的方法
init: function () {
window.onhashchange = function () {
// 將外部的router傳進(jìn)來
var that = this;
// 當(dāng) hash 改變普筹,需要得到當(dāng)前新的 hash
var hash = location.hash.replace('#','');
// 根據(jù)hash 觸發(fā) routes 對象中的對應(yīng) callback
// 利用邏輯與運算,前面成立,則執(zhí)行 && 后面的內(nèi)容隘马,如果前面路由是真太防,則執(zhí)行回調(diào)函數(shù)
that.routes[hash] && that.routes[hash]();//&& 后面是對象實例化
}
}
};
var container = document.getElementById('container');
// 定義路由規(guī)則
router.route("/", function () {
container.innerHTML = '這是首頁功能';
});
router.route("/category", function () {
container.innerHTML = '這是分類功能';
});
router.route("/user", function () {
container.innerHTML = '這是用戶功能';
});
// 初始化路由
router.init();
</script>
History方式實現(xiàn)前端路由
History 方式采用 html5 提供的新功能實現(xiàn)前端路由
在操作時通過 history.pushState() 變更url執(zhí)行對應(yīng)操作。
實現(xiàn)前進(jìn)后退功能酸员,首先需要再更改url時保存路由標(biāo)記蜒车;通過popstate事件監(jiān)聽前進(jìn)后退按鈕操作酿愧,并檢測 state庞钢;調(diào)用初始化方法監(jiān)聽操作基括。
<body>
<div>
<a href="/">首頁</a>
<a href="/category">分類頁</a>
<a href="/user">用戶頁</a>
</div>
<div id="container">
這是首頁功能
</div>
<script>
var router = {
// 存儲路由的對象
routes: {},
// 定義路由的方法
route (path, callback) {
this.routes[path] = callback;
},
// go 用于 觸發(fā) 指定的路由操作
go (path) {
// 更改url饭冬,前進(jìn)后退功能炊苫,需要pushstate方法將更改url時的標(biāo)記存儲在第一個參數(shù)中,方便后面popstate調(diào)用
history.pushState({path : path}, null, path);//第一個參數(shù)是與數(shù)據(jù)有關(guān)的唠梨,第二個參數(shù)瀏覽器目前不支持
// 觸發(fā)路由對應(yīng)的回調(diào)函數(shù)
this.routes[path] && this.routes[path]();
// console.log(this.routes[path]());
},
init() {
var that = this;
window.addEventListener('popstate', function(e) {//監(jiān)聽前進(jìn)后退操作醉箕,并檢測state
var path = e.state ? e.state.path : '/';
// 觸發(fā)路由對應(yīng)的回調(diào)函數(shù)
that.routes[path] && that.routes[path]();
});
}
};
// 初始化操作
router.init();
// 設(shè)置 a 標(biāo)簽 功能
var links = document.querySelectorAll('a');
var container = document.querySelector('#container');
links.forEach(function (ele) {
ele.addEventListener ('click', function (event) {
router.go(this.getAttribute('href'));
event.preventDefault();//防止跳轉(zhuǎn)
});
});
// 定義路由規(guī)則
router.route("/", function () {
container.innerHTML = '這是首頁功能';
});
router.route("/category", function () {
container.innerHTML = '這是分類功能';
});
router.route("/user", function () {
container.innerHTML = '這是用戶功能';
});
</script>
總結(jié):
history可以實現(xiàn)前進(jìn)后退
url沒有#剧辐,更加美觀
hash傳遞數(shù)據(jù)最大2k,history的pushstate可以存儲640k鳄梅;
history只兼容HTML5
VueRouter
Vue.js官方路由管理器悲雳,讓構(gòu)建單頁面應(yīng)用更簡單
基本使用
安裝
- 直接下載 / CDN
? 最新版本:https://unpkg.com/vue-router/dist/vue-router.js
? 指定版本:https://unpkg.com/vue-router@3.4.9/dist/vue-router.js - npm
? npm install vue-router
基本使用
- Vue Router 提供了 <router-link>和 <router-view> 組件來進(jìn)行路由設(shè)置
<router-link> 鏈接跳轉(zhuǎn)挎峦,默認(rèn)就是a標(biāo)簽,如果希望改變合瓢,可以用tag屬性進(jìn)行改變
<router-view> 進(jìn)行視圖區(qū)域變換坦胶,用來顯示路由匹配到的組件
<router-link>使用
- 定義路由需要的組件,進(jìn)行規(guī)則設(shè)置晴楔,
- 創(chuàng)建vue Router實例迁央,通過 Routes屬性配置路由
- 創(chuàng)建vue 實例,通過 router 屬性注入路由滥崩。
<div id="app">
<!-- 設(shè)置用于進(jìn)行路由操作的組件 -->
<router-link to="/">首頁</router-link>
<router-link to="/user">用戶</router-link>
<router-link to="/category">分類</router-link>
<!-- 用于切換顯示組件 -->
<router-view></router-view>
</div>
<script src="lib/vue.js"></script>
<script src="lib/vue-router.js"></script>
<script>
console.log(VueRouter);
// 2.定義組件信息
var Index = {
template:`<div>這是首頁信息</div>`
};
var User = {
template:`<div>這是用戶信息</div>`
};
var Category = {
template:`<div>這是分類信息</div>`
};
// 1.定義路由規(guī)則
var routes1 = [
{ path: '/', component: Index},
{ path: '/user', component: User},
{ path: '/category', component: Category},
];
// 3. 創(chuàng)建 Vue Router實例
var router = new VueRouter({
// 配置對象屬性routes,將配置好的路由規(guī)則加入進(jìn)來
routes:[
{ path: '/', component: Index},
{ path: '/user', component: User},
{ path: '/category', component: Category},
]
});
// 4.創(chuàng)建vue 實例,注入router
new Vue({
el:"#app",
router
});
</script>
<router-view>基本使用
- 導(dǎo)航(跳轉(zhuǎn))后讹语,希望統(tǒng)計展示多個視圖(組件)钙皮,這是就需要進(jìn)行命名視圖。
- 路由中通過 components 屬性進(jìn)行設(shè)置不同視圖的對應(yīng)組件。
// 側(cè)邊欄結(jié)構(gòu)
var SideBar1 = {
template:`<div>側(cè)邊欄1功能</div>`
};
var SideBar2 = {
template:`<div>側(cè)邊欄2功能</div>`
};
var Index = {
template:`<div>首頁功能</div>`
};
var User = {
template:`<div>用戶功能</div>`
};
// 定義路由規(guī)則
var rules = [
{
path:'/',
components: {
// router-view 的name: 組件配置對象
default: Index,
sidebar: SideBar1
}
},
{
path:'/user',
components: {
// router-view 的name: 組件配置對象
default: User,
sidebar: SideBar2
}
}
];
// 創(chuàng)建 Vue Router 實例
var router = new VueRouter({
routes: rules
});
// 創(chuàng)建 Vue 實例
new Vue({
el: '#app',
router
});
</script>
動態(tài)路由處理
多個url對應(yīng)一個組件的方式
應(yīng)用場景:
需要將一類URL都映射到一個組件短条,就需要使用動態(tài)路由使用方法
· 定義動態(tài)路由規(guī)則時导匣,將路徑中的某個部分使用:
冒號進(jìn)行標(biāo)記,即可設(shè)置為動態(tài)路由
· 設(shè)置動態(tài)路由后茸时,動態(tài)部分為任意內(nèi)容均跳轉(zhuǎn)到同一組件
· 冒號:部分對應(yīng)的信息成為路徑參數(shù)贡定,存儲在 vm.$route.params 中偵聽路由參數(shù)
· 如果要相應(yīng)路由參數(shù)變化,可以通過watch監(jiān)聽 $route
<div id="app">
<router-link to="/user/1">用戶1</router-link>
<router-link to="/user/2">用戶2</router-link>
<router-link to="/user/3">用戶3</router-link>
<router-view></router-view>
</div>
<script src="lib/vue.js"></script>
<script src="lib/vue-router.js"></script>
<script>
// 設(shè)置組件
var User = {
template: `
<div>
這是用戶 {{ $route.params.id }} 的功能
<input type="text">
</div>`,
// 由于組件沒有重新創(chuàng)建可都,所以生命周期鉤子只能執(zhí)行一次
/* created () {
console.log('創(chuàng)建了組件的實例');//只輸出了一次
} */
// 監(jiān)聽路由參數(shù)
watch: {
$route (route) {
console.log($route.params.id);
}
}
};
// 設(shè)置路由規(guī)則
var routes = [
{
path: '/user/:id', component: User
}
];
var router = new VueRouter({ routes });
var vm = new Vue({
el: '#app',
router
});
</script>
- 路由傳參處理
· 通過路由的props設(shè)置數(shù)據(jù)缓待,并通過組件 porps 接收
<div id="app">
<router-link to="/user/1">用戶1</router-link>
<router-link to="/user/2">用戶2</router-link>
<router-link to="/user/3">用戶3</router-link>
<router-link to="/category/1">分類1</router-link>
<router-link to="/category/2">分類2</router-link>
<router-link to="/category/3">分類3</router-link>
<router-view></router-view>
<router-view name="sidebar"></router-view>
<router-view name="sidebar2"></router-view>
</div>
<script src="lib/vue.js"></script>
<script src="lib/vue-router.js"></script>
<script>
// 組件的配置對象
var User = {
template: `<div>這是用戶 {{ $route.params.id }} 功能</div>`
};
var Category = {
props: ['id'],
template: `<div>這是分類 {{ id }} 功能</div>`
};
var SideBar = {
template: `<div>側(cè)邊欄功能</div>`
};
var SideBar2 = {
props: ['a', 'b'],
template: `
<div>
側(cè)邊欄2功能: {{ a }} {{ b }}
</div>`
};
// 設(shè)置路由規(guī)則
var routes = [
{
path: '/user/:id',
component: User
},
{
path: '/category/:id',
components: {
default: Category,
sidebar: SideBar,
sidebar2: SideBar2
},
props: {
default: true,
sidebar: false,
sidebar2: {
a: '狀態(tài)1',
b: '狀態(tài)2'
}
}
}
];
var router = new VueRouter({ routes });
var vm = new Vue({
el: '#app',
router
});
</script>
- 路由傳參其他方式
· 包含多個命名視圖時,需要將路由的 props 設(shè)置為對象
· 如果希望設(shè)置靜態(tài)數(shù)據(jù)渠牲,可以將 props 中的額某個組件對應(yīng)的選項設(shè)置為對象旋炒,內(nèi)部屬性會綁定給 props
<div id="app">
<router-link to="/user/1">用戶1</router-link>
<router-link to="/user/2">用戶2</router-link>
<router-link to="/user/3">用戶3</router-link>
<router-link to="/category/1">分類1</router-link>
<router-link to="/category/2">分類2</router-link>
<router-link to="/category/3">分類3</router-link>
<router-view></router-view>
<router-view name="sidebar"></router-view>
<router-view name="sidebar2"></router-view>
</div>
<script src="lib/vue.js"></script>
<script src="lib/vue-router.js"></script>
<script>
// 組件的配置對象
var User = {
template: `<div>這是用戶 {{ $route.params.id }} 功能</div>`
};
var Category = {
props: ['id'],
template: `<div>這是分類 {{ id }} 功能</div>`
};
var SideBar = {
template: `<div>側(cè)邊欄功能</div>`
};
var SideBar2 = {
props: ['a', 'b'],
template: `
<div>
側(cè)邊欄2功能: {{ a }} {{ b }}
</div>`
};
// 設(shè)置路由規(guī)則
var routes = [
{
path: '/user/:id',
component: User
},
{
path: '/category/:id',
components: {
default: Category,
sidebar: SideBar,
sidebar2: SideBar2
},
// 多個視圖時,需要將props改為對象签杈,并設(shè)置加載方式
props: {
default: true,
sidebar: false,
sidebar2: {
a: '狀態(tài)1',
b: '狀態(tài)2'
}
}
}
];
var router = new VueRouter({ routes });
var vm = new Vue({
el: '#app',
router
});
</script>
嵌套路由
路由通常由多層嵌套的組件組合而成瘫镇,這是需要使用嵌套路由配置。
· 使用 children 來進(jìn)行嵌套路由中的子路由設(shè)置答姥。
<div id="app">
<router-link to="/user">用戶功能</router-link>
<router-view></router-view>
</div>
<script src="lib/vue.js"></script>
<script src="lib/vue-router.js"></script>
<script>
var User = {
template:`
<div>
<h3>這是 User 組件的功能</h3>
<router-link to="/user/hobby">愛好功能</router-link>
<router-link to="/user/info">用戶信息</router-link>
<router-view></router-view>
</div>
`
};
// 愛好
var UserHobby = {
template: `<div> UserHobby 組件</div>`
};
// info
var UserInfo = {
template: `
<div>
UserInfo 組件
<router-link to="/user/info/school">學(xué)校信息</router-link>
<router-view></router-view>
</div>`
};
var UserInfoSchool = {
template:`<div> UserInfoSchool 組件</div>`
};
// 路由規(guī)則設(shè)置
var routes = [
{
path: '/user',
component: User,
children: [
{
path: 'hobby',
component: UserHobby
},
{
path: 'info',
component: UserInfo,
children: [
{
path: 'school',
component: UserInfoSchool
}
]
}
]
}
];
var router = new VueRouter({ routes });
var vm = new Vue({
el:'#app',
router
});
</script>
編程式導(dǎo)航
指的是通過方法設(shè)置導(dǎo)航铣除。
router.push() 用來導(dǎo)航一個新的URL
<router-link> 的 to 屬性 使用綁定方式時也可以是 屬性對象結(jié)構(gòu)
<div id="app">
<!-- 聲明式導(dǎo)航 -->
<!-- <router-link to="/user/200">用戶200</router-link> -->
<!-- 編程式導(dǎo)航 -->
<router-link :to="{ path: '/user/700' }">用戶700</router-link>
<router-view></router-view>
</div>
<script src="./lib/vue.js"></script>
<script src="./lib/vue-router.js"></script>
<script>
var User = {
template: `<div> 這是用戶 {{ $route.params.id }} </div>`
};
// 設(shè)置路由規(guī)則
var routes = [
{
path: '/user/:id',
component: User
}
];
var router = new VueRouter({ routes });
var vm = new Vue({
el: '#app',
router
});
</script>
命名路由
設(shè)置路由時添加 name 屬性,根據(jù)name處理路由
在 push() 中設(shè)置 name 導(dǎo)航到對應(yīng)路由鹦付,參數(shù)通過 params 設(shè)置
<div id="app">
<!-- <router-link :to="{ name: 'school', params: { id: 10 } }">學(xué)校10</router-link> -->
<!-- 通過name屬性尋找對應(yīng)的組件 -->
<router-link :to="{ name: 'school', params: { id :10 }}">學(xué)校10</router-link>
<router-view></router-view>
</div>
<script src="lib/vue.js"></script>
<script src="lib/vue-router.js"></script>
<script>
var School = {
template: `
<div>school 組件的功能: {{ $route.params }}</div>`
};
var routes = [
{
path:'/user/:id/info/school',
name: 'school',
component: School
}
];
var router = new VueRouter({ routes });
var vm = new Vue({
el: '#app',
router
});
</script>
重定向
訪問不合理的URL時尚粘,被重新指定到了一個位置
<div id="app">
<router-link to="/">首頁</router-link>
<router-link to="/category/2">分類2</router-link>
<router-link to="/category"> /category 錯誤演示 </router-link>
<router-view></router-view>
</div>
<script src="./lib/vue.js"></script>
<script src="./lib/vue-router.js"></script>
<script>
var Index = {
template: `<div>首頁功能</div>`
};
var Category = {
template: `<div>分類 {{ $route.params.id }} 功能</div>`
};
var router = new VueRouter({
routes: [
{
path: '/',
component: Index
},
{
path: '/category/:id',
component: Category
},
// 如果id沒有書寫的話,無法訪問到對應(yīng)的category睁壁,那我們就需要重新定向
{
path: '/category',
redirect: '/'
}
]
});
var vm = new Vue({
el: '#app',
router
});
</script>
別名功能
<div id="app">
<!-- 命名式路由 -->
<router-link :to="{ name: 'school', params: { id: 10, date: '0612'} }">學(xué)校信息</router-link>
<!-- 導(dǎo)航別名 -->
<router-link to="/20/1234">學(xué)校信息2</router-link>
<router-view></router-view>
</div>
<script src="lib/vue.js"></script>
<script src="lib/vue-router.js"></script>
<script>
// 組件
var School = {
template: `
<div>School 組件</div>
`
};
// 路由規(guī)則
var router = new VueRouter({
routes: [
{
path: '/user/:id/info/school/:date',
name: 'school',
component: School,
// 設(shè)置別名背苦,此處綁定id和日期,為了傳參使用
alias: '/:id/:date'
}
]
});
var vm = new Vue({
el: '#app',
router
});
</script>
導(dǎo)航守衛(wèi)
- 某些特定網(wǎng)址可能需要登錄潘明,所以需要使用導(dǎo)航守衛(wèi)進(jìn)行跳轉(zhuǎn)
- to到哪里去行剂,from來自哪里,需要守衛(wèi)時調(diào)用next钳降,調(diào)用且調(diào)用一次
- next可以傳入false組織本次導(dǎo)航厚宰,無法往后執(zhí)行
- 傳入?yún)?shù)跳轉(zhuǎn)到登錄頁面,傳入?yún)?shù)和router-link中的參數(shù)傳入的是相同的
router.beforeEach(function (to, from, next){
函數(shù)體
next();
});
<script>
var Index = {
template: `<div>這是首頁功能</div>`
};
var User = {
template: `<div>這是用戶功能</div>`
};
var Category = {
template: `<div>這是分類功能</div>`
};
// 建立導(dǎo)航對象 router
var router = new VueRouter({
routes: [
{ path: '/', component: Index },
{ path: '/user', component: User },
{ path: '/category', component: Category },
]
});
// 通過上面建立的導(dǎo)航對象router遂填,設(shè)置導(dǎo)航守衛(wèi)
router.beforeEach(function (to ,from, next) {
console.log(to,from);
//阻止了導(dǎo)航繼續(xù)操作
// next(false);
// 按條件跳轉(zhuǎn)
if(to.path === '/user') {
next('/category');
}else {
next();
}
});
var vm = new Vue({
el: '#app',
router
})
</script>
history 模式
vue router默認(rèn)使用的hash模式設(shè)置
也可以提供history模式铲觉,需要Vue Router實例的mode 選項設(shè)置,這樣可以是 URL更加美觀吓坚,需要后端支持避免出現(xiàn)問題
var router = new VueRouter({
mode: 'history',
routes: [
{ path: '/', component: Index },
{ path: '/user', component: User },
{ path: '/category', component: Category },
]
});
Vue CLI
基于 Vue.js 進(jìn)行快速開發(fā)的完整系統(tǒng)撵幽,稱為為腳手架工具,
統(tǒng)一架構(gòu)風(fēng)格礁击,
初始化配置項目依賴盐杂。
提供單文件組件功能逗载。
Vue CLI安裝
? 安裝
? npm install –g @vue/cli
? 升級
? npm update –g @vue/cli
項目搭建
? 創(chuàng)建項目:
vue create project-demo
? 選擇 Preset:
? 選擇包管理器:
- 運行項目:
? npm run serve
目錄與文件
? 文件目錄介紹:
└─ 根目錄
├─ public 預(yù)覽文件目錄
└─ src
├─ assets 靜態(tài)資源目錄
└─ components 項目組件目錄
└─ App.vue 根組件
└─ main.js 入口文件
- 單文件組件
可以將組件的功能統(tǒng)一保存在以.vue為擴(kuò)展名的文件中。
打包與部署
打包
? 打包就是將 Vue CLI 項目編譯為瀏覽器可識別的文件链烈。
? 命令:
npm run build
部署
? 部署指的是將 Vue 項目dist 目錄部署到服務(wù)器上厉斟。
? 安裝靜態(tài)文件服務(wù)器:
- npm install -g serve
? 在 dist 下通過 serve 命令部署
先到dist目錄下:cd dist
再運行服務(wù)器:serve