vue3 出来了,学和用要结合起来,我就做了个小demo,此中用到了watch,computed,toRefs等新特性。如图:

点击下部的tab导航,对应的顶部内容切换

思路:由于顶部导航的内容是不确定的,所以使用slot插槽,将导航的内容做为一个变量(headerTitle)存在vuex的state中,通过mutations根据路由名的变化来更改state中的headerTitle

核心内容:

1.获取路由

import {useRouter} from 'vue-router'
const router = useRouter()

获取路由名

router.currentRoute.value.name

2.使用watch来监听路由变化,注:watch需要先引用 watch两个参数都是函数,当监听第一个参数变化时,返回值可做为第二个参数传入第二个函数中

 watch(()=> {
      return router.currentRoute.value.name;
    },(value)=>{
       //console.log(value);
  })

3.获取store

    import { useStore } from 'vuex'
    const store = useStore(),
          state = store.state;

4.通过computed来获取变化的headerTitle,注:computed需要先引用  ,因为computed返回一个ref对象,所以需要.value来获取返回的值

const headerTitle = computed(() => state).value;

5.使用toRefs来解构响应式对象数据,注:toRefs需要先引用


     ...toRefs(headerTitle)
    

6.vuex中数据

import { createStore } from 'vuex'

export default createStore({
  state: {
    headerTitle:'当天信息'
  },
  mutations: {
    setHeaderTitle(state,routerName){
      switch(routerName){
        case 'day':
          state.headerTitle ='当天信息';
          break;
        case 'months':
          state.headerTitle = '当月信息';
          break;
        case 'years':
          state.headerTitle = '当年信息';
          break;
        default:
          break;
      }
    }
  }
})

完整代码如下:

App.vue

<template>
   <div>
    <header-top>{{headerTitle}}</header-top>
     <tab-bar></tab-bar>
    <router-view/>
  </div>
  
</template>

<script>
import { defineComponent,watch,computed,toRefs} from "vue";
import {useRouter} from 'vue-router'
import { useStore } from 'vuex'

 import tabBar from './views/tabBar.vue'
 import HeaderTop from './views/HeaderTop.vue'

export default defineComponent({
  name: "header",
  components: {
    tabBar,
    HeaderTop
  },
  setup(){
    const router = useRouter(),//获取路由
          store = useStore(), //获取store
          state = store.state;
      //因为返回一个ref对象,所以需要.value来获取返回的值
     const headerTitle = computed(() => state).value;
        router.push('/'); //刷新页面跳到初始页面
    watch(()=> {
      return router.currentRoute.value.name;
    },(value)=>{
       //console.log(value);
       store.commit('setHeaderTitle',value);
    })
    return {
      ...toRefs(headerTitle)
    }
  }
});
</script>
<style>
*{
  margin:0;
  padding:0;
}
.header {
  height: 44px;
  width: 100%;
  text-align: center;
}
</style>

路由index.js

import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import Day from '../views/day/day.vue'

const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    name: 'day',
    component: Day
  },
  {
    path: '/months',
    name: 'months',
    component: () => import(/* webpackChunkName: "about" */ '../views/months/months.vue')
  },
  {
    path: '/years',
    name: 'years',
    component: () => import(/* webpackChunkName: "about" */ '../views/years/years.vue')
  }
]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

export default router

headerTop.vue

<template>
    <div class="heard">
       <h1><slot></slot></h1>
    </div>
</template>
<style scoped>
.heard h1{
    width:100%;
    text-align:center;
    background:pink;
    font-size:22px;
    height:44px;
    line-height:44px;
}
</style>

底部tabBar->tabarItem,我封装了个tabarItem做为tabBar子页面,这样页面显得不哪么臃肿

tabBar.vue

<template>
     <div class="tab">
         <div class="tab-item" v-for="(item,index) in state.list" :key="index">
          <tabar-item :content="item.content" :path="item.path" />
          </div>
     </div>
</template>
<script>
import tabarItem from '../components/tabarItem.vue'
import {reactive} from 'vue'
export default {
    components:{
        tabarItem
    },
    setup(){
        const state = reactive({
            list:[{
                path:"/",
                content:'当天'
            },
            {
                path:"/months",
                content:'近期'
            },{
                path:"/years",
                content:'当年'
            }]
        })
        return {
           state
        }
    }
}
</script>
<style scoped>
.tab{
    width:100%;
    display:flex;
     height:44px;
     position:fixed;
     justify-content: center;
     align-items: center;
     bottom:0;
     left:0;
     border-top:1px solid #ccc;
}
.tab-item{
    flex:1;
    text-align:center;
}
</style>

tabarItem.vue

<template>
    <div>
        <router-link :to="path">
             {{content}}
        </router-link>
    </div>
</template>
<script>
export default {
    props:{
        content:String,
        path:String
    }
}
</script>

day.vue(和months,years都一样,一个基本的页面结构,我这里只写一个day.vue)

<template>
    <div class="day">
        day页面
    </div>
</template>

 

Logo

前往低代码交流专区

更多推荐