0


Vue项目实战——实现一个任务清单【基于 Vue3.x 全家桶(简易版)】

Vue3.x 项目实战(一)

内容参考链接Vue2.x全家桶Vue2.x 全家桶参考链接Vue2.x项目(一)Vue2.x 实现一个任务清单Vue2.x项目(二)Vue2.x 实现GitHub搜索案例Vue3.x项目(三)Vue3.x 实现一个任务清单

文章目录


Vue3.x 实现 todoList

1、前言

如果你对 vue3 的基础知识还很陌生,推荐先去学习一下 vue 基础
内容参考链接Vue2.x全家桶Vue2.x全家桶参考链接Vue3.x的基本使用Vue3.x基本使用参考链接

  • 如果你 刚学完 vue3 基础知识,想检查一下自己的学习成果
  • 如果你 已学完 vue3 基础知识,想快速回顾复习
  • 如果你 已精通 vue3 基础知识,想做个小案例
  • 那不妨看完这篇文章,我保证你一定会有收获的!

2、项目演示(一睹为快)

Vue3.x_任务清单

在这里插入图片描述

在这里插入图片描述

3、涉及知识点

麻雀虽小,五脏俱全,接下来开始我们的项目之旅吧~~

  • Vue3.x基础:插值语法,常用指令,键盘事件,列表渲染,计算属性,生命周期
  • Vue3.x进阶:props(父传子),自定义事件(任意组件间通信)
  • Vuex4.x:状态管理库的使用
  • Vue-router4.x:使用路由进行页面跳转

备注:

  1. 任意组件间的通信方式有很多种(全局事件总线,消息订阅预发布…),熟练掌握一种即可(推荐自定义事件,配置简单,容易理解)
  2. 本文是 vue 基础的练习项目,也涉及 vue 周边(Vuex,Vue-Router)

4、项目详情

main.js

  • 导入 store 和 router,并且使用
  1. import{ createApp }from'vue'import App from'./App.vue'import router from'./router'import store from'./store'createApp(App).use(store).use(router).mount('#app')

./router/index.js

  • 配置路由
  • 直接导入 VS 按需导入(节约性能)
  • 使用了 history 路由模式
  1. import{ createRouter, createWebHistory }from'vue-router'// 直接引入import Start from'../views/Start.vue'const routes =[{path:'/',name:'Start',component: Start
  2. },{path:'/home',name:'Home',// 按需引入,节约性能component:()=>import('../views/Home.vue')}]// 创建路由对象const router =createRouter({history:createWebHistory(process.env.BASE_URL),
  3. routes
  4. })exportdefault router

./store/index.js

  • state 中定义初始化数据
  • mutations 中定义方法
  1. import{
  2. createStore
  3. }from'vuex'exportdefaultcreateStore({// 定义初始化状态state:{list:[{title:"吃饭",complete:false,},{title:"睡觉",complete:false,},{title:"敲代码",complete:true,},]},// 同步修改 state 都是方法// 第一个参数 state 第二个参数是需要修改的值mutations:{// 添加任务addTodo(state, payload){
  4. state.list.push(payload)},// 删除任务delTodo(state, payload){
  5. state.list.splice(payload,1)},// 清除已完成clear(state, payload){// 把过滤之后的数组传进来
  6. state.list = payload
  7. }},// 异步提交 mutation// 第一个参数是 store 第二个参数是修改的值actions:{},// 模块化modules:{}})

App.vue 组件

  • 做呈现的组件
  • <router-view /> 呈现内容
  1. <template><router-view/></template><style lang="scss">*{margin:0;padding:0;}</style>

Start.vue 组件

  • 初始化页面
  • 点击开启任务,跳转到任务页面
  1. <template><div class="title"><h1>欢迎来到前端杂货铺</h1><button @click="start">开始任务</button></div></template><script>import{ ref }from"vue";import{ useRouter }from"vue-router";exportdefault{name:"Start",setup(){// router 是全局路由对象let router =useRouter();let name =ref(10);// 点击进行路由跳转letstart=()=>{
  2. router.push({name:"Home",params:{name: name.value,},});};return{
  3. start,};},};</script><style lang="scss" scoped>.title {color: orange;
  4. text-align: center;
  5. margin-top:20%;}
  6. button {
  7. margin-top: 20px;width: 100px;height: 50px;background: skyblue;color: white;
  8. font-weight: bold;
  9. font-size: 15px;cursor: pointer;}button:hover {
  10. font-weight: bold;background: white;color: skyblue;cursor: pointer;}</style>

