Vue-router
路由的核心:改變URL,頁面不會整體刷新
一、創(chuàng)建項目
1、使用vite創(chuàng)建項目
npm init vue@latest
注意:根據(jù)需求,選擇‘可選功能’完成安裝(具體安裝步驟vue.md)
2、項目結構
3、創(chuàng)建登錄項目
<1>創(chuàng)建一個組件(登錄頁面),我們把這個組件稱為單文件組件
位置:(規(guī)范情況下,將組件寫到components目錄下)
命名:大駝峰式命名規(guī)則
格式(三個部分):
<script>
</script>
<template>
</template>
<style scoped>
</style>
<2>Login.vue(登錄組件)
<script>
export default {
// 響應式數(shù)據(jù) data() 函數(shù)
data(){
return{
name:'',
password:'',
tip:'',
// 設置標識
flag:'false'
}
},
// 方法書寫在 methods 中
methods:{
sign(){
// 先判斷用戶名和密碼是否為空
if(this.name === '' || this.password === ''){
// 如果為空的彈出提示
this.flag='false'
this.tip='用戶名和密碼為空'
} else if(this.name ==='admin' && this.password === '123456'){
this.flag='true',
this.tip=''
// 跳轉(zhuǎn)頁面
this.$router.push({
path:'/logins'
})
} else {
this.flag='false',
this.tip='賬號名或密碼錯誤'
}
}
}
}
</script>
<template>
<div class="box1">
<div>
<h1>Login</h1>
<ul>
<label>
<li>用戶:<input type="text" placeholder="請輸入用戶名" v-model.trim="name"></li>
</label>
<label>
<li>密碼:<input type="password" placeholder="請輸入密碼" v-model.trim="password"></li>
</label>
<li><button @click="sign">登錄</button></li>
<li v-show="flag" :class="{style1:flag}">
{{ this.tip }}
</li>
</ul>
</div>
</div>
</template>
// scoped 樣式的作用域在本組件中
<style scoped>
div.box1 {
height: 50%;
width: 100%;
/* background-color: red; */
}
.style1{
color:red;
}
div.box1 div{
text-align: center;
height: 50%;
color:rgb(96, 207, 170);
/* background-color: aqua; */
border: 1px solid #111;
}
/* 注意:使用彈性布局時,內(nèi)部所有的元素都會變成內(nèi)聯(lián)塊 */
div.box1 div ul li {
margin-top: 10px;
list-style: none;
color:rgb(96, 207, 170)
}
div.box1 div ul li button {
width: 35%;
}
</style>
Tips:
1、使用彈性布局時,內(nèi)部所有的元素都會變成內(nèi)聯(lián)塊
2、在輸入用戶名和密碼的時候,在表單元素上進行數(shù)據(jù)的雙向綁定,v-model=‘響應式變量’,進行去除前后空格的修飾操作.trim
3、在按鈕上取消默認行為(.prevent,相當于事件對象event.defaultPrevent()),并綁定點擊事件,觸發(fā)sign函數(shù)
相當于v-on=‘sign’ 簡寫為@click=‘sign’
4、響應式數(shù)據(jù) 模塊是 data函數(shù),返回一個對象
5、methods是一個對象,在對象內(nèi)部書寫各種函數(shù)
①書寫函數(shù)sign函數(shù)
sign(){
// 先判斷用戶名和密碼是否為空
if(this.name === '' || this.password === ''){
// 如果為空的彈出提示
this.flag='false'
this.tip='用戶名和密碼為空'
} else if(this.name ==='admin' && this.password === '123456'){
this.flag='true',
this.tip=''
// 跳轉(zhuǎn)頁面
this.$router.push({
path:'/logins'
})
} else {
this.flag='false',
this.tip='賬號名或密碼錯誤'
}
}
注意:
1、函數(shù)中獲取響應式數(shù)據(jù)需要使用this獲取
2、通過一個標識來判斷提示信息是否彈出,使用v-show判斷(注意:v-if和v-show的區(qū)別)
-------v-if(判斷時,不斷的銷毀重建)
-------v-show(相當于使用display:none)
3、用戶名和密碼正確,進行跳轉(zhuǎn)頁面
②頁面的跳轉(zhuǎn)
使用路由router進行頁面的跳轉(zhuǎn):用法:this.$router (路由實例)
this.$router.push()或replace()方法
啟動項目,打開頁面,直接進入login頁面
**方式一:**將Login組件作為App.vue的子組件
在APP.vue中引入Login組件,并注冊
<script>
import Login from './components/Login.vue'
export default {
// 參數(shù)是對象
components: {Login},
}
</script>
<template>
// 組件一般都是大駝峰式,和html標簽區(qū)分
<Login></Login>
</template>
在使用時,將原有的所有樣式都清除(src->assets->main.css)
啟動項目,打開前端頁面
問題:在地址欄中輸入任何內(nèi)容,都會跳轉(zhuǎn)到登錄頁面
**原因:**因為我們把Login組件作為了App.vue中模板的內(nèi)容,App.vue是根組件,所以當我們的路徑發(fā)生變化時,只會顯示Login組件。我們所使用的this.$router.push就會失效,導致跳轉(zhuǎn)不成功。
補充知識點:路由(router)
路由:是組件和路徑的一一映射關系
位置:我們將路由再寫(src->router->路由名稱)
①創(chuàng)建路由
創(chuàng)建路由對象,通過createRouter函數(shù)創(chuàng)建,首先引入方法
import { createRouter, createWebHashHistory } from "vue-router";
通過createRouter函數(shù)創(chuàng)建路由
// 創(chuàng)建路由實例 const Router = createRouter({ // 模式有兩種:createWebHashHistory()--路徑中含有#,createWebHistory() history: createWebHashHistory(), // 將每個路由映射到對應的組件 routes: [ { path:'/logins', // 路徑 name:'logins', component:LoginFirst // 組件--當訪問'/'時就會顯示LoginFirst組件中的內(nèi)容 } ] });
要使用LoginFirst組件就需要引入組件
import LoginFirst from '../components/login/LoginFirst.vue'
將路由導出
export default Router
使用路由,在main.js中引入路由,使用路由
import Router from '../src/router/Router' app.use(Router)
通過對路由知識的補充,我們能夠充分理解到方法一的問題,為解決這個問題,我們使用方式二
**方式二:**應該要有路由顯示的位置,但是上面沒有,所以我們需要指定區(qū)域顯示路由,在App.vue中中使用顯示我們的路由,也可以使用
<script>
import Login from './components/Login.vue'
export default {
// 參數(shù)是對象
components: {Login},
}
</script>
<template>
// 顯示路由的區(qū)域
<RouterView></RouterView>
</template>
我們使用的是顯示路由,所以登錄的組件(Login.vue)也需要和路徑進行一一對應
因為我們需要打開頁面就進入Login組件,所以我們可以將路徑設置為‘/’或者‘/login’
// 創(chuàng)建路由實例
const Router = createRouter({
history: createWebHashHistory(),
// 將每個路由映射到對應的組件
routes: [
{
path:'/',
// 設置別名
alias:'/login'
component:Login
},
{
path:'/logins',
name:'logins',
component:LoginFirst
}
]
});
當然Login組件也需要引用
import Login from '../components/Login.vue'
但是,輸入路徑不對時,出現(xiàn)空白。用戶體驗不好,所以當輸入別的路徑時,出現(xiàn)404NotFound。同樣的我們在路由中進行設置
import { createRouter, createWebHashHistory } from "vue-router";
import NotFound from '../components/test/NotFound.vue'
import LoginFirst from '../components/login/LoginFirst.vue'
import Login from '../components/Login.vue'
// 創(chuàng)建路由實例
const Router = createRouter({
history: createWebHashHistory(),
// 將每個路由映射到對應的組件
routes: [
// 404
{
path: '/:paths(.*)*',
component: NotFound
},
{
path:'/',
component:Login
},
{
path:'/logins',
name:'logins',
component:LoginFirst
}
]
});
export default Router
當路徑不正確時,出現(xiàn)NotFound組件。簡單的寫一個404頁面。
<script>
</script>
<template>
<div>
404 NotFout
</div>
</template>
<style>
</style>
詳細解釋匹配404路徑知識:
{
path: '/:path(.*)*',
component: NotFound
},
將所有匹配到的路徑存放在 $route.params.path 下, 將非法路徑的所有部分作為參數(shù)
我們使用$route.params.path獲取動態(tài)路由參數(shù)
<template>
<div>
404 NotFout {{ this.$route.params.path }}
</div>
</template>
區(qū)別:
/:paths(.*)
:如果是這樣書寫的,意思是:將/后所有的路徑放入一個字符串中
/:paths(.*)*
:如果是這樣書寫的,意思是:將/后所有路徑,以/分割,將分割的內(nèi)容,放入數(shù)組中
4、首頁(登錄進去后的頁面)
<1>設計頁面
注意:這里就需要路由相關知識了
<2>創(chuàng)建路由
①一級標簽可以做成超鏈接(a鏈接),但是點擊a標簽會進行整個頁面的刷新,性能低。我們需要點擊時,只刷新渲染局部。(改變地址欄路徑,頁面不會重新刷新)
通過<router-link to=''></router-link>
來實現(xiàn)
②我們修改LoginFirst.vue組件(只導了template部分的代碼)
<template>
<div class="box1">
<ul>
<router-link to="/grade2022"><li>2022級</li></router-link>
<router-link to="/grade2021"><li>2021級</li></router-link>
<router-link to="/grade2020"><li>2020級</li></router-link>
</ul>
// 顯示區(qū)
<router-view></router-view>
</div>
</template>
提示:當點擊2022時,會在地址欄中顯示/grade2022地址,同時,/grade2022會對應一個組件,因此,需要在路由中設置路徑與組件的映射
③在路由(Router)中設置映射
創(chuàng)建三個Grade組件
在路由中引入,在完成路徑和組件的映射
發(fā)現(xiàn)問題?組件太多了,三個組件的模板基本相同,只是數(shù)據(jù)不同。因此可以寫一個組件,復用組件進行傳參。
代碼優(yōu)化:
<1>創(chuàng)建一個Grade組件,顯示參數(shù)
<2>在路由中引入Grade
<3>配置映射,并傳參
<4>修改router-link to 中的路徑
二、完善需求
1、發(fā)現(xiàn)問題:
當路徑地址為/grade/2022時,Grade組件顯示在App.vue中的區(qū)域中,但是我們的需求是想要Grade組件中的內(nèi)容顯示在LoginFirst組件列表的下方。
解決方法:路由的嵌套
<1>修改路由(我這里嵌套了三個路由—Login)
{
path: '/logins',
name: 'logins',
component: LoginFirst,
children: [
{
path: 'grade/:id',
component: Grade,
children: [
{
path: 'a1',
component: GradeBottom
}
]
}
]
},
注意:
1>使用children關鍵字,值為數(shù)組,數(shù)組中每一個元素都是路徑與組件的映射
2>子路由中路徑開始的地方不應該有/
<2>修改路徑
訪問結果:
<3>修飾樣式
LoginFirst.vue
<script>
</script>
<template>
<div class="box1">
<ul>
<!-- class="router-link-active" 設置點擊產(chǎn)生高亮行為 -->
<router-link :to="{name:'grade',params:{id:1}}"><li>2022級</li></router-link>
<router-link :to="{name:'grade',params:{id:2}}"><li>2021級</li></router-link>
<router-link :to="{name:'grade',params:{id:3}}"><li>2020級</li></router-link>
</ul>
<div><router-view></router-view></div>
</div>
</template>
<style scoped>
*{
margin: 0;
padding: 0;
}
div.box1 ul li {
display: inline-block;
text-align: center;
margin-left: 15px;
width: 50px;
height: 30px;
line-height: 30px;
background-color: rgb(228, 233, 233);
list-style: none;
}
/* .router-link-active{
background-color:red;
} */
</style>
Grade.vue
<script>
// 導入數(shù)據(jù)
import data from '../../Data'
export default {
// 定義一個數(shù)組接收數(shù)據(jù)
data() {
return {
list: []
}
},
// 使用參數(shù)
props:['id'],
// 鉤子函數(shù)
mounted() {
// 獲取id
const id = this.$route.params.id
// 使用list接收數(shù)據(jù),初始化
this.list = data.filter(item => item.id === id)[0].items
},
updated() {
const id = this.$route.params.id;
// 更新時也要更新list
this.list = data.filter(item => item.id === id)[0].items
}
}
</script>
<template>
<!-- <div class="topBox"> Grade---{{ this.$route.params.id }} </div> -->
<div class="divBox">
<router-link v-for='item of list' :to="{
name: 'school',
params: { id }
}">{{ item }}</router-link>
<router-view></router-view>
</div>
</template>
<style scoped>
/* div.topBox {
text-align: center;
} */
a {
margin-left: 10px;
color:rgb(81, 87, 82);
font-size:14px
}
</style>
<4>顯示二級標簽(就是路由的嵌套)
{
path: '/logins',
name: 'logins',
// 當?shù)刂窞?main時也是登錄頁面
// 使用別名
alias:'/main',
// 使用重定向
// redirect:{name:'logins'},
component: LoginFirst,
children: [
{
path: 'grade/:id',
name:'grade',
// 方便傳參數(shù)
props:true,
component: Grade,
children: [
{
path: 'a1',
name:'school',
component: GradeBottom
}
]
}
]
},
效果圖:
<5>為了讓路由的使用更加方便,我們可以給路由設置名稱(ps:前面的路由代碼中已設置是使用了)
<6>我們設置了名稱后,就可以在router-link中使用了,傳遞參數(shù)方便
<router-link :to="{name:'grade',params:{id:1}}"><li>2022級</li></router-link>
<router-link :to="{name:'grade',params:{id:2}}"><li>2021級</li></router-link>
<router-link :to="{name:'grade',params:{id:3}}"><li>2020級</li></router-link>
<7>在push(replace)中使用
this.$router.replace({name:'logins'})
tip:在編程式導航中,可以使用replace替換當前位置,它的作用類似于router.push,唯一的不同是,它在導航時不會向history添加新記錄
2、新的需求:
當點擊一級菜單時,顯示對應的二級菜單,二級菜單各不相同。
<1>如何在組件中獲取參數(shù)?
通過this.$route.param來獲取參數(shù)
<2>在Grade組件中獲取參數(shù),根據(jù)一級菜單不同,加載對應的二級菜單,因此,需要使用生命周期函數(shù)mounted頁面加載完成后的事情(初始化的工作一般都在此函數(shù)中運行)
// 定義一個數(shù)組接收數(shù)據(jù)
data() {
return {
list: []
}
},
// 使用參數(shù)
props:['id'],
// 鉤子函數(shù)
mounted() {
// 獲取id
const id = this.$route.params.id
// 使用list接收數(shù)據(jù),初始化
this.list = data.filter(item => item.id === id)[0].items
},
注意:data是聲明的假數(shù)據(jù),真實的數(shù)據(jù)需要從后臺獲取
data.js假數(shù)據(jù):
// 數(shù)據(jù)
const data = [
{
id:'1',
items:['計算機科學與技術','信息管理','信息與計算']
},
{
id:'2',
items:['人工智能','計算機科學','大數(shù)據(jù)']
},
{
id:'3',
items:['云存儲','算法','信息與計算']
}
];
export default data
<3>參數(shù)更新后也要對數(shù)據(jù)進行更新,使用updated函數(shù)
updated() {
const id = this.$route.params.id;
// 更新時也要更新list
this.list = data.filter(item => item.id === id)[0].items
}
<4>動態(tài)渲染文章來源:http://www.zghlxwxcb.cn/news/detail-421484.html
<template>
<!-- <div class="topBox"> Grade---{{ this.$route.params.id }} </div> -->
<div class="divBox">
<router-link v-for='item of list' :to="{
name: 'school',
params: { id }
}">{{ item }}</router-link>
<router-view></router-view>
</div>
</template>
<5>為了方便使用參數(shù),可以將props(路徑中的參數(shù))傳遞給組件。文章來源地址http://www.zghlxwxcb.cn/news/detail-421484.html
到了這里,關于登錄頁面的實現(xiàn)及跳轉(zhuǎn)(vue-router)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!