vue3项目小demo练习

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>

 

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vue3 标准项目 demo 是一个使用 Vue3 编写的示例项目,旨在展示 Vue3 的新特性和用法。 该项目包含了一个简单的任务管理系统,用户可以添加、删除和标记已完成的任务。项目结构清晰,代码简洁易懂,适合初学者学习和了解 Vue3 的基本用法。 在该项目中,主要使用了 Vue3 的以下特性: 1. Composition API:Vue3 引入了 Composition API,用于替代之前的 Options API。Composition API 可以将相关的逻辑组织在一起,使代码更加清晰和可维护。 2. Teleport:Vue3 引入了 Teleport,用于将组件的内容挂载到指定的 DOM 节点上,而不是直接挂载到组件所在的父节点上。这样可以实现更灵活的组件渲染方式。 3. Fragments:Vue3 允许在组件的根元素中使用多个 DOM 元素,而不再需要一个根元素包裹所有内容。这样可以减少不必要的 DOM 节点。 4. 新的响应式系统:Vue3 使用了 Proxy 和 Reflect 来替代 Vue2 中的 Object.defineProperty,提供了更强大和灵活的响应式系统。这使得数据的变化可以更高效地被追踪和更新。 5. TypeScript 支持:Vue3 引入了对 TypeScript 的原生支持,可以提供更好的类型检查和代码提示,提高开发效率和代码质量。 通过这个标准项目 demo,开发者可以学习并了解到 Vue3 的新特性和用法,为日后的项目开发打下良好的基础。同时,也可以根据自己的需求对该 demo 进行扩展和定制,以满足实际项目的要求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值