vue学习笔记 十九、实例完整代码
系列导航 | ||
---|---|---|
基础知识讲了不少,今天把之前所学的所有内容整合起来实现一个例子完善 vue学习笔记 九、父子组件实例-基本结构 中的功能,仔细看代码会有不小的收获。
一、 效果
父组件:Home 由三个子组件组成分别是:navHeader、navMain、navFooter
要完成的功能说明:
navHeader组件:输入新的任务,点击回车如果新的任务navMain中没有则添加到navMain中。
navMain组件:展示任务,点击“删除按钮”则删除当前任务,多选框可以多选任务。
navFooter组件:记录任务完成的数量(多选框选中为完成)、总数,以及点击“清除已完成”按钮删除navHeader中的已完成任务。
二、 项目结构截图
三、代码:
router--index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | import { createRouter, createWebHistory,createWebHashHistory } from 'vue-router' import Home from '../views/Home.vue' //路由的配置属组 //paht:路由路劲 必须以/开头 必填 //component:对应的路由组件 必填 //name:路由的名字 const routes = [ { path: '/' , name: 'Home' , //按需引入 //如果没有访问/about 就不会加载这个组件 节约性能 component: () => import ( '../views/Home.vue' ) }, { path: '/about' , name: 'About' , //按需引入 //如果没有访问/about 就不会加载这个组件 节约性能 component: () => import ( '../views/About.vue' ) } ] //创建路由对象 const router = createRouter({ //createWebHashHistory hash模式路径前面会多一个#号 history: createWebHistory(process.env.BASE_URL), routes }) export default router |
store--index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | import { createStore } from 'vuex' export default createStore({ //定义所需要的状态 state: { list:[ { title: '吃饭' , complete: false },{ title: '睡觉' , complete: false },{ title: '敲代码' , complete: true }, ] }, //同步修改state 都是方法 //第一个参数state,第二个参数是需要修改的值 mutations: { //添加任务 addTodo(state,payload){ state.list.push(payload) }, //删除任务 splice(下标,个数) delTodo(state,payload){ state.list.splice(payload,1) }, //清除已完成 clear(state,payload){ state.list = payload } }, //异步提交mutations //第一个参数是store 第二个参数是修改的值 actions: { }, //模块化的 modules: { } }) |
Home.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | <template> <div class = "item" > <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> //编写js内容 import NavHeader from '@/components/navHeader/NavHeader.vue' import NavMain from '@/components/navMain/NavMain.vue' import NavFooter from '@/components/navFooter/NavFooter.vue' import {defineComponent,ref,computed} from 'vue' import {useStore} from 'vuex' export default defineComponent({ name: 'Home' , components:{ NavHeader, NavMain, NavFooter }, setup(){ let store = useStore() let list = computed(()=>{ return store.state.list }) let value = ref( '' ) let add =(val)=>{ value.value = val //设置flag 判断输入的信息是否已经存在 let flag = true list.value.map(item =>{ if (item.title===value.value){ //有重复任务 flag = false ; alert( '任务已经存在' ) } }) if (flag){ //调用mutation store.commit( 'addTodo' ,{ title:value.value, complete: false }) } } //删除任务 let del =(val)=>{ console.log(val) store.commit( 'delTodo' ,val) } let clear =(val)=>{ store.commit( 'clear' ,val) } return { add, value, list, del, clear } } }) </script> <style scoped lang= "scss" > .item{ text-align:left; } </style> |
NavHeader.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <template> <div > <input placeholder= "请输入任务名称" v-model= "value" @keydown.enter= "enter" /> </div> </template> <script> import {defineComponent,ref} from 'vue' export default defineComponent({ name: 'navHeader' , setup(props,ctx){ let value=ref( '' ) //按回车确认 let enter = () => { ctx.emit( 'add' ,value.value) //console.log(value.value) //清空输入框 value.value= '' } return { value, enter } } }) </script> <style scoped lang= "scss" > input{ margin-bottom: 10px; } </style> |
NavMain.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | <template> <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> </template> <script> import {defineComponent,ref} from 'vue' export default defineComponent({ name: 'navMain' , props:{ list:{ type:Array, required: true } }, //放分发事件的属性名字 没有这句浏览器控制台有报错 emits:[ 'del' ], setup(props,ctx){ //删除任务 let del =(item,index)=>{ ctx.emit( 'del' ,index) console.log(item) console.log(index) } return { del } } }) </script> <style scoped lang= "scss" > .item{ height: 35px; line-height: 35px; position: relative; width: 260px; cursor: pointer; button{ position: absolute; right: 20px; top: 6px; display: none; z-index: 99; } &:hover{ background: #ddd; button{ display: block; } } } </style> |
NavFooter.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | <template> <div > <div>已完成{{isComplete}} /全部{{list.length}}</div> <div v- if = "isComplete >0" class = "btn" > <button @click= "clear" >清除已完成</button> </div> </div> </template> <script> import {defineComponent,ref,computed} from 'vue' export default defineComponent({ name: 'navFooter' , props:{ list:{ type:Array, required: true } }, setup(props,ctx){ let isComplete = computed(()=>{ //过滤已完成 let arr = props.list.filter(item =>{ return item.complete }) return arr.length }) let clear = ()=>{ //过滤未完成的 let arr = props.list.filter(item =>{ return item.complete === false }) ctx.emit( 'clear' ,arr) console.log( 'clear' ) } return { isComplete, clear } } }) </script> <style scoped lang= "scss" > .btn{ margin-left: 10px; } </style> |
资源丰富的的网盘资源:网盘资源大全! 推荐一个适合零基础学习SQL的网站:不用安装数据库,在线轻松学习SQL!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!