router/index.js
, 写入路由模块代码index.js
, 开头加入import Vue from 'vue'
, 结尾加入export default router
main.js
中加入import router from './router/index'
需求: 实现导航高亮效果
<template>
<div>
<div class="footer_wrap">
<router-link to="/find">发现音乐router-link>
...
div>
...
div>
template>
<style>
.footer_wrap a.router-link-active {
background-color: blue;
}
style>
router-link-active 模糊匹配
to="/find" => 地址栏 /find /find/one /find/two ...
router-link-exact-active
to="/find" => 地址栏 /find
router-link-active {
background-color: blue;
}
router-link-exact-active {
background-color: blue;
} */
const router = new VueRouter({
...
// link自定义高亮类名
linkActiveClass: 'active', // 配置模糊匹配的类名
linkExactActiveClass: 'exact-active' // 配置精确匹配的类名
})
to="/path?参数名1=值&参数名2=值"
$route.query.参数名
path: "/path/参数名
to="/path/参数名
$route.params.参数名
/path/:words?
表示参数可传可不传const router = new VueRouter({
routes: [
{ path: '/', redirect: '/home'},
...
]
})
const router = new VueRouter({
routes: [
...
{ path: '*', component: NotFind}
]
})
#
#
, 但是上线后需要服务器端支持const router = new VueRouter({
mode: 'history',
...
})
<script>
export default {
...
methods: {
goSearch () {
// 1. 通过路径的方式跳转
// 简写
// this.$router.push('/search')
// 完整写法
// this.$router.push({
// path: '/search'
// })
// 2. 通过命名路由的方式跳转 (需要给路由命名, 适合长路由)
this.$router.push({
name: 'search'
})
}
}
}
</script>
<script>
export default {
name: 'FindMusic',
methods: {
goSearch () {
// 1. 通过路径的方式跳转
// 简写
// query传参
this.$router.push('/search?key1=val1&key2=val2')
// 动态路由传参
this.$router.push('/search/val')
// 完整写法
// query传参
this.$router.push({
path: '/search',
query: {
key1: 'val1',
key2: 'val2'
}
})
// 动态路由传参
this.$router.push({
path: '/search/val',
})
// 2. 通过命名路由的方式跳转 (适合长路由)
// query传参
this.$router.push({
name: 'search',
query: {
key1: 'val1',
key2: 'val2'
}
})
// 动态路由传参
this.$router.push({
name: 'search',
params: {
key1: 'val1',
key2: 'val2'
}
})
}
}
}
</script>
<template>
<div class="h5-wrapper">
<keep-alive :include="keepArray">
<router-view>router-view>
keep-alive>
div>
template>
<script>
export default {
name: "h5-wrapper",
data () {
return {
keepArray: ['LayoutPage']
}
}
}
script>
<style>
body {
margin: 0;
padding: 0;
}
style>
<style lang="less" scoped>
.h5-wrapper {
.content {
margin-bottom: 51px;
}
.tabbar {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
height: 50px;
line-height: 50px;
text-align: center;
display: flex;
background: #fff;
border-top: 1px solid #e4e4e4;
a {
flex: 1;
text-decoration: none;
font-size: 14px;
color: #333;
-webkit-tap-highlight-color: transparent;
&.router-link-active {
color: #fa0;
}
}
}
}
style>
import Vue from 'vue'
import VueRouter from "vue-router"
import Article from '@/views/Article'
import ArticleDetail from '@/views/ArticleDetail'
import Layout from '@/views/Layout'
import Collect from '@/views/Collect'
import Like from '@/views/Like'
import User from '@/views/User'
Vue.use(VueRouter)
const router = new VueRouter({
routes: [
{
path: '/',
component: Layout,
redirect: '/article',
// 通过children配置项, 可以配置嵌套子路由
// 1. 在children配置项中, 配规则
// 2. 准备二级路由出口
children: [
{ path: '/article', component: Article },
{ path: '/collect', component: Collect },
{ path: '/like', component: Like },
{ path: '/user', component: User },
]
},
{ path: '/detail/:id', component: ArticleDetail },
]
})
export default router
<template>
<div class="article-page">
<div class="article-item"
v-for="item in list" :key="item.id"
@click="$router.push(`/detail/${item.id}`)">
<div class="head">
<img :src="item.creatorAvatar" alt="" />
<div class="con">
<p class="title"> {{item.stem}} p>
<p class="other"> {{item.creatorName}} | {{item.createdAt}} p>
div>
div>
<div class="body">
{{ item.content }}
div>
<div class="foot">点赞 {{item.likeCount}} | 浏览 {{item.views}} div>
div>
div>
template>
<script>
import axios from 'axios'
// 请求地址: https://mock.boxuegu.com/mock/3083/articles
// 请求方式: get
export default {
name: 'ArticlePage',
data () {
return {
list: []
}
},
async created () {
const res = await axios.get('https://mock.boxuegu.com/mock/3083/articles')
this.list = res.data.result.rows
// console.log(this.list)
},
methods: {
}
}
script>
<style lang="less" scoped>
.article-page {
background: #f5f5f5;
}
.article-item {
margin-bottom: 10px;
background: #fff;
padding: 10px 15px;
.head {
display: flex;
img {
width: 40px;
height: 40px;
border-radius: 50%;
overflow: hidden;
}
.con {
flex: 1;
overflow: hidden;
padding-left: 15px;
p {
margin: 0;
line-height: 1.5;
&.title {
text-overflow: ellipsis;
overflow: hidden;
width: 100%;
white-space: nowrap;
}
&.other {
font-size: 10px;
color: #999;
}
}
}
}
.body {
font-size: 14px;
color: #666;
line-height: 1.6;
margin-top: 10px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.foot {
font-size: 12px;
color: #999;
margin-top: 10px;
}
}
style>
<template>
<div class="article-detail-page" v-if="article.id">
<nav class="nav"><span @click="$router.back()" class="back"><span> 面经详情nav>
<header class="header">
<h1> {{article.stem}} h1>
<p> {{article.createdAt}} | {{article.views}} 浏览量 | {{article.likeCount}} 点赞数p>
<p>
<img
:src="article.creatorAvatar"
alt=""
/>
<span> {{article.creatorName}} span>
p>
header>
<main class="body">
{{article.content}}
main>
div>
template>
<script>
// 请求地址: https://mock.boxuegu.com/mock/3083/articles/:id
// 请求方式: get
import axios from 'axios'
export default {
name: "ArticleDetailPage",
data() {
return {
article: {}
}
},
async created () {
const res = await axios.get(`https://mock.boxuegu.com/mock/3083/articles/${this.$route.params.id}`)
this.article = res.data.result
// console.log(this.article);
}
}
script>
<style lang="less" scoped>
.article-detail-page {
.nav {
height: 44px;
border-bottom: 1px solid #e4e4e4;
line-height: 44px;
text-align: center;
.back {
font-size: 18px;
color: #666;
position: absolute;
left: 10px;
top: 0;
transform: scale(1, 1.5);
}
}
.header {
padding: 0 15px;
p {
color: #999;
font-size: 12px;
display: flex;
align-items: center;
}
img {
width: 40px;
height: 40px;
border-radius: 50%;
overflow: hidden;
}
}
.body {
padding: 0 15px;
}
}
style>
<template>
<div class="h5-wrapper">
<div class="content">
<router-view>router-view>
div>
<nav class="tabbar">
<router-link to="/article">面经router-link>
<router-link to="/collect">收藏router-link>
<router-link to="/like">喜欢router-link>
<router-link to="/user">我的router-link>
nav>
div>
template>
<script>
export default {
// 组件名, 如果没有配置name, 才会找文件名作为组件名
name: "LayoutPage",
// 组件缓存后, created和mounted只会执行一次, 且不执行destroyed
// 但是提供了 activated 和 deactivated
activated () {
alert('回到首页')
console.log('activated');
},
deactivated() {
console.log('deactivated');
},
}
script>
<style>
body {
margin: 0;
padding: 0;
}
style>
<style lang="less" scoped>
.h5-wrapper {
.content {
margin-bottom: 51px;
}
.tabbar {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
height: 50px;
line-height: 50px;
text-align: center;
display: flex;
background: #fff;
border-top: 1px solid #e4e4e4;
a {
flex: 1;
text-decoration: none;
font-size: 14px;
color: #333;
-webkit-tap-highlight-color: transparent;
}
a.router-link-active {
color: orange;
}
}
}
style>
黑马程序员. Vue2+Vue3基础入门到实战项目