Vue-router:9、路由案例
9.1 抽离并且渲染App
根组件。
将素材中的代码修改成如下的形式:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>基于vue-router的案例</title>
<script src="./lib/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<style type="text/css">
html,
body,
#app {
margin: 0;
padding: 0px;
height: 100%;
}
.header {
height: 50px;
background-color: #545c64;
line-height: 50px;
text-align: center;
font-size: 24px;
color: #fff;
}
.footer {
height: 40px;
line-height: 40px;
background-color: #888;
position: absolute;
bottom: 0;
width: 100%;
text-align: center;
color: #fff;
}
.main {
display: flex;
position: absolute;
top: 50px;
bottom: 40px;
width: 100%;
}
.content {
flex: 1;
text-align: center;
height: 100%;
}
.left {
flex: 0 0 20%;
background-color: #545c64;
}
.left a {
color: white;
text-decoration: none;
}
.right {
margin: 5px;
}
.btns {
width: 100%;
height: 35px;
line-height: 35px;
background-color: #f5f5f5;
text-align: left;
padding-left: 10px;
box-sizing: border-box;
}
button {
height: 30px;
background-color: #ecf5ff;
border: 1px solid lightskyblue;
font-size: 12px;
padding: 0 20px;
}
.main-content {
margin-top: 10px;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}
ul li {
height: 45px;
line-height: 45px;
background-color: #a0a0a0;
color: #fff;
cursor: pointer;
border-bottom: 1px solid #fff;
}
table {
width: 100%;
border-collapse: collapse;
}
td,
th {
border: 1px solid #eee;
line-height: 35px;
font-size: 12px;
}
th {
background-color: #ddd;
}
</style>
</head>
<body>
<div id="app"><router-view></router-view></div>
<script>
const App = {
template: `<div>
<!-- 头部区域 -->
<header class="header">传智后台管理系统</header>
<!-- 中间主体区域 -->
<div class="main">
<!-- 左侧菜单栏 -->
<div class="content left">
<ul>
<li>用户管理</li>
<li>权限管理</li>
<li>商品管理</li>
<li>订单管理</li>
<li>系统设置</li>
</ul>
</div>
<!-- 右侧内容区域 -->
<div class="content right"><div class="main-content">添加用户表单</div></div>
</div>
<!-- 尾部区域 -->
<footer class="footer">版权信息</footer>
</div>`,
};
//创建路由对象
const router = new VueRouter({
routes: [{ path: "/", component: App }],
});
const vm = new Vue({
el: "#app",
router,
});
</script>
</body>
</html>
在上面的代码中,我们导入了Vue
与Vue-Router
的文件。
然后将核心内容定义到App
这个组件中,同时创建了路由对象,并且指定了路由的规则。接下来将路由对象挂载到了Vue
的实例中。
同时在<div id='app'></div>
中使用router-view
定义了一个占位符。当输入的地址为/
,对应的App
组件就会在该占位符中进行展示。
9.2 将菜单改造为路由连接
将模板中的菜单修改成路由连接的形式,如下所示:
/ <!-- 左侧菜单栏 -->
<div class="content left">
<ul>
<li><router-link to="/users"> 用户管理</router-link></li>
<li><router-link to="/rights"> 权限管理</router-link></li>
<li><router-link to="/goods"> 商品管理</router-link></li>
<li><router-link to="/orders"> 订单管理</router-link></li>
<li><router-link to="/settings"> 系统设置</router-link></li>
</ul>
</div>
9.3 创建菜单对应组件
基本组件创建如下:
const Users = {
template: `<div>
<h3>用户管理区域</h3>
</div>`,
};
const Rights = {
template: `<div>
<h3>权限管理区域</h3>
</div>`,
};
const Goods = {
template: `<div>
<h3>商品管理区域</h3>
</div>`,
};
const Orders = {
template: `<div>
<h3>订单管理区域</h3>
</div>`,
};
const Settings = {
template: `<div>
<h3>系统设置区域</h3>
</div>`,
};
我们知道,当单击左侧的菜单时,上面定义的组件将会在右侧进行展示。
所以需要在右侧,添加一个router-view
的占位符。
<!-- 右侧内容区域 -->
<div class="content right"><div class="main-content"> <router-view /></div></div>
9.4 添加子路由规则并实现路由重定向
在上一小节中,我们已经将组件都定义好了,下面需要定义其对应的路由规则。
怎样添加对应的路由规则呢?
我们知道整个页面是App
根组件渲染出来的,而前面定义的组件,都是在App
根组件中进行渲染的,也就是作为了App
组件的子组件。
所以,为上一小节中创建的组件添加路由规则,应该是作为App
的子路由来进行添加,这样对应的组件才会在App
组件中进行渲染。
// 创建路由对象
const router = new VueRouter({
routes: [
{
path: "/",
component: App,
redirect: "/users",
children: [
{ path: "/users", component: Users },
{ path: "/rights", component: Rights },
{ path: "/goods", component: Goods },
{ path: "/orders", component: Orders },
{ path: "/settings", component: Settings },
],
},
],
});
当用户在浏览器的地址栏中输入’/'的时候,会渲染App
组件,同时会重定向到/users
,从而将Users
组件渲染出来,而Users
组件是在整个App
组件的右侧进行渲染展示。
当点击左侧的菜单时,对应的组件会在右侧进行展示。
9.5 渲染用户列表数据
这里将用户组件的内容修改成如下形式:
const Users = {
data() {
return {
userlist: [
{ id: 1, name: "张三", age: 10 },
{ id: 2, name: "李四", age: 20 },
{ id: 3, name: "王五", age: 30 },
{ id: 4, name: "赵六", age: 40 },
],
};
},
template: `<div>
<h3>用户管理区域</h3>
<table>
<thead>
<tr><th>编号</th><th>姓名</th><th>年龄</th><th>操作</th></tr>
</thead>
<tbody>
<tr v-for="item in userlist" :key="item.id">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.age}}</td>
<td>
<a href="javascript:;">详情</a>
</td>
</tr>
</tbody>
</table>
</div>`,
};
在Users
组件中定义用户数据,并且在模板中通过循环的方式将数据渲染出来。
9.6 跳转到详情页
当单击"详情"链接时,跳转到对应的详情页面。这里需要用到编程式导航的内容。
首先定义用户详情页组件
//用户详情组件
const UserInfo = {
props: ["id"],
template: `<div>
<h5>用户详情页 --- 用户Id为:{{id}}</h5>
<button @click="goback()">后退</button>
</div>`,
methods: {
goback() {
// 实现后退功能
this.$router.go(-1);
},
},
};
在该组件中通过props
方式接收传递过来的的用户编号,并且将其打印出来。
同时在该组件中添加一个后退的按钮,通过编程式导航的方式实现后退。
对应的路由规则如下:
// 创建路由对象
const router = new VueRouter({
routes: [
{
path: "/",
component: App,
redirect: "/users",
children: [
{ path: "/users", component: Users },
{ path: "/userinfo/:id", component: UserInfo, props: true },
{ path: "/rights", component: Rights },
{ path: "/goods", component: Goods },
{ path: "/orders", component: Orders },
{ path: "/settings", component: Settings },
],
},
],
});
当输入的地址为:’/userinfo/5’的形式是会渲染UserInfo
这个组件,同时将props
设置为true
,表示会传递对应的id
值。
UserInfo
这个组件也是App
组件的子组件,对应的也会在App
组件的右侧进行展示。
同时,在Users
组件中,给“详情”链接添加对应的单击事件,
const Users = {
data() {
return {
userlist: [
{ id: 1, name: "张三", age: 10 },
{ id: 2, name: "李四", age: 20 },
{ id: 3, name: "王五", age: 30 },
{ id: 4, name: "赵六", age: 40 },
],
};
},
methods: {
goDetail(id) {
console.log(id);
this.$router.push("/userinfo/" + id);
},
},
template: `<div>
<h3>用户管理区域</h3>
<table>
<thead>
<tr><th>编号</th><th>姓名</th><th>年龄</th><th>操作</th></tr>
</thead>
<tbody>
<tr v-for="item in userlist" :key="item.id">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.age}}</td>
<td>
<a href="javascript:;" @click="goDetail(item.id)">详情</a>
</td>
</tr>
</tbody>
</table>
</div>`,
};
对应goDetail
方法中,通过编程式导航跳转到用户详情页面。
完整代码案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>基于vue-router的案例</title>
<script src="./lib/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<style type="text/css">
html,
body,
#app {
margin: 0;
padding: 0px;
height: 100%;
}
.header {
height: 50px;
background-color: #545c64;
line-height: 50px;
text-align: center;
font-size: 24px;
color: #fff;
}
.footer {
height: 40px;
line-height: 40px;
background-color: #888;
position: absolute;
bottom: 0;
width: 100%;
text-align: center;
color: #fff;
}
.main {
display: flex;
position: absolute;
top: 50px;
bottom: 40px;
width: 100%;
}
.content {
flex: 1;
text-align: center;
height: 100%;
}
.left {
flex: 0 0 20%;
background-color: #545c64;
}
.left a {
color: white;
text-decoration: none;
}
.right {
margin: 5px;
}
.btns {
width: 100%;
height: 35px;
line-height: 35px;
background-color: #f5f5f5;
text-align: left;
padding-left: 10px;
box-sizing: border-box;
}
button {
height: 30px;
background-color: #ecf5ff;
border: 1px solid lightskyblue;
font-size: 12px;
padding: 0 20px;
}
.main-content {
margin-top: 10px;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}
ul li {
height: 45px;
line-height: 45px;
background-color: #a0a0a0;
color: #fff;
cursor: pointer;
border-bottom: 1px solid #fff;
}
table {
width: 100%;
border-collapse: collapse;
}
td,
th {
border: 1px solid #eee;
line-height: 35px;
font-size: 12px;
}
th {
background-color: #ddd;
}
</style>
</head>
<body>
<div id="app"><router-view></router-view></div>
<script>
const App = {
template: `<div>
<!-- 头部区域 -->
<header class="header">传智后台管理系统</header>
<!-- 中间主体区域 -->
<div class="main">
<!-- 左侧菜单栏 -->
<div class="content left">
<ul>
<li><router-link to="/users"> 用户管理</router-link></li>
<li><router-link to="/rights"> 权限管理</router-link></li>
<li><router-link to="/goods"> 商品管理</router-link></li>
<li><router-link to="/orders"> 订单管理</router-link></li>
<li><router-link to="/settings"> 系统设置</router-link></li>
</ul>
</div>
<!-- 右侧内容区域 -->
<div class="content right"><div class="main-content"> <router-view /></div></div>
</div>
<!-- 尾部区域 -->
<footer class="footer">版权信息</footer>
</div>`,
};
const Users = {
data() {
return {
userlist: [
{ id: 1, name: "张三", age: 10 },
{ id: 2, name: "李四", age: 20 },
{ id: 3, name: "王五", age: 30 },
{ id: 4, name: "赵六", age: 40 },
],
};
},
methods: {
goDetail(id) {
console.log(id);
this.$router.push("/userinfo/" + id);
},
},
template: `<div>
<h3>用户管理区域</h3>
<table>
<thead>
<tr><th>编号</th><th>姓名</th><th>年龄</th><th>操作</th></tr>
</thead>
<tbody>
<tr v-for="item in userlist" :key="item.id">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.age}}</td>
<td>
<a href="javascript:;" @click="goDetail(item.id)">详情</a>
</td>
</tr>
</tbody>
</table>
</div>`,
};
//用户详情组件
const UserInfo = {
props: ["id"],
template: `<div>
<h5>用户详情页 --- 用户Id为:{{id}}</h5>
<button @click="goback()">后退</button>
</div>`,
methods: {
goback() {
// 实现后退功能
this.$router.go(-1);
},
},
};
const Rights = {
template: `<div>
<h3>权限管理区域</h3>
</div>`,
};
const Goods = {
template: `<div>
<h3>商品管理区域</h3>
</div>`,
};
const Orders = {
template: `<div>
<h3>订单管理区域</h3>
</div>`,
};
const Settings = {
template: `<div>
<h3>系统设置区域</h3>
</div>`,
};
// 创建路由对象
const router = new VueRouter({
routes: [
{
path: "/",
component: App,
redirect: "/users",
children: [
{ path: "/users", component: Users },
{ path: "/userinfo/:id", component: UserInfo, props: true },
{ path: "/rights", component: Rights },
{ path: "/goods", component: Goods },
{ path: "/orders", component: Orders },
{ path: "/settings", component: Settings },
],
},
],
});
const vm = new Vue({
el: "#app",
router,
});
</script>
</body>
</html>