Vue開發之底部導航欄

1、導航切換html

封裝一個公用組件Tabbar,在須要導航頁的頁面引入組件便可。代碼以下:vue

<template>
  <div class="tabbar">
	<!-- 佔位容器 -->
	<div class="placegolder-container"></div>
	<!-- 底部導航欄 -->
	<div class="bottom-tabs">
	  <div class="tabs-item" v-for="(item, index) in tabsList" :key="index" @click="tabsChange(index)" >
		<img class="tab-icon" :src="tabIndex==index?item.src:item.src1">
		<p class="tab-text" :class="tabIndex==index?'active':''">{{item.text}}</p>
	  </div>
	</div>
  </div>
</template>

<script>
export default {
  name: "tabbar",
  components: {},
  data() {
	return {
	  tabIndex: 0,
	  tabsList: [
		{
		  src: require("../../assets/icon/home.png"),
		  src1: require("../../assets/icon/home1.png"),
		  text: "首頁",
		  path: "/"
		},
		{
		  src: require("../../assets/icon/brand.png"),
		  src1: require("../../assets/icon/brand1.png"),
		  text: "禮品",
		  path: "/Gift"
		},
		{
		  src: require("../../assets/icon/find.png"),
		  src1: require("../../assets/icon/find1.png"),
		  text: "發現",
		  path: "/Test"
		},
		{
		  src: require("../../assets/icon/my.png"),
		  src1: require("../../assets/icon/my1.png"),
		  text: "個人",
		  path: "/UploadFile"
		}
	  ]
	};
  },
  created() {
	this.tabIndex = localStorage.getItem("tabIndex");
	console.log(this.tabIndex);
  },
  methods: {
	tabsChange(index) {
	  this.tabIndex = index;
	  this.$router.push({
		path: this.tabsList[index].path
	  });
	  localStorage.setItem("tabIndex", this.tabIndex);
	}
  },
  watch: {
	$route(newVal, oldVal) {
	  // console.log(newVal, oldVal);
	  if (newVal.meta.index >= 0) {
		this.tabIndex = newVal.meta.index;
		localStorage.setItem("tabIndex", this.tabIndex);
	  }
	}
  }
};
</script>


<style scoped lang="less">
.tabbar {
  position: fixed;
  bottom: 0;
  left: 0;
}
.placegolder-container {
  height: 70px;
}

.bottom-tabs {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 5;
  display: flex;
  flex-direction: row;
  justify-content: space-around;
  align-items: center;
  box-shadow: 0px -1px 1px #e6e6e6;
  background-color: #fff;

  .tabs-item {
	padding: 5px 0;
	flex: 1;
	height: 60px;
	display: flex;
	flex-direction: column;
	justify-content: space-around;
	align-items: center;

	.tab-icon {
	  width: 30px;
	  height: 30px;
	  border-radius: 4px;
	}

	.tab-text {
	  font-size: 14px;
	  margin: 0;

	  &.active {
		color: #624980;
	  }
	}
  }
}
</style>

注意:git

  • 頁面設置佔位容器是爲了抵消底部導航欄固定定位的高度。
  • tabIndex 標記當前選中的路由。
  • tabsChange(index) 底部導航欄路由切換。
  • watch 監聽路由變化,保持路由選中的駐留(選中/激活)樣式。

2、緩存使用vuex

  • 爲何要使用緩存?緩存哪些內容?
  • 答:使用緩存是爲了保存選中路由的 tabIndex ,在刷新頁面的時候,依然能夠保持(選中/激活)狀態。

3、路由配置與監聽vue-cli

(1)配置瀏覽器

在配置路由的時候,咱們能夠添加 meta對象,裏面添加你須要的屬性;用於路由切換時獲取meta的值, 如:meta.needLogin 規定進入路由需不需登陸緩存

{
	  path: '/',
	  name: 'Home',
	  meta: { index: 0, title: '首頁',needLogin: false },
	  component: Home
	},
	{
	  path: '/Gift',
	  name: 'Gift',
	  meta: { index: 1, title: '禮品' },
	  component: Gift
	},
	{
	  path: '/Test',
	  name: 'Test',
	  meta: { index: 2, title: '發現',needLogin: true },
	  component: Test,
	  children:[
		{
		  path: '/title1',
		  name: 'Title1',
		  component: Title1
		},
		{
		  path: '/title2',
		  name: 'Title2',
		  component: Title2
		},
		{
		  path: '/title3',
		  name: 'Title3',
		  component: Title3
		}
	  ]
	}, 
	{
	  path: '/UploadFile',
	  name: 'UploadFile',
	  meta: { index: 3, title: '個人' },
	  component: UploadFile
	},

(2)監聽session

  • 使用監聽的目的是爲了在使用瀏覽器前進後退的時候,保持路由選中的駐留(選中/激活)樣式。less

    watch: {
      $route(newVal, oldVal) {
        // console.log(newVal, oldVal);
        if (newVal.meta.index >= 0) {
      	this.tabIndex = newVal.meta.index;
      	localStorage.setItem("tabIndex", this.tabIndex);
        }
      }
    }

4、動態修改頁面標題以及增長路由攔截flex

(1)在修改頁面標題 title 的時候,咱們能夠用配置路由的 title 屬性來控制。路由攔截咱們便可使用配置路由的 needLogin 屬性控制。

//main.js

import store from "./store/index";

// 用來作一些進入頁面的配置與限制
router.beforeEach((to, from, next) => {
  console.log({ to, from })
  /*路由發生改變修改頁面的title */
  if (to.meta.title) {
	document.title = to.meta.title
  }else{
	document.title = "小魚蕾蕾"
  }
  /*判斷路由是否須要權限才能進入,即路由攔截 */
  if(to.meta.needLogin){
	if(store.state.person.userInfo.userId){ //從vuex裏面獲取userId
	  next()
	}else{
	  next({path:'/login'})
	}
  }
  next();
})

(2)在store下的modules裏增長一個模塊 person.js, 而後使用vuex整一個userId

const state = {
  userInfo: {
	userId: 11,
  },
};
// getters
const getters = {
  userInfo: (state) => state.userInfo
};

// actions
const actions = {
  UpdatePerson({ commit }, userInfo) {
	commit("UpdatePerson", userInfo);
  },
};

// mutations
const mutations = {

  UpdatePerson(state, userInfo) {
	// 變動狀態
	state.userInfo=userInfo
  },
};

export default {
  state,
  getters,
  actions,
  mutations
};

(3) 在store目錄下新建一個 index.js 它經過modules 屬性引入 person模塊。

import Vue from "vue";
import Vuex from "vuex";
import actions from "./actions";
import getters from "./getter";
import createPersistedState from "vuex-persistedstate";
import person from "./modules/person";

Vue.use(Vuex);

const state = {};

export default new Vuex.Store({
  state,
  mutations,
  actions,
  getters,
  modules: {
	person,
  },
  strict: debug,
  plugins: [createPersistedState({ storage: window.sessionStorage })]
});

5、組件引用

在須要底部導航的頁面裏引用子組件,以下代碼

import Tabbar from './common/Tabbar';//引用子組件
//註冊組件
components: {
	"Tabbar":Tabbar
},

//html結構底部增長
<!-- 底部菜單 -->
<Tabbar />

6、效果圖

注:項目代碼地址爲(僅供參考) https://gitee.com/xiaoyuleilei/vue-cli_demo

相關文章
相關標籤/搜索