Banner.vue
<template>
<div>
<h1>Banner</h1>
<button @click="back">后退</button>
<button @click="forward">前进</button>
<button @click="go">go</button>
</div>
</template>
<script>
export default {
name: "TheBanner",
methods: {
back() {
this.$router.back();
},
forward() {
this.$router.forward();
},
go() {
this.$router.go(-2); //后退两步
},
},
};
</script>
<style>
</style>
Message.vue
<template>
<div class="three_main">
<ul>
<li v-for="m in message" :key="m.id">
<button @click="pushShow(m)">push查看</button>
<button @click="replaceShow(m)">replace查看</button>
<!-- 1111111111111111111 -->
<!-- 跳转路由并携带query参数,to的字符串写法 -->
<router-link :to="`/home/message/detail/${m.id}/${m.text}`">
message{{ m.id }}
</router-link>
</li>
</ul>
<div>
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
name: "TheMessage",
methods: {
pushShow(m) {
this.$router.push(`/home/message/detail/${m.id}/${m.text}`);
},
replaceShow(m) {
this.$router.replace(`/home/message/detail/${m.id}/${m.text}`);
},
},
data() {
return {
message: [
{
id: "001",
text: "检察机关去年批捕侵害未成年人犯罪4.6万人",
},
{
id: "002",
text: "全国大学英语四六级成绩今日可查 这些常见问题请注意",
},
{
id: "003",
text: "宁夏出台搬迁撤并类村庄认定标准 不得强制农民集中上楼",
},
{
id: "004",
text: "急难愁盼|不交房?湖北随州督促企业上海地铁早高峰间隔时间过长?回应来了",
},
],
};
},
};
</script>
<style>
.three_main {
display: flex;
flex-direction: column;
}
li,
ul,
p {
margin: 0;
padding: 0;
margin-left: 10px;
}
</style>
News.vue
<template>
<div class="three_main">
<ul>
<li>欢迎学习vue</li>
<li v-for="n in news" :key="n.id">
news{{ n.id }}
<input type="text" id="n.id" />
</li>
</ul>
</div>
</template>
<script>
export default {
name: "TheNews",
data() {
return {
news: [
{
id: "001",
text: ' 时习之|当"冰雪白"遇上"中国红" ',
},
{
id: "002",
text: "汪洋主持召开全国政协主席会议",
},
{
id: "003",
text: "韩正:推动中央生态环保督察工作向纵深发展",
},
{
id: "004",
text: '"十个明确"彰显马克思主义中国化新飞跃',
},
],
opacity: 1,
};
},
// 组件被激活时
activated() {
console.log("组件激活");
this.timer = setInterval(() => {
console.log(this.opacity);
this.opacity -= 0.1;
if (this.opacity <= 0) this.opacity = 1;
}, 300);
},
// 组件未激活时
deactivated() {
console.log("组件未激活");
clearInterval(this.timer);
},
// 独享路由守卫
beforeEnter: (to, from, next) => {
console.log("123");
if (to.meta.isAuth) {
// 判定是否需要权限
if (localStorage.getItem("name") === "llx") {
next();
} else {
alert("名称不对");
}
} else {
next();
}
},
};
</script>
<style>
</style>
About.vue
<template>
<div class="second_main">
<div style="width: 100%">
<h2>About组件内容</h2>
<div class="second_btn_div">
<router-link
class="title_button"
active-class="selected_button"
to="/about/news"
>News</router-link
>
<router-link
class="title_button"
active-class="selected_button"
to="/about/message"
>Message</router-link
>
</div>
<hr />
<div>
<router-view></router-view>
</div>
</div>
</div>
</template>
<script>
export default {
name: "TheAbout",
components: {},
// 通过路由规则,进入该组件时被调用
beforeRouteEnter(to, from, next) {},
// 通过路由规则,离开该组件时被调用
beforeRouteLeave(to, from, next) {},
};
</script>
<style>
</style>
Detail.vue
<template>
<div>
<ul>
<!-- 通过query拿值 -->
<!-- <li>消息编号:{{ $route.query.id }}</li>
<li>消息标题:{{ $route.query.text }}</li> -->
<!-- 通过params拿值 -->
<!-- 不使用props写法 -->
<!-- <li>消息编号:{{ $route.params.id }}</li>
<li>消息标题:{{ $route.params.text }}</li>
-->
<!-- <li>消息编号:{{ a }}</li>
<li>消息标题:{{ b }}</li>
-->
<li>消息编号:{{ id }}</li>
<li>消息标题:{{ text }}</li>
</ul>
</div>
</template>
<script>
export default {
name: "TheDetail",
// props: ["a", "b"],
props: ["id", "text"],
};
</script>
<style>
</style>
Home.vue
<template>
<div class="second_main">
<div style="width: 100%">
<h2>Home组件内容</h2>
<div class="second_btn_div">
<router-link
class="title_button"
active-class="selected_button"
to="/home/news"
>News</router-link
>
<router-link
class="title_button"
active-class="selected_button"
to="/home/message"
>Message</router-link
>
</div>
<hr />
<div>
<!-- includu保持该组件不被销毁值为组件里的name -->
<!-- 缓存多个 :include="['TheNews','TheMessage']" -->
<keep-alive include="TheNews">
<router-view></router-view>
</keep-alive>
</div>
</div>
</div>
</template>
<script>
export default {
name: "TheHome",
};
</script>
<style>
</style>
router/index.js
// 该文件专门用于创建整个应用的路由器
import VueRouter from "vue-router";
// 引入组件
import About from '../pages/About.vue';
import Home from '../pages/Home.vue';
import News from '../pages/News.vue';
import Message from '../pages/Message';
import Detail from '../pages/Detail.vue';
const router = new VueRouter({
mode: 'history', // 调成哈希模式
// hash模式下, 仅hash符号之前的内容会被包含在请求中,
// 如http: //www.abcd.com,因此对于后端来说,
// 即使没有做到对路由的覆盖,也不会返回404错误。
// history模式下, 前端的url必须和实际向后台发起请求的url一致,
// 如http: //www.abcd.com/movie/id。如果后端缺少对/movie/id的路由处理,
// 将返回404错误。
routes: [{
name: 'guanyu',
path: '/about',
component: About,
meta: {
title: 'About',
},
},
{
name: 'zhuye',
path: '/home',
component: Home,
meta: {
title: 'Home'
},
// redirect: "home/news",
children: [{
path: 'news',
component: News,
meta: {
title: 'News',
isAuth: true, //是否需要权限的校验
},
// 对此组件做独享路由守卫
beforeEnter: (to, from, next) => {
if (to.meta.isAuth) { // 判定是否需要授权
if (localStorage.getItem('name') === 'llx') {
next();
} else {
alert('姓名不对');
}
} else {
next();
}
}
},
{
name: 'xiaoxi',
path: 'message',
component: Message,
meta: {
isAuth: true,
title: '信息',
},
children: [{
name: 'xiangqing',
// 使用占位符定义detail后面携带两个参数
// 定义了之后就得使用params方式传参了url/参数1/参数2
path: 'detail/:id/:text',
component: Detail,
// props的第二种写法,值为布尔值,若布尔值为真,
// 就会把该路由组件收到的所以params参数, 以props的形式传个Detail组件
props: true
}]
}
]
},
]
});
// 守卫拦截
// 初始化和每一次路由切换之前都都会调用
// router.beforeEach((to, from, next) => {
// if (to.meta.isAuth) { // 判定是否需要授权
// if (localStorage.getItem('name') === 'llx') {
// next();
// } else {
// alert('姓名不对');
// }
// } else {
// next();
// }
// });
router.afterEach((to, from) => {
document.title = to.meta.title || 'llx'; // 实时切换标题
});
export default router;
App.vue
<template>
<div id="app">
<banner></banner>
<hr />
<br />
<div class="app">
<div class="left">
<!-- replace当该值=false时,你点击了router-link控件则
此时浏览器可以点击返回上一页记录,=true时则没有记录 -->
<router-link
replace
ref="default_selected"
to="/about"
class="title_button"
active-class="selected_button"
>About</router-link
>
<router-link
replace
to="/home"
class="title_button"
active-class="selected_button"
>Home</router-link
>
</div>
<div class="right">
<router-view></router-view>
</div>
</div>
</div>
</template>
<script>
import Banner from "./components/Banner.vue";
export default {
name: "App",
components: { Banner },
data() {
return {
btn_style: "selected",
list: [
{ text: "About", style: "selected", show: true },
{ text: "Home", style: "unselected", show: false },
],
};
},
mounted() {
// 自动点击一次
// this.$refs.default_selected.$el.click();
},
methods: {
change_bg(text) {
this.list.forEach((element) => {
if (element.text == text) {
element.style = "selected";
element.show = true;
} else {
element.style = "unselected";
element.show = false;
}
});
},
},
};
</script>
<style>
#app {
width: 100%;
height: auto;
}
.app {
display: flex;
}
/* 左侧 */
.left {
width: 200px;
border-radius: 4px;
display: flex;
flex-direction: column;
background-color: #ffffff;
}
.right {
width: 88%;
}
/* 按钮 */
.title_button {
text-decoration: none;
border-radius: 2px;
margin-top: 0.3px;
cursor: pointer;
height: 30px;
display: flex;
align-items: center;
background-color: #d6cdcd;
color: black;
padding: 5px;
}
.selected_button {
background-color: #1c6cb8;
color: #ffffff;
}
/* 子组件 */
.second_main {
margin-top: 28px;
margin-left: 30px;
display: flex;
flex-direction: column;
width: 100%;
height: auto;
align-items: flex-start;
}
.second_btn_div {
display: flex;
}
h2 {
margin-top: 5px;
margin-bottom: 1px;
}
</style>
main.js
import Vue from 'vue';
import App from './App.vue';
import VueRouter from 'vue-router';
import router from './router';
Vue.use(VueRouter);
new Vue({
// 创建vm并使用stroe
render: h => h(App),
router: router
}).$mount('#app');