基本語法
1.1、初時Vue
1.想讓Vue工作,就必須創(chuàng)建一個Vue實例,且要傳入一個配置對象;
2.root容器里的代碼依然符合html規(guī)范,只不過混入了一些特殊的Vue語法;
3.root容器里的代碼被稱為【Vue模板】;
4.Vue實例和容器是一一對應的;
5.真實開發(fā)中只有一個Vue實例,并且會配合著組件一起使用;
6.{{xxx}}中的xxx要寫js表達式,且xxx可以自動讀取到data中的所有屬性;
7.一旦data中的數(shù)據(jù)發(fā)生改變,那么頁面中用到該數(shù)據(jù)的地方也會自動更新;
注意區(qū)分:js表達式 和 js代碼(語句)
1.表達式:一個表達式會產(chǎn)生一個值,可以放在任何一個需要值的地方:
(1). a
(2). a+b
(3). demo(1)
(4). x === y ? 'a' : 'b'
2.js代碼(語句)
(1). if(){}
(2). for(){}
1.2、插值語法{{}}
Vue模板語法有2大類:
1.插值語法:
功能:用于解析標簽體內容。
寫法:{{xxx}},xxx是js表達式,且可以直接讀取到data中的所有屬性。
** 2.指令語法:**
功能:用于解析標簽(包括:標簽屬性、標簽體內容、綁定事件…)。
舉例:v-bind:href=“xxx” 或 簡寫為 :href=“xxx”,xxx同樣要寫js表達式,
且可以直接讀取到data中的所有屬性。
備注:Vue中有很多的指令,且形式都是:v-???,此處我們只是拿v-bind舉個例子。
1.3、綁定屬性
Vue中有2種數(shù)據(jù)綁定的方式:
1.單向綁定(v-bind):數(shù)據(jù)只能從data流向頁面。
2.雙向綁定(v-model):數(shù)據(jù)不僅能從data流向頁面,還可以從頁面流向data。
備注:
1.雙向綁定一般都應用在表單類元素上(如:input、select等)
2.v-model:value 可以簡寫為 v-model,因為v-model默認收集的就是value值。
<!-- 普通寫法 -->
單向數(shù)據(jù)綁定:<input type="text" v-bind:value="name"><br/>
雙向數(shù)據(jù)綁定:<input type="text" v-model:value="name"><br/>
<!-- 簡寫 -->
單向數(shù)據(jù)綁定:<input type="text" :value="name"><br/>
雙向數(shù)據(jù)綁定:<input type="text" v-model="name"><br/>
1.3.1綁定樣式
<template>
<div>
<!--綁定樣式-->
<div :style="['font-size:50px','color:red']">box</div>
<div :style="[fontSize,bgColor]">box</div>
<hr>
<!--綁定類-->
<!-- <div class="one" :class="'two'">aaaaaaaa</div>-->
<div class="one" :class="two">aaaaaaaa</div>
<!-- <div class="one" :class="['one','two']">aaaaaaaa</div>-->
<!--數(shù)組方式-->
<div class="one" :class="[one,two]">元素為變量</div>
<div class="one" :class="boxStyle">數(shù)組為變量</div>
<hr>
<!--對象方式 {類名:真假值} 真則添加 假則不添加-->
<div :class="{one:isone,two:istwo}">{類名:真假值} 真則添加 假則不添加</div>
<div :class="{three}">鍵值相同可簡寫</div><!--鍵值相同可簡寫-->
<!--函數(shù)返回值方式-->
<div :class="getStyleObj()">函數(shù)返回對象</div>
<div :class="getStyleArr()">函數(shù)返回數(shù)組</div>
</div>
</template>
<script>
/*
* 單向綁定 v-bind 簡寫 :
*
* */
export default {
name: 'App',
data() {
return {
size: 100,
fontSize: 'font-size:50px',
bgColor: 'background-color:blue',
two: 'two',
one: 'one ',
boxStyle: ['one', 'two'],
isone: false,
istwo: true,
three: true,
};
},
methods: {
getStyleArr() {
return [this.one, this.two];
},
getStyleObj() {
return { one: this.isone, two: this.istwo };
},
},
};
</script>
1.4、計算屬性
1.定義:要用的屬性不存在,要通過已有屬性計算得來。
2.原理:底層借助了Objcet.defineproperty方法提供的getter和setter。
3.get函數(shù)什么時候執(zhí)行?
(1).初次讀取時會執(zhí)行一次。
(2).當依賴的數(shù)據(jù)發(fā)生改變時會被再次調用。
4.優(yōu)勢:與methods實現(xiàn)相比,內部有緩存機制(復用),效率更高,調試方便。
5.備注:
(1)計算屬性最終會出現(xiàn)在vm上,直接讀取使用即可。
(2)如果計算屬性要被修改,那必須寫set函數(shù)去響應修改,且set中要引起計算時依賴的數(shù)據(jù)發(fā)生改變。
computed:{
fullName:{
//get有什么作用?當有人讀取fullName時,get就會被調用,且返回值就作為fullName的值
//get什么時候調用?1.初次讀取fullName時。2.所依賴的數(shù)據(jù)發(fā)生變化時。
get(){
console.log('get被調用了')
// console.log(this) //此處的this是vm
return this.firstName + '-' + this.lastName
},
//set什么時候調用? 當fullName被修改時。
set(value){
console.log('set',value)
const arr = value.split('-')
this.firstName = arr[0]
this.lastName = arr[1]
}
}
}
1.5、事件監(jiān)聽
在前端開發(fā)中,需要經(jīng)常和用戶交互
綁定事件監(jiān)聽器指令:v-on
縮寫: @ (語法糖)
參數(shù): $event
v-on事件修飾符號
–.stop 阻止事件冒泡
–.self 當事件在該元素本身觸發(fā)時才觸發(fā)事件
–.capture 添加事件偵聽器是,使用事件捕獲模式
–.prevent 阻止默認事件
–.once 事件只觸發(fā)一次
1.6、條件分支指令v-if和v-show
1.v-if
寫法:
(1).v-if=“表達式”
(2).v-else-if=“表達式”
(3).v-else=“表達式”
適用于:切換頻率較低的場景。
** 特點:不展示的DOM元素直接被移除。**
注意:v-if可以和:v-else-if、v-else一起使用,但要求結構不能被“打斷”。
2.v-show
寫法:v-show=“表達式”
適用于:切換頻率較高的場景。
特點:不展示的DOM元素未被移除,僅僅是使用樣式隱藏掉(display:none)
3.備注:使用v-if的時,元素可能無法獲取到,而使用v-show一定可以獲取到。
1.7、循環(huán)遍歷指令v-for
v-for指令:
1.用于展示列表數(shù)據(jù)
2.語法:v-for=“(item, index) in xxx” :key=“yyy”
3.可遍歷:數(shù)組、對象、字符串(用的很少)、指定次數(shù)(用的很少)
<!-- 遍歷數(shù)組 -->
<h2>人員列表(遍歷數(shù)組)</h2>
<ul>
<li v-for="(p,index) of persons" :key="index">
{{p.name}}-{{p.age}}
</li>
</ul>
<!-- 遍歷對象 -->
<h2>汽車信息(遍歷對象)</h2>
<ul>
<li v-for="(value,k) of car" :key="k">
{{k}}-{{value}}
</li>
</ul>
<!-- 遍歷字符串 -->
<h2>測試遍歷字符串(用得少)</h2>
<ul>
<li v-for="(char,index) of str" :key="index">
{{char}}-{{index}}
</li>
</ul>
<!-- 遍歷指定次數(shù) -->
<h2>測試遍歷指定次數(shù)(用得少)</h2>
<ul>
<li v-for="(number,index) of 5" :key="index">
{{index}}-{{number}}
</li>
</ul>
補充:key的原理
:::info
面試題:react、vue中的key有什么作用?(key的內部原理)
1. 虛擬DOM中key的作用:
key是虛擬DOM對象的標識,當數(shù)據(jù)發(fā)生變化時,Vue會根據(jù)【新數(shù)據(jù)】生成【新的虛擬DOM】,
隨后Vue進行【新虛擬DOM】與【舊虛擬DOM】的差異比較,比較規(guī)則如下:
2.對比規(guī)則:
(1).舊虛擬DOM中找到了與新虛擬DOM相同的key:
①.若虛擬DOM中內容沒變, 直接使用之前的真實DOM!
②.若虛擬DOM中內容變了, 則生成新的真實DOM,隨后替換掉頁面中之前的真實DOM。
(2).舊虛擬DOM中未找到與新虛擬DOM相同的key
創(chuàng)建新的真實DOM,隨后渲染到到頁面。
3. 用index作為key可能會引發(fā)的問題:
1. 若對數(shù)據(jù)進行:逆序添加、逆序刪除等破壞順序操作:
會產(chǎn)生沒有必要的真實DOM更新 ==> 界面效果沒問題, 但效率低。
2. 如果結構中還包含輸入類的DOM:
會產(chǎn)生錯誤DOM更新 ==> 界面有問題。
4. 開發(fā)中如何選擇key?:
1.最好使用每條數(shù)據(jù)的唯一標識作為key, 比如id、手機號、身份證號、學號等唯一值。
2.如果不存在對數(shù)據(jù)的逆序添加、逆序刪除等破壞順序操作,僅用于渲染列表用于展示,
使用index作為key是沒有問題的。
:::
1.8、v-model雙向綁定
v-model的修飾符號:
.lazy 懶加載修飾符
.number 修飾符讓其轉換為 number 類型
.trim修飾符可以自動過濾掉輸入框的首尾空格
1.9、v-model在表單中的應用
1.9.1、單選框
1、使用v-model 可以代替name 變量相同則代表同組
2、單選框狀態(tài)發(fā)生改變時 會把value中的數(shù)據(jù)傳到 v-model綁定的變量中
3、初始選項不必再使用checked ,直接給變量賦初值即可
<input type="radio" name="sex" value="女">女-->
<input type="radio" value="男" v-model="sex">男
<input type="radio" value="女" v-model="sex">女
<br>{{sex}}
data() {
return {
msg: 'this is a test',
sex:'男',
isRead:false,
hobby:[],
language:'vue',
languages:'vue',
}
1.9.2、多選框
1、當只需要一個復選框為真假值判斷的時候,v-model傳遞一個布爾值,會自動根據(jù)選種情況來改變 變量值的真或假
2、當需要多個復選框同組使用時 , 需要使用數(shù)組變量接收 ,會把選中項的value值存到數(shù)組中
使用v-model 可以代替name 變量相同則代表同組
<input type="checkbox" v-model="isRead">我已閱讀協(xié)議{{isRead}}
<br>
<input type="checkbox" v-model="hobby" value="smoke">抽煙
<input type="checkbox" v-model="hobby" value="drink">喝酒
<input type="checkbox" v-model="hobby" value="hotHead">燙頭
<br>
{{hobby}}
data() {
return {
msg: 'this is a test',
sex:'男',
isRead:false,
hobby:[],
language:'vue',
languages:'vue',
}
1.9.3、下拉列表
1、單選時
1)v-model綁定在select標簽上 可以代替name的功能
2)使用一個字符串接受選中value值
3)設置初始選項時可以將目標選項的value賦給字符串變量
2、多選時 multiple
會自動將變量轉成數(shù)組類型,并將選中選項的value值存到數(shù)組中
<select v-model="language">
<option value="java">java</option>
<option value="php">php</option>
<option value="vue">vue</option>
<option value="python">python</option>
</select>
{{language}}
<br>
<select v-model="languages" multiple>
<option value="java">java</option>
<option value="php">php</option>
<option value="vue">vue</option>
<option value="python">python</option>
</select>
{{languages}}
data() {
return {
msg: 'this is a test',
sex:'男',
isRead:false,
hobby:[],
language:'vue',
languages:'vue',
}
組件化開發(fā)
- 組件化是Vue的精髓,Vue開發(fā)就是由一個一個的組件構成的。
- 組件的分類:
- 頁面級組件
- 業(yè)務上可復用的基礎組件
- 與業(yè)務無關的獨立功能組件
- 組件開發(fā)三要素(prop,自定義事件,slot)
- prop用于定義組件的屬性。
- 自定義事件用于觸發(fā)組件的事件。
- slot用于組件功能的擴展。
- 組件設計需要考慮的問題
- 可擴展性強
- 組件中方法函數(shù)的抽離,便于復用,適用程度高。
- 文檔清楚詳細
- 顆粒度合適,適度抽象
- 功能盡可能單一,代碼行數(shù)適中
2.1、父子組件之間的通信
2.1.1、父組件向子組件傳數(shù)據(jù) 父=>子
props配置項
- 功能:讓組件接收外部傳過來的數(shù)據(jù) , 接收到后用法和data中數(shù)據(jù)一樣 (父 ==> 子)
- 傳遞數(shù)據(jù):
- 接收數(shù)據(jù):
- 第一種方式(只接收):props:[‘name’]
- 第二種方式(限制類型):props:{name:String}
- 第三種方式(限制類型、限制必要性、指定默認值):
:::info
props:{
name:{
type:String, //類型
required:true, //必要性 不傳則警告
default:‘老王’ //默認值
}
}
:::
_ 備注:props是只讀的,Vue底層會監(jiān)測你對props的修改,如果進行了修改,就會發(fā)出警告,_
_ 若業(yè)務需求確實需要修改,那么請復制props的內容到data中一份,然后去修改data中的數(shù)據(jù)。_
//父組件
<my-conn :article="article"></my-conn>
//子組件
<li v-for="item in article">{{item}}</li>
export default {
name: "MyConn",
props:{
article:{
type:Array,
}
}
}
2.1.2、子組件向父組件傳數(shù)據(jù) 子=>父
**通過自定義事件
e
m
i
t
(
)
和事件監(jiān)聽實現(xiàn)
?
?
子組件通過使用
t
h
i
s
.
emit()和事件監(jiān)聽實現(xiàn)** 子組件通過使用this.
emit()和事件監(jiān)聽實現(xiàn)??子組件通過使用this.emit(‘自定義事件名稱’,傳遞參數(shù)data)
父組件通過在組件標簽上使用<子組件 @自定義事件名稱=“方法fun”></子組件>
fun(子組件傳遞的參數(shù)data){}
//子組件 my-conn
<button @click="changeNum(2)">++++</button>
methods:{
changeNum(n){
this.$emit("myCountEvent",n)
}
}
//父組件
<my-conn @myCountEvent="myDemo"></my-conn>
methods:{
myDemo(data){
this.count += data
}
}
2.2父子組件之間的訪問方式
2.2.1、子組件訪問父組件:
可以通過$parent獲取父組件中的屬性和方法,可連續(xù)調用訪問多層
如果訪問跟組件可直接調用$root方法
2.2.2、父組件訪問子組件:
在Vue2中可以使用$children 獲取一個子組件數(shù)組,Vue3刪除了該方法
可以先使用 ref屬性標記子組件 (類似id屬性) ref="xxx"
再調用 $refs.xxx 獲取子組件
2.3、插槽
- 作用:讓父組件可以向子組件指定位置插入html結構,也是一種組件間通信的方式,
適用于父組件 ===> 子組件。 - 分類:默認插槽、具名插槽、作用域插槽
2.3.1、默認插槽
<!-- 默認插槽 ==>父組件 -->
<MyBar>
<button>默認插槽--提交</button>
</MyBar>
<!-- 默認插槽 ==>子組件-->
<slot>默認值</slot>
2.3.2、具名插槽
:::info
需要使用包裹內容
template中設置屬性
1. v-slot:子組件中插槽name值 簡寫 #子組件中插槽name值
2. Vue2中還可使用 slot=“子組件中插槽name值” Vue3已刪除
:::
<!-- 具名插槽 ==>父組件-->
<MyBar>
<template v-slot:btn>
<button>具名插槽--提交</button>
</template>
<template #one>
<a href="">具名插槽--one</a>
</template>
<template #two>
<a href="">具名插槽--two</a>
</template>
</MyBar>
<!-- 具名插槽 ==>子組件-->
<slot name="btn">默認值1</slot>
<br>
<slot name="one">默認值2</slot>
<br>
<slot name="two">默認值3</slot>
<br>
2.3.3、作用域插槽
:::info
理解:數(shù)據(jù)在組件的自身,但根據(jù)數(shù)據(jù)生成的結構需要組件的使用者來決定。
(userinfo和school數(shù)據(jù)在子組件Mybar中,但使用數(shù)據(jù)所遍歷出來的結構由父組件MySidebar決定)
使用方法 :
v-slot:子組件中插槽的name值=“自定義對象” ,子組件傳的所有數(shù)據(jù)都會存到自定義的對象中
簡寫:#子組件中插槽的name值=“自定義對象”
:::
<!--作用域插槽 ==>父組件 -->
<MyBar>
<!-- <template v-slot:user="user">-->
<template #user="hello">
<p>作用域插槽--{{hello.userinfo.name}}-{{hello.userinfo.age}}--{{hello.userinfo.sex}}</p>
<p v-for="item in hello.school">{{item}}</p>
</template>
</MyBar>
<!-- 作用域插槽 ==>子組件-->
<slot name="user" :userinfo="userinfo" :school="school"></slot>
data(){
return{
title:"this is a title",
userinfo:{name:'張三',age:24,sex:'男'},
school:['融職教育','清華大學','北京大學','麻省理工']
}
}
2.4、Vue中組件的生命周期函數(shù)
- (1)初始化顯示
- beforeCreate()
- created()
- beforeMount()
- mounted()
- (2)更新狀態(tài): this.xxx = value
- beforeUpdate()
- updated()
- (3)銷毀 vue 實例: vm.$destory()
Vue2- beforeDestory()
- destoryed()
Vue3
-
beforeUnmount()
-
unmounted()
-
(4) nextTick
- 語法:
this.$nextTick(回調函數(shù))
- 作用:在下一次 DOM 更新結束后執(zhí)行其指定的回調。
- 什么時候用:當改變數(shù)據(jù)后,要基于更新后的新DOM進行某些操作時,要在nextTick所指定的回調函數(shù)中執(zhí)行。
- 語法:
-
(5)Vue-router的生命周期鉤子
:::info
:::-
- 作用:路由組件所獨有的兩個鉤子,用于捕獲路由組件的激活狀態(tài)。
-
- 具體名字:
activated路由組件被激活時觸發(fā)。
? ? ? ? ? ?deactivated路由組件失活時觸發(fā)。
2.5、Vue網(wǎng)絡請求axios
import axios from "axios";
const server = axios.create({
baseURL: 'https://api.shop.eduwork.cn',
timeout: 10000,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
//請求攔截器
server.interceptors.request.use(
config => {
console.log('-------------------請求攔截器----------------------')
config.headers.Authorization = `Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2FwaS5zaG9wLmVkdXdvcmsuY24vYXBpL2F1dGgvbG9naW4iLCJpYXQiOjE2ODE4MTk0OTQsImV4cCI6MTY4MjE3OTQ5NCwibmJmIjoxNjgxODE5NDk0LCJqdGkiOiJ4clZ6c2ZVelpySVJnYk1wIiwic3ViIjoiODk0MiIsInBydiI6IjIzYmQ1Yzg5NDlmNjAwYWRiMzllNzAxYzQwMDg3MmRiN2E1OTc2ZjcifQ.vsKQvw9m0HhWfUbzJuOvBvWVK4BnAxi-vOSNCkBwJoQ`
return config
},
err => {
return Promise.reject(error)
}
)
//響應攔截器
server.interceptors.response.use(
resp => {
console.log('-------------------響應攔截器----------------------')
return resp
},
err => {
return Promise.reject(err)
}
)
export function get(url) {
return server.get(url)
}
export function getParams(url, params) {
return server.get(url, {params})
}
export function post(url, params) {
return server.post(url, params)
}
export function put(url, params) {
return server.put(url, params)
}
export function del(url, params) {
return server.delete(url, params)
}
Vue Router 路由
3.1、基本使用
- 安裝vue-router,命令:
npm i vue-router
- 應用插件:
Vue.use(VueRouter)
import router from './router'
createApp(App).use(router).mount('#app')
- 配置:
//引入路由的創(chuàng)建方法和模式
import {createRouter,createWebHistory} from 'vue-router'
//引入組件
import About from "@/view/About";
import Home from "@/view/Home";
import User from "@/view/User";
// 聲明變量
const routes = [
{
path:'/',
name:'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
},
{
path: '/user',
name: 'User',
component: User
}
]
//創(chuàng)建路由
const router = createRouter({
history:createWebHistory(process.env.BASE_URL), //歷史模式
// routes:routes,
routes
})
export default router
- 實現(xiàn)路由切換
<router-link to="/">首頁</router-link> |
<router-link active-class="active" to="/about">關于我們</router-link> |
<router-link to="/user">個人中心</router-link>
//active-class="active" 當跳轉到當前路由時添加active類樣式
- 指定顯示位置
:::info
:::
3.2 幾個注意點
- 路由組件通常存放在view文件夾,一般組件通常存放在components文件夾。
- 通過切換,“隱藏”了的路由組件,默認是被銷毀掉的,需要的時候再去掛載。
- 每個組件都有自己的$route屬性,里面存儲著自己的路由信息。
- 整個應用只有一個router,可以通過組件的$router屬性獲取到。
3.3 路由模式切換和懶加載
路由是由多個URL組成的,使用不同的URL可以相應的導航到不同的位置
Vue-Router在切換頁面時是沒有重新進行請求的,使用起來就好像頁面是有狀態(tài)的一樣
借助了瀏覽器的History API來實現(xiàn)的,這樣可以使得頁面跳轉而不刷新,頁面的狀態(tài)就被維持在瀏覽器中
vue-router中默認使用的是hash模式,也就是會出現(xiàn)如URL:‘localhost:8080/#/’ URL中帶有#號
有三種模式
Hash: 使用URL的hash值來作為路由,用來指導瀏覽器動作的,對服務器端完全無用,支持所有瀏覽器。
History: 以來HTML5 History API 和服務器配置。
Abstract: 支持所有javascript運行模式。如果發(fā)現(xiàn)沒有瀏覽器的API,路由會自動強制進入這個模式。
引入路由
:::info
//引入路由的創(chuàng)建方法和模式
import {createRouter,createWebHistory,createWebHashHistory} from ‘vue-router’
:::
創(chuàng)建路由
const router = createRouter({
//設計模式
history:createWebHistory(process.env.BASE_URL), //歷史模式
// history:createWebHashHistory(process.env.BASE_URL),//哈希模式
//定義路由組件
/*
routes:[
{
path:'/',
name:'Home',
component: Home
},
]
*/
//外部引入變量方式
// routes:routes,
//簡寫
routes
})
引入組件的方式
方式一:普通方式:
打包時會將所有路由全部打包到一個js文件中,并加載全部組件
//引入組件
import Home from "@/view/Home";
import About from "@/view/About";
import User from "@/view/User";
const routes = [
{
path:'/',
name:'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
},
{
path: '/user',
name: 'User',
component:User
}
]
方式二:懶加載:
通過下面方法引入組件,會在打包時會打包成多個js文件,訪問哪個路由加載哪個js文件(懶加載) — 加載速度快
const routes = [
{
path:'/',
name:'Home',
component: ()=>import('../view/Home')
},
{
path: '/about',
name: 'About',
component: About
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
//通過下面方法引入組件,會在打包時會打包成多個js文件,訪問哪個路由加載哪個js文件(懶加載) --- 加載速度快
/* component: () => import(/!* webpackChunkName: "about" *!/ '../views/About.vue')*/
/*component: ()=>{return import('../view/About')}*/
component: ()=>import('../view/About')
},
{
path: '/user',
name: 'User',
component:()=>import('../view/User')
}
]
拆分寫法
//引入路由的創(chuàng)建方法和模式
import {createRouter,createWebHistory,createWebHashHistory} from 'vue-router'
const Home = ()=> import('../view/Home')
const About = ()=> import('../view/About')
const User = ()=> import('../view/User')
// 聲明變量
const routes = [
{
path:'/',
name:'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
},
{
path: '/user',
name: 'User',
component:User
}
]
//創(chuàng)建路由
const router = createRouter({
//設計模式
history:createWebHistory(process.env.BASE_URL), //歷史模式
// history:createWebHashHistory(process.env.BASE_URL),//哈希模式
// routes:routes,
routes
})
export default router
使用路由:在入口js文件中
import {createApp} from 'vue'
import App from './App'
import router from './router'
createApp(App).use(router).mount('#app')
3.4 自定義標簽
標簽在打包時會編譯成a標簽,如果想要自定義其他標簽的話在Vue3中需要通過以下方法:
<router-link to="/about" custom v-slot="{navigate}">
<button @click="navigate" @keypress.enter="navigate" role="link">關于我們</button>
</router-link>
//或
// 通過在全局路由追加歷史記錄實現(xiàn)
<button @click="$router.push('/user')" :class="{active:$route.path ==='/user'}">個人中心</button>
$router 表示全局路由
$route 表示當前路由
3.5 <router-link>的replace屬性
- 作用:控制路由跳轉時操作瀏覽器歷史記錄的模式
- 瀏覽器的歷史記錄有兩種寫入方式:分別為
push
和replace
,push
是追加歷史記錄,replace
是替換當前記錄。路由跳轉時候默認為push
- 如何開啟
replace
模式:<router-link replace .......>News</router-link>
3.6 嵌套路由
- 配置路由規(guī)則,使用children配置項:
const routes = [
{
path:'/',
name:'Home',
component: Home
},
{
path: '/user',
name: 'User',
component:User,
// /user/order
children: [
{
path:'', //默認頁面
component:MyOrder,
},
{
path:'order', //此處一定不要寫:/order
name:'MyOrder',
component:MyOrder,
},
{
path:'setting', //此處一定不要寫:/setting
name:'MySetting',
component:MySetting,
},
{
path:'page/:id',
name:'MyPage',
component:MyPage,
},
]
}
]
- 跳轉**(要寫完整路徑)**
<router-link to="/user/order">我的訂單</router-link>
<br>
<router-link to="/user/setting">個人設置</router-link>
3.7 參數(shù)傳遞
3.7.1 query參數(shù)
- 傳遞參數(shù)
<!-- 跳轉并攜帶query參數(shù),to的字符串寫法 -->
<router-link :to="/home/message/detail?id=666&title=你好">跳轉</router-link>
<!-- 跳轉并攜帶query參數(shù),to的對象寫法 -->
<router-link
:to="{
path:'/home/message/detail',
query:{
id:666,
title:'你好'
}
}"
>跳轉</router-link>
- 接收參數(shù):
$route.query.id
$route.query.title
3.7.2 命名路由
- 作用:可以簡化路由的跳轉。
- 如何使用
- 給路由命名:
{
path:'/demo',
component:Demo,
children:[
{
path:'test',
component:Test,
children:[
{
name:'hello' //給路由命名
path:'welcome',
component:Hello,
}
]
}
]
}
- 簡化跳轉:
<!--簡化前,需要寫完整的路徑 -->
<router-link to="/demo/test/welcome">跳轉</router-link>
<!--簡化后,直接通過名字跳轉 -->
<router-link :to="{name:'hello'}">跳轉</router-link>
<!--簡化寫法配合傳遞參數(shù) -->
<router-link
:to="{
name:'hello',
query:{
id:666,
title:'你好'
}
}"
>跳轉</router-link>
3.7.3 params參數(shù)
- 配置路由,聲明接收params參數(shù)
{
path:'/home',
component:Home,
children:[
{
path:'news',
component:News
},
{
component:Message,
children:[
{
name:'xiangqing',
path:'detail/:id/:title', //使用占位符聲明接收params參數(shù)
component:Detail
}
]
}
]
}
- 傳遞參數(shù)
<!-- 跳轉并攜帶params參數(shù),to的字符串寫法 -->
<router-link :to="/home/message/detail/666/你好">跳轉</router-link>
<!-- 跳轉并攜帶params參數(shù),to的對象寫法 -->
<router-link
:to="{
name:'xiangqing',
params:{
id:666,
title:'你好'
}
}"
>跳轉</router-link>
特別注意:路由攜帶params參數(shù)時,若使用to的對象寫法,則不能使用path配置項,必須使用name配置!
- 接收參數(shù):
$route.params.id
$route.params.title
3.7.4路由的props配置
作用:讓路由組件更方便的收到參數(shù)
{
name:'xiangqing',
path:'detail/:id',
component:Detail,
//第一種寫法:props值為對象,該對象中所有的key-value的組合最終都會通過props傳給Detail組件
// props:{a:900}
//第二種寫法:props值為布爾值,布爾值為true,則把路由收到的所有params參數(shù)通過props傳給Detail組件
// props:true
//第三種寫法:props值為函數(shù),該函數(shù)返回的對象中每一組key-value都會通過props傳給Detail組件
props(route){
return {
id:route.query.id,
title:route.query.title
}
}
}
<ul>
<li>消息編號:{{id}}</li>
<li>消息標題:{{title}}</li>
</ul>
<script>
export default {
name:'Detail',
props:['id','title'],
}
</script>
3.8 編程式路由導航
- 作用:不借助
<router-link>
實現(xiàn)路由跳轉,讓路由跳轉更加靈活 - 具體編碼:
//$router的兩個API
this.$router.push({
name:'xiangqing',
params:{
id:xxx,
title:xxx
}
})
this.$router.replace({
name:'xiangqing',
params:{
id:xxx,
title:xxx
}
})
this.$router.forward() //前進;
this.$router.back() //后退
this.$router.go() //可前進也可后退
3.9 重定向和別名
重定向:跳轉到當前路由時,若此路由被重定向,則跳轉到重定向指定的路由
redirect{name:‘路由name’}
別名:別
名是 **路徑 ,**通過別名也可代替path中的路徑
單個別名:alias: ‘/a’
多個別名:alias: [‘/a’ ,‘/b’,‘/c’]
注意:原路徑有params參數(shù) 別名也需要寫
:::info
{
path:‘page/:id’,
name:‘MyPage’,
alias:[‘p/:id’],
}
:::
const routes = [
{
path:'/',
name:'HomeRoot',
component: Home
},
{
path:'/home',
name:'Home',
//重定向
// redirect:'/', //路徑
redirect:{name:'HomeRoot'}, //名字
component: Home
},
{
path: '/about',
name: 'About',
//單個別名
// alias:'/a',
//多個別名
alias:['/a','/b','/c'],
//原路徑有params參數(shù) 別名也需要寫
component: About
},
{
path: '/user',
name: 'User',
component:User,
// /user/order
children: [
{
path:'page/:id',
name:'MyPage',
//原路徑有params參數(shù) 別名也需要寫
alias:['p/:id'],
/* redirect:to=>{
//to => $route
return {path:'article',query:{name:'zhangsan',age:to.params.id}}
},*/
//縮寫 to=>({})
component:MyPage,
},
]
}
]
3.10 路由守衛(wèi)
- 作用:對路由進行權限控制
- 分類:全局守衛(wèi)、獨享守衛(wèi)、組件內守衛(wèi)
全局守衛(wèi):
//全局路由守衛(wèi)
//全局前置路由守衛(wèi)
/*Vue2中 有三個參數(shù) :to :即將進入的路由
from 要離開的路由,
next (放行)
Vue3中 可以有兩個參數(shù):to ,from,next(可選) ,是否放行取決于返回值,假則禁止放行,真或不寫則放行*/
router.beforeEach((to,from)=>{
document.title = to.meta.title;
// return false
})
//全局后置路由守衛(wèi)
router.afterEach((to,from)=>{
// console.log('afterEach',to,from)
if(to.meta.title){
document.title = to.meta.title //修改網(wǎng)頁的title
}else{
document.title = 'vue_test'
}
})
獨享守衛(wèi):
{
path:'setting', //此處一定不要寫:/setting
name:'MySetting',
beforeEnter(to,from){
console.log('beforeEnter',to,from)
if(localStorage.getItem('school') === 'rongzhi'){
return true
}else{
alert('暫無權限查看')
return false
}
},
component:MySetting,
},
組件內守衛(wèi): 在組件中使用
進入守衛(wèi):通過路由規(guī)則,進入該組件時被調用
:::info
beforeRouteEnter (to, from) {
},
:::
離開守衛(wèi):通過路由規(guī)則,離開該組件時被調用
:::info
beforeRouteLeave (to, from) {
}
:::
3.11 keep-alive和vue-router結合使用
- 作用:讓不展示的路由組件保持掛載,不被銷毀,保存在緩存中。
- 具體編碼:
Vue3中:
<router-view v-slot="{Component}">
<transition>
<keep-alive>
<component :is="Component"/>
</keep-alive>
</transition>
</router-view>
Vue2中:
<keep-alive include="News">
<router-view></router-view>
</keep-alive>
兩個新的生命周期鉤子
- 作用:路由組件所獨有的兩個鉤子,用于捕獲路由組件的激活狀態(tài)。
- 具體名字:
-
activated
路由組件被激活時觸發(fā)。 -
deactivated
路由組件失活時觸發(fā)。
VueX
概念
在Vue中實現(xiàn)集中式狀態(tài)(數(shù)據(jù))管理的一個Vue插件,對vue應用中多個組件的共享狀態(tài)進行集中式的管理(讀/寫),也是一種組件間通信的方式,且適用于任意組件間通信。
何時使用?
多個組件需要共享數(shù)據(jù)時
基本使用
- 初始化數(shù)據(jù)、配置actions、配置mutations,操作文件store.js
export default createStore({
state: {
num:0,
dnum:0,
},
getters: {
},
mutations: {
mutAdd(state){
state.dnum ++
},
mutSub(state){
state.dnum --
},
//接收一個參數(shù),參數(shù)可以使任意類型
mutAdd2(state,count){
state.dnum +=count
},
mutSub2(state,count){
state.dnum -=count
},
//接收多個參數(shù)
//將多個參數(shù)存在一個對象中
mutAdd3(state,payload){
state.dnum +=payload.count+payload.num
},
mutSub3(state,payload){
state.dnum -=payload.count+payload.num
},
//對象寫法接收
mutSub4(state,p){
state.dnum -=p.payload.count+p.payload.num
},
},
actions: {
},
modules: {
}
})
- 組件中讀取vuex中的數(shù)據(jù):$store.state.sum
- 組件中修改vuex中的數(shù)據(jù):$store.dispatch(‘a(chǎn)ction中的方法名’,數(shù)據(jù)) 或 $store.commit(‘mutations中的方法名’,數(shù)據(jù))
備注:若沒有網(wǎng)絡請求或其他業(yè)務邏輯,組件中也可以越過actions,即不寫dispatch,直接編寫commit
搭建vuex環(huán)境
- 創(chuàng)建文件:
src/store/index.js
//引入Vuex
import { createStore } from 'vuex'
//暴露
export default createStore({
//準備state對象——保存具體的數(shù)據(jù)
state: {
num:0,
},
//VueX中的計算屬性
getters: {
},
//準備mutations對象——修改state中的數(shù)據(jù)
mutations: {
},
//準備actions對象——響應組件中用戶的動作
actions: {
},
//模塊化
modules: {
}
})
- 在main.js中創(chuàng)建vm時傳入store配置項
import store from './store'
createApp(App).use(store).use(router).mount('#app')
mutations傳參問題
mutations中的方法只能接受兩個參數(shù)
第一個參數(shù):當前 state
第二個參數(shù):接收到的數(shù)據(jù)
可以接收任何類型的數(shù)據(jù),如果要傳遞多個數(shù)據(jù),則需要將數(shù)據(jù)放到一個對象中進行傳遞
組件讀取mutations中方法的方式:this.$store.commit(‘方法名’, 參數(shù))
mutations: {
mutAdd(state){
state.dnum ++
},
mutSub(state){
state.dnum --
},
//接收一個參數(shù),參數(shù)可以使任意類型
mutAdd2(state,count){
state.dnum +=count
},
mutSub2(state,count){
state.dnum -=count
},
//接收多個參數(shù)
//將多個參數(shù)存在一個對象中
mutAdd3(state,payload){
state.dnum +=payload.count+payload.num
},
mutSub3(state,payload){
state.dnum -=payload.count+payload.num
},
//對象寫法接收
mutSub4(state,p){
state.dnum -=p.payload.count+p.payload.num
},
},
調用mutations中的方法
subMut() {
//調用Vuex中mutation中的方法
//this.$store.commit.('方法名')
this.$store.commit('mutSub')
},
subTwo() {
let count = 2
this.$store.commit('mutSub2', count)
},
addThree() {
/*let count = 2
let num = 1*/
let payload = {
count: 2,
num: 1
}
//commit只有兩個參數(shù),如果想傳多個參數(shù)則需要放到一個對象里
this.$store.commit('mutAdd3', payload)
},
subThree() {
let payload={
count:2,
num:1
}
// this.$store.commit('mutSub3',payload)
// 對象寫法
this.$store.commit({
type: 'mutSub4', //方法名
/*payload: {
count: 2,
num: 1
}*/
payload
})
}
vuex中的計算屬性getters應用
- 概念:當state中的數(shù)據(jù)需要經(jīng)過加工后再使用時,可以使用getters加工。
- 組件中讀取數(shù)據(jù):$store.getters.方法名
:::info
getters中定義的方法有兩個參數(shù)
第一個參數(shù)就是state
第二個getters
如果想要傳參數(shù)的話需要通過返回回調函數(shù),并將要傳的參數(shù)作為回調函數(shù)的參數(shù)
:::
vxNum(state) {
return state.num * state.num
},
booksPrice(state) {
let priceSum;
priceSum = state.books.reduce((s, n) => {
return s + n.price
}, 0)
return priceSum
},
booksGet(state) {
return state.books.filter(book=>{
return book.price >30
})
},
booksGet1(state,getters) {
//參入以回調函數(shù)參數(shù)形式傳入
return function (price) {
return state.books.filter(book=>{
return book.price > price
})
}
/*return state.books.filter(book=>{
return book.price >30
})*/
},
//組件中
<h2>getter中的計算屬性</h2>
<h3>{{$store.getters.vxNum}}</h3>
<h1>全部圖書的總價</h1>
<h2>{{$store.getters.booksPrice}}</h2>
<h1>價格大于30的數(shù)的圖書</h1>
<h2>{{$store.getters.booksGet}}</h2>
<h1>價格大于30的數(shù)的圖書總價</h1>
<h2>{{$store.getters.booksPrice1}}</h2>
<h1>參數(shù)傳遞:價格大于20的數(shù)的圖書</h1>
<h2>{{$store.getters.booksGet1(20)}}</h2>
actions異步處理操作
:::info
參數(shù):第一個參數(shù) context 代表上下文
相當于組件中的 this.
s
t
o
r
e
第二個參數(shù)和
m
u
t
a
t
i
o
n
s
中方法的第二個參數(shù)一樣
,
負責接收數(shù)據(jù)
:
:
:
組件中獲取
a
c
t
i
o
n
s
中方法的方式:
?
?
t
h
i
s
.
store 第二個參數(shù)和mutations中方法的第二個參數(shù)一樣,負責接收數(shù)據(jù) ::: 組件中獲取actions中方法的方式:**this.
store第二個參數(shù)和mutations中方法的第二個參數(shù)一樣,負責接收數(shù)據(jù):::組件中獲取actions中方法的方式:??this.store.dispatch(‘方法名’,參數(shù))**
demo(context){
setTimeout(()=>{
// context.state.num = 99;
context.commit('mutAdd')
},3000)
},
context中的方法: 可以使用解構賦值選擇調用
1.commit
2.dispatch
3.getters
4.state
5.rootGetters 獲取根中的getters
6.rootState 獲取根中的state
fun2({state,commit,getters},payload){
// const {state,commit} = context
setTimeout(()=>{
state.num=99+payload.num1
commit('cnum')
},100)
}
注意:若沒有網(wǎng)絡請求或其他業(yè)務邏輯,組件中也可以越過actions,即不寫dispatch,直接編寫****commit
module模塊劃分
modules: {
//拆分成多個模塊
//普通形式
user:{
state:{
},
getters:{},
mutations:{},
actions:{}
},
//聲明調用分開
article:article,
//簡寫
cart,
goods,
}
const article = {
//在模塊中state狀態(tài)需要放在函數(shù)里面返回 類似 data(){return{}}
state:()=>({
name:'lmonkey',
slogen:'abc'
}),
getters:{
fullname(state){
return state.name+state.slogen
},
fullname2(state,getters){
//本模塊中的getters
return getters.fullname+"222222"
},
fullname3(state,getters,rootState){
//rootState 根
//調用根中的state
return getters.fullname2+rootState.books[0].name
}
},
mutations:{
setname(state,payload){
state.name = payload.name
}
},
actions:{
demosome(context,payload){
/* context中的方法: 可以使用解構賦值選擇調用
1.commit
2.dispatch
3.getters
4.state
5.rootGetters 獲取根中的getters
6.rootState 獲取根中的state
*/
// console.log(context)
setTimeout(()=>{
context.commit('setname',payload)
},2000)
}
}
}
const cart = {
state:{
},
getters:{},
mutations:{},
actions:{}
}
const goods = {
state:{
},
getters:{},
mutations:{},
actions:{}
}
如果在模塊中想要獲取根中的數(shù)據(jù)
在getters中,可以直接使用第三個參數(shù)rootState,獲取根中的狀態(tài)
在actions中,可以使用context中的rootState或rootGetters文章來源:http://www.zghlxwxcb.cn/news/detail-821517.html
組合式API
https://vue3js.cn/vue-composition-api/文章來源地址http://www.zghlxwxcb.cn/news/detail-821517.html
到了這里,關于Vue3腳手架筆記的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!