如何在vue项目中使用vue-router和vuex实现一个简易的头部导航栏
一、vue-router是什么?
路由就是用来跟后端服务器进行交互的一种方式,通过不同的路径,来请求不同的资源,请求不同的页面是路由的其中一种功能。 vue-router是vue.js官方路由管理器。vue的单页应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来二、使用步骤
前情提要:vue项目中已经引入了vue-router和vuex状态管理工具
1.添加vue-router
首先在router/index.js文件中
代码如下(示例):
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import First from '@/components/First'
import Second from '@/components/Second'
import Thirt from '@/components/Thirt'
import Fourth from '@/components/Fourth'
Vue.use(Router)
export default new Router({
routes: [{
path: '/',
name: 'hello页✌',
component: HelloWorld,
meta: { requiresAuth: true }
},
{
path: '/First',
name: '第一页✌',
component: First,
meta: { requiresAuth: false }
},
{
path: '/Second',
name: '第二页✌',
component: Second,
meta: { requiresAuth: false }
},
{
path: '/Thirt',
name: '第三页✌',
component: Thirt,
meta: { requiresAuth: false }
},
{
path: '/Fourth',
name: '第四页✌',
component: Fourth,
meta: { requiresAuth: false }
}
]
})
const originalPush = Router.prototype.push
Router.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
2.创建vuex管理状态
在store/index.js文件中
代码如下(示例):
/**
* Created by Administrator on 2017/9/18.
*/
import Vue from "vue"
import Vuex from "vuex"
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
index: 0,
type: '',
routes: [],
},
getters: {
getIndex: function(state) {
return state.index;
},
getType: function(state) {
if (!state.type) {
state.type = localStorage.getItem('type')
}
return state.type;
},
getRoutes: function(routes) {
return routes
}
},
mutations: {
//格式:类型(名字)+处理函数
//加1
changeIndex(state, index) {
state.index = index;
},
changetype(state, type) {
//console.log(state)//state对象
state.type = type;
alert("可以去其他页面看一下")
},
changeRoutes(state, routes) {
state.routes = routes;
}
},
actions: {
/* increment({commit}){
commit("INCREMENT")
}*/
}
})
export default store
3.创建vuex管理状态
在components文件夹下创建组件
代码如下(示例):
<template>
<div id="First">
<div id="centerBody">
<div class="centerBody-margin">
<div class="timu">这是用state获取的state</div>
<div class="zhanshi">
<div
class="zhanshi_item"
v-for="(value,key,index) in state"
:key="index"
>state[{{index}}]--{{key}}--{{!value ? '空' : value}}</div>
</div>
</div>
</div>
</div>
</template>
<script>
import centerBody from "../common/vue/centerBody";
import { mapState } from "vuex";
export default {
name: "First",
components: { centerBody },
data() {
return {};
},
computed: {
state() {
return this.$store.state;
},
},
mounted() {
let obj = { foo: 123 };
//Object.getOwnPropertyDescriptor可以获得该对象的描述属性
Object.getOwnPropertyDescriptor(obj, "foo");
},
};
</script>
<style lang="less" scoped>
@import "../common/css/bodycss.css";
@import "../common/css/lessTest.less";
#First {
height: 100%;
margin: @margin;
}
</style>
4.创建common公共组件
创建common/headerNav.vue文件
代码如下(示例):
<template>
<div id="header">
<div class="frame">
<div class="frame_img-div">
<img src="../../assets/svg/wohenshuai.svg" height="40" class="title_svg" />
</div>
<div class="title_nav">
<div
:class="navIndex === index ? 'title_nav-children_exmple' : 'title_nav-children'"
v-for="(item, index) in routes"
:key="index"
@click="navGo(item, index)"
>{{item.name}}</div>
</div>
</div>
</div>
</template>
<script>
import { mapGetters, mapMutations } from "vuex";
export default {
name: "headerNav",
data() {
return {};
},
computed: {
routes() {
return this.getRoutes.routes;
},
navIndex() {
return this.getIndex;
},
...mapGetters([
"getIndex",
"getRoutes",
// ...
]),
},
mounted() {
this.$nextTick(() => {
this.$router.push(this.routes[this.navIndex].path);
});
},
methods: {
navGo(item, index) {
this.changeIndex(index);
this.$router.replace(item.path);
},
...mapMutations(["changeIndex"]),
},
};
</script>
<style scoped>
#header {
position: fixed;
top: 0;
z-index: 1;
height: 50px;
width: 100%;
background: white;
}
.frame {
position: relative;
display: flex;
height: 100%;
width: 100%;
}
#header .frame .title_svg {
margin-left: 15px;
}
.title_nav {
height: 100%;
width: 80%;
margin-left: 15px;
}
.frame_img-div {
padding-top: 2px;
}
.frame .title_nav-children {
font-family: "Satisfy", cursive;
font-size: 17px;
display: inline-block;
height: 100%;
padding-left: 1.5em;
padding-right: 1.5em;
text-align: center;
line-height: 50px;
font-weight: bold;
cursor: pointer;
}
.frame .title_nav-children:hover {
font-size: 19px;
background: #95a5a6;
}
.frame .title_nav-children_exmple {
font-family: "Satisfy", cursive;
font-size: 17px;
display: inline-block;
height: 100%;
padding-left: 15px;
padding-right: 15px;
text-align: center;
line-height: 50px;
font-weight: bold;
cursor: pointer;
background: black;
color: white;
}
</style>
5.在App.vue文件中组合
在App.vue文件中
代码如下(示例):
<template>
<div id="app">
<headerNav />
<router-view style="margin-top: 50px;" />
</div>
</template>
<script>
import headerNav from "./common/vue/headerNav";
import { mapGetters, mapMutations } from "vuex";
export default {
name: "App",
components: { headerNav },
data() {
return {};
},
computed: {
routes() {
return this.$router.options.routes;
},
...mapGetters([
"getIndex",
"getRoutes",
// ...
]),
},
mounted() {
this.changeRoutes(this.routes);
},
methods: {
...mapMutations([
"changeRoutes", // 将 `this.changeRoutes()` 映射为 `this.$store.commit('changeRoutes')`
]),
},
};
</script>
<style>
html {
height: 100%;
}
body {
padding: 0;
margin: 0;
height: calc(100vh - 50px);
width: 100%;
font-family: "Poppins", sans-serif;
font-weight: 300;
font-size: 15px;
line-height: 1.7;
color: #c4c3ca;
background-color: #1f2029;
overflow-x: hidden;
}
#app {
height: 100%;
}
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
}
</style>
完成效果如下
github链接: https://github.com/NotBerlin/vue-router-vuex.git.