vue3项目小demo练习
vue3 出来了,学和用要结合起来,我就做了个小demo,此中用到了watch,computed,toRefs等新特性。如图:点击下部的tab导航,对应的顶部内容切换思路:由于顶部导航的内容是不确定的,所以使用slot插槽,将导航的内容做为一个变量(headerTitle)存在vuex的state中,通过mutations根据路由名的变化来更改state中的headerTitle核心内容:1.获取
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>
更多推荐
所有评论(0)