Home.vue 组件

  • 其他组件 表演的舞台
  • 传递数据
  • 自定义事件,进行组件间通信
  1. <template><div class="container"><nav-header @add="add"></nav-header><nav-main :list="list" @del="del"></nav-main><nav-footer :list="list" @clear="clear"></nav-footer></div></template><script>import NavHeader from"@/components/navHeader/NavHeader";import NavMain from"@/components/navMain/NavMain";import NavFooter from"@/components/navFooter/NavFooter";import{ ref, computed }from"vue";import{ useStore }from"vuex";exportdefault{name:"Home",// 接收父组件的数据props:{},// 定义子组件components:{
  2. NavHeader,
  3. NavMain,
  4. NavFooter,},// 接收的数据,上下文setup(props, ctx){let store =useStore();let list =computed(()=>{return store.state.list;});let value =ref("");// 添加任务letadd=(val)=>{
  5. value.value = val;// 任务存在 不能重复添加let flag =true;
  6. list.value.map((item)=>{if(item.title === value.value){// 有重复任务
  7. flag =false;alert("任务已存在");}});// 没有重复任务if(flag ==true){// 调用 mutation
  8. store.commit("addTodo",{title: value.value,complete:false,});}};// 删除任务letdel=(val)=>{// 调用删除的 mutation
  9. store.commit('delTodo', val)
  10. console.log(val);}// 清除已完成letclear=(val)=>{
  11. store.commit('clear', val)}return{
  12. add,
  13. list,
  14. del,
  15. clear
  16. };},};</script>

NavHeader.vue 组件

  • 头部组件(输入框)
  • 输入任务按下回车进行任务的添加
  • emit,使用分发的事务
  1. <template><div><div class="container"><input
  2. type="text"
  3. placeholder="请输入任务名称"
  4. v-model="value"
  5. @keyup.enter="enter"/></div></div></template><script>import{ ref }from"vue";exportdefault{name:"navHeader",// 接收的数据,上下文setup(props, ctx){let value =ref("");// 按回车键确认letenter=()=>{// 把输入框的内容传递给父组件
  6. ctx.emit("add", value.value);// 清空输入框
  7. value.value ="";};return{
  8. value,
  9. enter,};},};</script><style lang="scss" scoped>.container {
  10. text-align: center;
  11. margin-top: 220px;}.container input {height: 25px;width: 200px;
  12. margin-bottom: 10px;}</style>

NavMain.vue 组件

  • props 接收 list 数据
  • v-for 遍历出来内容
  • 使用条件判断做呈现
  1. <template><div class="container"><div v-if="list.length > 0"><div v-for="(item, index) in list":key="index"><div class="item"><input type="checkbox" v-model="item.complete"/>{{ item.title }}<button class="del" @click="del(item, index)">删除</button></div></div></div><div v-else>
  2. 暂无任务
  3. </div></div></template><script>exportdefault{name:"navMain",props:{list:{type: Array,required:true,},},// 分发事件的属性名emits:["del"],setup(props, ctx){// 删除任务letdel=(item, index)=>{
  4. ctx.emit("del", index);
  5. console.log(index, item);};return{
  6. del,};},};</script><style lang="scss" scoped>.container {margin: auto;border: 2px solid #ccc;width: 200px;
  7. margin-bottom: 20px;}.item {height: 35px;
  8. line-height: 35px;position: relative;width: 200px;
  9. button {cursor: pointer;position: absolute;right: 4px;top: 6px;display: none;
  10. z-index:99;}&:hover {background: #ddd;
  11. button {display: block;}}}</style>

NavFooter.vue 组件

  • 过滤出已完成的任务,获取到已完成任务的个数
  • 过滤出未完成的任务,清除的时候保留未完成的任务
  1. <template><div class="container">
  2. 已完成 {{ isCompelete }}/ 全部 {{ list.length }}<span v-if="isCompelete"class="btn"><button @click="clear">清除已完成</button></span></div></template><script>import{ computed }from"vue";exportdefault{name:"navFooter",props:{list:{type: Array,required:true,},},setup(props, ctx){let isCompelete =computed(()=>{// 过滤已完成let arr = props.list.filter((item)=>{return item.complete;});return arr.length;});// 清除已完成letclear=()=>{// 过滤未完成的let arr = props.list.filter((item)=>{return item.complete ===false;});
  3. ctx.emit("clear", arr);
  4. console.log("clear");};return{
  5. isCompelete,
  6. clear,};},};</script><style lang="scss" scoped>.container {
  7. text-align: center;}</style>

至此,此项目就实现了,如果什么问题,欢迎评论区或私信留言,看到定会第一时间解决!

5、写在最后的话

如果你是 看完全篇 阅读到了这里,我相信你一定是有收获的!

那么下面不妨打开自己的电脑,启动自己的编译器,来跟着做 / 自己做一遍吧!

有机会的话,在不久的将来还会对这个小案例进行升级(功能以及样式的升级)敬请期待吧~~

6、附源码


在这里插入图片描述



本文转载自: https://blog.csdn.net/qq_45902692/article/details/127018571
版权归原作者 前端杂货铺 所有, 如有侵权,请联系我们删除。

“Vue项目实战——实现一个任务清单【基于 Vue3.x 全家桶(简易版)】”的评论:

还没有评论