什么是Vue
- 是一套用于構(gòu)建用戶界面的漸進(jìn)式 javascript 框架(漸進(jìn)式:想用什么就用什么不必全都用)
- 在傳統(tǒng)的前端開發(fā)中,是基于 jQuery+ 模板引擎 來構(gòu)建界面的
vue全家桶
- vue 核心庫
- vue-router (路由)
- vuex (全局狀態(tài)管理)
- vue 組件庫(快速搭建頁面UI效果的方案)
輔助vue開發(fā)的工具
- vue-cli (基于webpack一鍵生成vue工程化項(xiàng)目)
- vite (一鍵生成vue工程化項(xiàng)目-小而巧)
- vue-detools (瀏覽器插件,輔助調(diào)試的工具)
- vetur (vscode插件,提供語法高亮和智能提示)
vue特性
- 數(shù)據(jù)驅(qū)動(dòng)視圖
- 雙向數(shù)據(jù)綁定
MVVM
- MVVM 是數(shù)據(jù)驅(qū)動(dòng)視圖和雙向數(shù)據(jù)綁定的核心原理
- M-Model --渲染依賴的數(shù)據(jù)源
- V-view --渲染的DOM結(jié)構(gòu)
- VM-ViewModel --vue實(shí)例是MVVM的核心
VUE指令
內(nèi)容渲染指令
- v-text ---會(huì)覆蓋元素中的默認(rèn)內(nèi)容
- {{ }} ---插值表達(dá)式
- v-html ---可以識(shí)別標(biāo)簽并渲染標(biāo)簽
- {{ }}中可以是三元運(yùn)算,可以簡單的運(yùn)算,也可以調(diào)用方法
屬性綁定指令
- v-bind 給標(biāo)簽屬性動(dòng)態(tài)綁定屬性值
- 簡寫 --- :
- 可以做簡單的運(yùn)算,字符串拼接
事件綁定指令
- v-on 給標(biāo)簽綁定事件 (v-on:click="clickFn")
- 處理函數(shù)在methods中聲明
- 簡寫---@click="clickFn"
- 事件對(duì)象參數(shù)e
- 沒有參數(shù),回調(diào)函數(shù)參數(shù)e
- 有參數(shù),就用$event占位,在回調(diào)中e接收
- 事件修飾符
- .prevent 阻止瀏覽器默認(rèn)行為(@click.prevent="clickFn")
- .stop 阻止冒泡(@click.stop="clickFn")
- 按鍵修飾符
- .enter 回車(@keyup.enter="keyupFn")
- .esc (@keyup.esc="keyupFn")
雙向綁定指令
- v-model 雙向數(shù)據(jù)綁定,不操作DOM,快速獲取表單數(shù)據(jù)
- 只要給表單元素綁定才有意義
- 與select下拉表單綁定時(shí),實(shí)際綁定的是option中的value屬性
- v-model 的修飾符
- .number 自動(dòng)將用戶輸入的值轉(zhuǎn)化為數(shù)字類型
- .trim 自動(dòng)過濾輸入的空白字符
- .lazy 在輸入框失去焦點(diǎn)時(shí)才更新
條件渲染指令
- v-if v-else
- v-show
- 為false時(shí)隱藏為true時(shí)顯示
- v-if 的原理是銷毀和重建標(biāo)簽
- v-show 的原理是給標(biāo)簽添加display:"none"屬性
- 頻繁切換時(shí)用v-show性能高
- v-if v-else 判斷是否為ture為ture顯示,否則隱藏
<div v-if="i>90">優(yōu)秀</div>
<div v-else="i>80">良好</div>
<div v-else="i>70">中等</div>
<div v-else>差勁</div>
循環(huán)渲染指令
v-for="(item,index) in list" :key="index"
- 基于 數(shù)組,對(duì)象,數(shù)字 來循環(huán)渲染列表結(jié)構(gòu)
- item為數(shù)組中的每一項(xiàng)
- index為當(dāng)前循環(huán)項(xiàng)的索引值
- list為循環(huán)的數(shù)據(jù)數(shù)組
- key屬性為了提升更新元素的性能,有ID綁定ID沒有ID綁索引
- 通過索引更改數(shù)組中的數(shù)據(jù)方法this.$set(數(shù)組,索引,要更改的數(shù)據(jù))
v-for指令中的key理解
- key屬性根據(jù)虛擬DOM和diff算法提升更新元素的性能
- 數(shù)組中哪些方法會(huì) 導(dǎo)致數(shù)組更新
- push( ) 末尾添加元素
- pop( ) 末尾刪除元素
- shift( ) 刪除數(shù)組第一個(gè)元素
- unshift( ) 添加數(shù)組第一個(gè)元素
- splice( ) 從數(shù)組中添加/刪除項(xiàng)目橄仆,然后返回被刪除的項(xiàng)目。
- sort( ) 對(duì)數(shù)組的元素進(jìn)行排序
- reverse( ) 翻轉(zhuǎn)數(shù)組
- 更新時(shí)新舊虛擬dom根據(jù)diff算法進(jìn)行對(duì)比
- 嘗試復(fù)用標(biāo)簽,就地更新內(nèi)容
- 虛擬Dom:本質(zhì)上就是保存 節(jié)點(diǎn)信息,屬性和內(nèi)容的JS對(duì)象
-
保存了標(biāo)簽的最重要的三個(gè)信息(類型,屬性,子節(jié)點(diǎn)信息)
- diff算法
- 同級(jí)比較根元素發(fā)生變化就會(huì)刪除整個(gè)dom樹重新創(chuàng)建
- 根元素沒有變化,只是屬性變了,那就只更新屬性
- 子元素變化 v-for更新分有key和無key
無key:子節(jié)點(diǎn)哪里變了更新哪里屬性或內(nèi)容
有key:
1)key為索引 -- 和無key更新一樣哪里變了更新哪里
2)key為id或不重復(fù)的字符串 -- 根據(jù)id比對(duì),內(nèi)容不變就地復(fù)用,極大程度復(fù)用標(biāo)簽提升更新性能
動(dòng)態(tài)class綁定
- 直接綁定:
:class="vue數(shù)據(jù)變量"
- 三元綁定:
:class= "vue數(shù)據(jù)變量布爾值? '類名':' '"
- 對(duì)象綁定:
:class= "{類名:vue數(shù)據(jù)變量布爾值}"
- 數(shù)組綁定:
:class="[vue數(shù)據(jù)變量]"
- 動(dòng)態(tài)class和靜態(tài)class并存會(huì)合并到一起
style動(dòng)態(tài)綁定
:style="{屬性名:屬性值}"
計(jì)算屬性-computed
注意: 計(jì)算屬性使用時(shí)不能加( ),計(jì)算屬性必須return一個(gè)結(jié)果
- 一個(gè)變量的值,依賴另外一些數(shù)據(jù)計(jì)算得來的結(jié)果,就會(huì)用到計(jì)算屬性
- 基于依賴項(xiàng)的值將結(jié)果進(jìn)行緩存,依賴項(xiàng)不變,就直接從內(nèi)存中取結(jié)果,而不是重新計(jì)算
- 計(jì)算屬性也是vue數(shù)據(jù)變量, 所以不要和data中的變量重名,用法和data中的變量用法完全相同
- 只要計(jì)算屬性的依賴項(xiàng)發(fā)生改變, 那么就會(huì)重新計(jì)算
computed:{
"計(jì)算屬性名"( ){
return "值"
}
}
計(jì)算屬性完整寫法
- 計(jì)算屬性用在v-model上進(jìn)行雙向數(shù)據(jù)綁定時(shí),改變計(jì)算屬性的值時(shí),就會(huì)用到完整寫法
- 獲取計(jì)算屬性值的時(shí)候會(huì)觸發(fā)get函數(shù)
- 設(shè)置計(jì)算屬性值的時(shí)候會(huì)觸發(fā)set函數(shù)
computed:{
"計(jì)算屬性名":{
set(改變后的值){
},
get(){
return "值"
}
}
}
vue監(jiān)聽器watch
- 可以監(jiān)聽data/computed屬性值的變化
- 監(jiān)聽基本數(shù)據(jù)類型
watch:{
"被偵聽的屬性名"(newval,lodval){
console.log(newval,lodval)
}
}
- 監(jiān)聽引用數(shù)據(jù)類型(復(fù)雜數(shù)據(jù)類型)
watch:{
"要偵聽的屬性名":{
immediate: true, //立即執(zhí)行
deep: true, //深度監(jiān)聽
handler (newval) { //偵聽函數(shù)
console.log(newval)
}
}
}
vue組件
- 好處:各自獨(dú)立,方便復(fù)用
- 組件是可復(fù)用的vue實(shí)例
- 組件的組成= 封裝標(biāo)簽+樣式+js代碼
- 組件化: 封裝的思想,把頁面上(可重用的部分)封裝為組件,從而方便項(xiàng)目的開發(fā)與維護(hù)
- 組件的使用
- 創(chuàng)建組件,封裝要復(fù)用的標(biāo)簽,樣式,js代碼
- 導(dǎo)入組價(jià)(import 組件對(duì)象 from 文件路徑)
- 注冊組件
- 使用組件, 把組件名當(dāng)自定義標(biāo)簽使用
(1)全局注冊- min.js中
// main.js
import Vue from 'vue'
import 組件對(duì)象 from 'vue組件路徑'
Vue.component("組件名",組件對(duì)象)
(2)局部注冊 - 使用組件的vue文件中
// 要使用組件的vue文件
import 組件對(duì)象 from 'vue組件路徑'
export default {
components:{
"組件名":組件對(duì)象
}
}
- 組件的命名
- 大駝峰命名 例如:MyProduct -->推薦使用大駝峰
- 烤串法 例如: my-product
- 組件的使用
- 大駝峰命名 例如:MyProduct
- 烤串法 例如: my-product -->推薦使用烤串法
結(jié)論:組件命名用大駝峰,組件使用時(shí)用烤串法
- 組件使用時(shí)用雙標(biāo)簽還是單標(biāo)簽?
如果組件標(biāo)簽需要夾內(nèi)容就用雙標(biāo)簽,不夾內(nèi)容就用單標(biāo)簽
- 組件中的name屬性
組件的name屬性的值可用作注冊組件時(shí)的組件名
- 組件style標(biāo)簽中的scoped屬性
- 作用:使當(dāng)前組件的css樣式只在當(dāng)前組件中生效,不會(huì)影響全局
- 原理:會(huì)在當(dāng)前組件的標(biāo)簽上生成一個(gè)data-v-hash:8, 每個(gè)組件內(nèi)的data-v-hash:8都是不同的,今后它會(huì)配合我們自己寫的選擇器上加一個(gè)屬性選擇器,從而保證了這個(gè)選擇器在組件內(nèi)部的唯一性,而不會(huì)影響其他組件
組件之間傳值
- 被引入的是兒子
在A組件中, import B from 'B.vue'
A(父) , B(子)
父傳子
- 子組件中通過props屬性接收數(shù)據(jù)
//子組件定義
props:{
變量名:{
type:變量數(shù)據(jù)類型,
default: 默認(rèn)值
}
}
- 父組件,通過屬性的方式傳值
<B :變量名="值"> </B>
子傳父
- 父傳給子的數(shù)據(jù)在子中是只讀的不能更改
- 從父到子的數(shù)據(jù)流向,叫 單向數(shù)據(jù)流
- 子想修改父組件傳過來的數(shù)據(jù)只能通過子傳父的方式通知父組件修改
- 子傳父語法:
(1)父組件內(nèi),綁定自定義事件和事件處理函數(shù)
<son @自定義事件名="事件處理函數(shù)" >
(2)子組件內(nèi)部在合適的時(shí)機(jī)觸發(fā)父組件的自定義事件
this.$emit('父組件中的自定義事件名',傳參,傳參)
-
單向數(shù)據(jù)流
父傳子時(shí) 子組件中的不能更改父組件中的變量(props中的變量都是只讀的)
解決方案: 子傳父(自通知父, 父自己改)
兩個(gè)沒有關(guān)系或者兄弟組件之間傳值
- EventBus:
創(chuàng)建一個(gè)空白 Vue對(duì)象new Vue()
只負(fù)責(zé)監(jiān)聽$on
和$emit
- 用法
- 創(chuàng)建一個(gè)空白Vue對(duì)象,封裝到EventBus.js文件
- A: 引入空白的vue對(duì)象,EventBus.$on("自定義事件名" ,事件處理函數(shù))
- B: 引入相同的這個(gè)空白Vue對(duì)象, EventBus.$emit("自定義事件名",值)
Vue組件中的生命周期
- 組件從創(chuàng)建到銷毀的過程就是組件的生命周期
鉤子函數(shù)
- 四個(gè)階段八個(gè)方法
- 初始化
beforeCreate
created
- created 鉤子函數(shù)可以獲取data中的變量但不能獲取真實(shí)的DOM
- created 鉤子函數(shù)可以用來發(fā)送axios請(qǐng)求
- 掛載
beforeMount
mounted
- 在mounted鉤子函數(shù)中才可以拿到真實(shí)的DOM
- 更新
beforeUpdate
updated
- data中數(shù)據(jù)改變后會(huì)觸發(fā)DOM更新在updated鉤子函數(shù)中可以拿到更新后的"真實(shí)DOM"
- 銷毀
beforeDestroy
destroyed
- destroyed鉤子函數(shù)中清除當(dāng)前組件自己的定時(shí)器 / 延時(shí)器 / 全局事件 (eventBus)
v-for循環(huán)
<p v-for="(item,index) in 數(shù)組" :key="item.id">
- 每次循環(huán)生成的組件都是全新的互不影響的
axios發(fā)送axjx請(qǐng)求
- 支持客戶端發(fā)送Ajax請(qǐng)求
- 支持服務(wù)器端Node.js發(fā)送請(qǐng)求
- 支持Promise 相關(guān)用法
- 支持請(qǐng)求和響應(yīng)的攔截器功能
- 自動(dòng)轉(zhuǎn)換JSON數(shù)據(jù)
- 什么是ajax?
一種前端異步請(qǐng)求后端數(shù)據(jù)的技術(shù) - ajax原理?
瀏覽器window接口的XMLHttpRequest - axios是什么?
基于原生ajax+Promise技術(shù)封裝用于前后端的請(qǐng)求庫
axios的使用
1.下載引入axios(yarn add axios)
//引入
import axios from 'axios'
- 發(fā)送請(qǐng)求
axios({
method:"請(qǐng)求方式", //get &put & post...
url:"請(qǐng)求的路徑", //http://123.57.109...
data:{
XXX:XXX //請(qǐng)求體參數(shù)
},
params:{
XXX:XXX //查詢參數(shù),會(huì)拼接到url路徑后
}
}).then(res={
//請(qǐng)求成功的回調(diào)
}).catch(err={
//請(qǐng)求失敗的回調(diào)
})
$refs獲取DOM&組件
- $refs 可以獲取DOM標(biāo)簽
- 也可以獲取組件實(shí)例從而調(diào)用組件中的方法或?qū)傩?/strong>
- 只有在Vue中才能使用$refs獲取DOM
- $refs使用
- 標(biāo)簽定義ref屬性和值
- this.$refs.值 - 原地獲取DOM
$nextTick獲取更新后的DOM
- 問題 : data數(shù)據(jù)改變,"dom更新是異步的"
- 在setTimeOut延時(shí)器中獲取DOM
- 在Vue中提供$nextTick方法(等待DOM更新后再執(zhí)行此方法中的回調(diào)函數(shù))
- $nextTick原理
嘗試用Promise.then() / setTimeout & setImmediate - $nextTick使用
this.$nextTick(()=>{
getElementById("myp").innerHTML
})
<keep-alive>組件緩存
- 用<keep-alive>包裹的組件會(huì)被緩存到內(nèi)存中在切換組件的時(shí)候就不會(huì)被銷毀和重建,提升渲染性能
<keep-alive>
<!-- vue內(nèi)置的組件component, 可以動(dòng)態(tài)顯示組件 -->
<component :is="comName"></component>
</keep-alive>
組件插槽
- vue提供組件插槽能力, 允許開發(fā)者在封裝組件時(shí),把不確定的部分定義為插槽
- 插槽步驟
- 組件內(nèi)用<slot></slot>占位
- 使用組件時(shí)<template></template>夾著的地方, 傳入標(biāo)簽替換slot
- <slot>夾著內(nèi)容默認(rèn)顯示內(nèi)容, 如果不給插槽slot傳東西, 則使用<slot>夾著的內(nèi)容在原地顯示
- 具名插槽(當(dāng)一個(gè)組件內(nèi)有2處以上需要外部傳入標(biāo)簽的地方,傳入的標(biāo)簽可以分別派發(fā)給不同的slot位置)
- 在slot標(biāo)簽上用name屬性命名
<slot name="one"></slot>
<slot name="two"></slot>
2.在template標(biāo)簽上用 v-slot:插槽名 傳入具體標(biāo)簽 , v-slot:可以簡寫成 " # "
<template #one>
<div>
<p>寒雨連江夜入?yún)?</p>
<p>平明送客楚山孤防嗡。</p>
<p>洛陽親友如相問屈芜,</p>
<p>一片冰心在玉壺炸裆。</p>
</div>
</template>
<template #two>
<img src="../assets/mm.gif" alt="" />
</template>
-
作用域插槽
子組件里值, 在給插槽賦值時(shí)在父組件環(huán)境下使用
- 創(chuàng)建組件, 準(zhǔn)備slot, 在slot上綁定屬性和子組件值
- 使用組件, 傳入自定義標(biāo)簽, 用template和v-slot="自定義變量名"
- 自定義變量名會(huì)自動(dòng)綁定slot上所有屬性, 就可以使用子組件內(nèi)值, 并替換slot位置
<template>
<div>
<p>這里是個(gè)Pannel3-子組件, 下面是插槽位置</p>
<slot name="one" :row="slotDefault">{{ slotDefault.default1 }}</slot>
</div>
</template>
<script>
export default {
data(){
return {
slotDefault: {
default1: "無名氏",
default2: "孫紅雷"
}
}
}
}
</script>
<template>
<div>
<!-- 想要改變默認(rèn)內(nèi)容, 但是默認(rèn)數(shù)據(jù)在子組件里, 想讓插槽使用就使用插槽作用域 -->
<!--
口訣: 1.創(chuàng)建組件, 準(zhǔn)備slot, 在slot上綁定屬性和子組件值
2. 使用組件, 傳入自定義標(biāo)簽, 用template和v-slot="自定義變量名"
3. 自定義變量名會(huì)自動(dòng)綁定slot上所有屬性, 就可以使用子組件內(nèi)值, 并替換slot位置
-->
<Pannel3>
<template #one="scope">
{{ scope.row.default2 }}
</template>
</Pannel3>
</div>
</template>
<script>
import Pannel3 from './Pannel3'
export default {
components: {
Pannel3
}
}
</script>
自定義指令
- 局部注冊和使用
<template>
<div>
<input type="text" v-focus />
</div>
</template>
<script>
export default {
// 局部注冊
directives: {
focus: { // 自定義指令名
inserted(el){ // 固定配置項(xiàng) - 當(dāng)指令插入到標(biāo)簽自動(dòng)觸發(fā)此函數(shù)
el.focus()
}
},
},
};
</script>
-
全局注冊
在main.js用 Vue.directive()方法來進(jìn)行注冊, 以后隨便哪個(gè).vue文件里都可以直接用v-fofo指令
Vue.directive("fofo", {
inserted(el){
el.focus()
}
})
自定義指令-接值
- 使用自定義指令, 傳入一個(gè)值
main.js定義處修改一下
Vue.directive("color", {
inserted(el, binding){ // 插入時(shí)觸發(fā)此函數(shù)
el.style.color = binding.value;
},
update(el, binding){ // 更新時(shí)觸發(fā)此函數(shù)
el.style.color = binding.value;
}
})
<p v-color="theColor" @click="changeColor">使用v-color指令控制顏色, 點(diǎn)擊變藍(lán)</p>
<script>
data() {
return {
theColor: "red",
};
},
methods: {
changeColor() {
this.theColor = 'blue';
},
},
</script>
router 路由
- 路徑和組件的映射關(guān)系
- vue-router本質(zhì)是一個(gè)第三方包
- 步驟
- 終端下載
yarn add vue-router - 導(dǎo)入路由
import VueRouter from 'vue-router'
- 注冊
// 在vue中誓禁,使用使用vue的插件唇牧,都需要調(diào)用Vue.use()
Vue.use(VueRouter)
- 創(chuàng)建規(guī)則數(shù)組
const routes = [
{
path: "/find",
component: Find
},
{
path: "/my",
component: My
},
{
path: "/part",
component: Part
}
]
- 創(chuàng)建路由對(duì)象 - 傳入規(guī)則
const router = new VueRouter({
routes
})
- 關(guān)聯(lián)到vue實(shí)例
new Vue({
router
})
- 設(shè)置路由掛載點(diǎn)
<router-view></router-view>
vue路由 - 聲明式導(dǎo)航
- vue-router提供了一個(gè)全局組件 router-link
- router-link實(shí)質(zhì)上最終會(huì)渲染成a鏈接 to屬性等價(jià)于提供 href屬性(to無需#)
- router-link提供了聲明式導(dǎo)航高亮的功能(自帶類名)
- router-link自帶的2個(gè)類名的區(qū)別是什么?
- router-link-exact-active (精確匹配) url中hash值路徑, 與href屬性值完全相同, 設(shè)置此類名
- router-link-active (模糊匹配) url中hash值, 包含href屬性值這個(gè)路徑
<template>
<div>
<div class="footer_wrap">
<router-link to="/find">發(fā)現(xiàn)音樂</router-link>
<router-link to="/my">我的音樂</router-link>
<router-link to="/part">朋友</router-link>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
聲明式導(dǎo)航 - 跳轉(zhuǎn)傳參
- 在跳轉(zhuǎn)路由時(shí), 可以給路由對(duì)應(yīng)的組件內(nèi)傳值
- 在router-link上的to屬性傳值, 語法格式如
- ?key=value 用$route.query.key 取值
- /值 提前在路由規(guī)則/path/:key 用$route.params.key 取值
- /path?參數(shù)名=值
- /path/值 – 需要路由對(duì)象提前配置 path: “/path/參數(shù)名”
對(duì)應(yīng)頁面組件接收傳遞過來的值
$route.query.參數(shù)名
$route.params.參數(shù)名
創(chuàng)建components/Part.vue - 準(zhǔn)備接收路由上傳遞的參數(shù)和值
<template>
<div>
<p>關(guān)注明星</p>
<p>發(fā)現(xiàn)精彩</p>
<p>尋找伙伴</p>
<p>加入我們</p>
<p>人名: {{ $route.query.name }} -- {{ $route.params.username }}</p>
</div>
</template>
路由定義
{
path: "/part",
component: Part
},
{
path: "/part/:username", // 有:的路徑代表要接收具體的值
component: Part
},
導(dǎo)航跳轉(zhuǎn), 傳值給MyGoods.vue組件
<router-link to="/part?name=小傳">朋友-小傳</router-link>
<router-link to="/part/小智">朋友-小智</router-link>
vue路由 - 重定向&模式&404頁面
路由 - 重定向
- 網(wǎng)頁打開url默認(rèn)hash值是/路徑
- redirect是設(shè)置要重定向到哪個(gè)路由路徑
const routes = [
{
path: "/", // 默認(rèn)hash值路徑
redirect: "/find" // 重定向到/find
// 瀏覽器url中#后的路徑被改變成/find-重新匹配數(shù)組規(guī)則
}
]
404頁面
- 放在路由最后, path匹配*(任意路徑) – 前面不匹配就命中最后這個(gè), 顯示對(duì)應(yīng)404組件頁面
- 步驟:
- 創(chuàng)建NotFound頁面
<template>
<img src="404圖片路徑" alt="">
</template>
<script>
export default {
}
</script>
<style scoped>
img{
width: 100%;
}
</style>
在main.js - 修改路由配置
import NotFound from '@/views/NotFound'
const routes = [
// ...省略了其他配置
// 404在最后(規(guī)則是從前往后逐個(gè)比較path)
{
path: "*",
component: NotFound
}
]
路由 - 模式設(shè)置
- 修改路由在地址欄的模式( hash 模式 或者 history 模式 )
- hash路由例如: http://localhost:8080/#/home
- history路由例如: http://localhost:8080/home (以后上線需要服務(wù)器端支持, 否則找的是文件夾)
router/index.js
const router = new VueRouter({
routes,
mode: "history" // 打包上線后需要后臺(tái)支持, 模式是hash
})
vue路由 - 編程式導(dǎo)航
- 用JS代碼跳轉(zhuǎn), 聲明式導(dǎo)航用a標(biāo)簽
main.js - 路由數(shù)組里, 給路由起名字
{
path: "/find",
name: "Find",
component: Find
},
{
path: "/my",
name: "My",
component: My
},
{
path: "/part",
name: "Part",
component: Part
},
App.vue - 換成span 配合js的編程式導(dǎo)航跳轉(zhuǎn)
<template>
<div>
<div class="footer_wrap">
<span @click="btn('/find', 'Find')">發(fā)現(xiàn)音樂</span>
<span @click="btn('/my', 'My')">我的音樂</span>
<span @click="btn('/part', 'Part')">朋友</span>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
<script>
// 目標(biāo): 編程式導(dǎo)航 - js方式跳轉(zhuǎn)路由
// 語法:
// this.$router.push({path: "路由路徑"})
// this.$router.push({name: "路由名"})
// 注意:
// 雖然用name跳轉(zhuǎn), 但是url的hash值還是切換path路徑值
// 場景:
// 方便修改: name路由名(在頁面上看不見隨便定義)
// path可以在url的hash值看到(盡量符合組內(nèi)規(guī)范)
export default {
methods: {
btn(targetPath, targetName){
// 方式1: path跳轉(zhuǎn)
this.$router.push({
// path: targetPath,
name: targetName
})
}
}
};
</script>
編程式導(dǎo)航 - 跳轉(zhuǎn)傳參
- JS跳轉(zhuǎn)路由, 傳參
- query / params 任選 一個(gè)
- 注意: 使用path會(huì)自動(dòng)忽略params
<template>
<div>
<div class="footer_wrap">
<span @click="btn('/find', 'Find')">發(fā)現(xiàn)音樂</span>
<span @click="btn('/my', 'My')">我的音樂</span>
<span @click="oneBtn">朋友-小黑</span>
<span @click="twoBtn">朋友-小白</span>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
<script>
// 目標(biāo): 編程式導(dǎo)航 - 跳轉(zhuǎn)路由傳參
// 方式1:
// params => $route.params.參數(shù)名
// 方式2:
// query => $route.query.參數(shù)名
// 重要: path會(huì)自動(dòng)忽略params
// 推薦: name+query方式傳參
// 注意: 如果當(dāng)前url上"hash值和?參數(shù)"與你要跳轉(zhuǎn)到的"hash值和?參數(shù)"一致, 爆出冗余導(dǎo)航的問題, 不會(huì)跳轉(zhuǎn)路由
export default {
methods: {
btn(targetPath, targetName){
// 方式1: path跳轉(zhuǎn)
this.$router.push({
// path: targetPath,
name: targetName
})
},
oneBtn(){
this.$router.push({
name: 'Part',
params: {
username: '小黑'
}
})
},
twoBtn(){
this.$router.push({
name: 'Part',
query: {
name: '小白'
}
})
}
}
};
</script>
vue路由 - 守衛(wèi)
- 路由跳轉(zhuǎn)之前, 先執(zhí)行一次前置守衛(wèi)函數(shù), 判斷是否可以正常跳轉(zhuǎn)
- next()放行, next(false)留在原地不跳轉(zhuǎn)路由, next(path路徑)強(qiáng)制換成對(duì)應(yīng)path路徑跳轉(zhuǎn)
// 目標(biāo): 路由守衛(wèi)
// 場景: 當(dāng)你要對(duì)路由權(quán)限判斷時(shí)
// 語法: router.beforeEach((to, from, next)=>{//路由跳轉(zhuǎn)"之前"先執(zhí)行這里, 決定是否跳轉(zhuǎn)})
// 參數(shù)1: 要跳轉(zhuǎn)到的路由 (路由對(duì)象信息) 目標(biāo)
// 參數(shù)2: 從哪里跳轉(zhuǎn)的路由 (路由對(duì)象信息) 來源
// 參數(shù)3: 函數(shù)體 - next()才會(huì)讓路由正常的跳轉(zhuǎn)切換, next(false)在原地停留, next("強(qiáng)制修改到另一個(gè)路由路徑上")
// 注意: 如果不調(diào)用next, 頁面留在原地
// 例子: 判斷用戶是否登錄, 是否決定去"我的音樂"/my
const isLogin = true; // 登錄狀態(tài)(未登錄)
router.beforeEach((to, from, next) => {
if (to.path === "/my" && isLogin === false) {
alert("請(qǐng)登錄")
next(false) // 阻止路由跳轉(zhuǎn)
} else {
next() // 正常放行
}
})