首页IT科技vue项目如何搭建(Vue项目实战——实现一个任务清单【基于 Vue3.x 全家桶(简易版)】)

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

时间2025-04-30 06:49:34分类IT科技浏览3198
导读:Vue3.x 项目实战(一) 内容 参考链接 Vue2.x全家桶 Vue2.x 全家桶参考链接 Vue2.x项目(一) Vue2.x 实现一个任务清单 Vue2.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:使用路由进行页面跳转

备注:

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

4          、项目详情

main.js

导入 store 和 router     ,并且使用 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 路由模式 import { createRouter, createWebHistory } from vue-router // 直接引入 import Start from ../views/Start.vue const routes = [ { path: /, name: Start, component: Start }, { path: /home, name: Home, // 按需引入               ,节约性能 component: () => import(../views/Home.vue) } ] // 创建路由对象 const router = createRouter({ history: createWebHistory(process.env.BASE_URL), routes }) export default router

./store/index.js

state 中定义初始化数据 mutations 中定义方法 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) }, // 删除任务 delTodo(state, payload) { state.list.splice(payload, 1) }, // 清除已完成 clear(state, payload) { // 把过滤之后的数组传进来 state.list = payload } }, // 异步提交 mutation // 第一个参数是 store 第二个参数是修改的值 actions: { }, // 模块化 modules: {} })

App.vue 组件

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

Start.vue 组件

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

Home.vue 组件

其他组件 表演的舞台 传递数据 自定义事件     ,进行组件间通信 <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"; export default { name: "Home", // 接收父组件的数据 props: {}, // 定义子组件 components: { NavHeader, NavMain, NavFooter, }, // 接收的数据               ,上下文 setup(props, ctx) { let store = useStore(); let list = computed(() => { return store.state.list; }); let value = ref(""); // 添加任务 let add = (val) => { value.value = val; // 任务存在 不能重复添加 let flag = true; list.value.map((item) => { if (item.title === value.value) { // 有重复任务 flag = false; alert("任务已存在"); } }); // 没有重复任务 if (flag == true) { // 调用 mutation store.commit("addTodo", { title: value.value, complete: false, }); } }; // 删除任务 let del = (val) => { // 调用删除的 mutation store.commit(delTodo, val) console.log(val); } // 清除已完成 let clear = (val) => { store.commit(clear, val) } return { add, list, del, clear }; }, }; </script>

NavHeader.vue 组件

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

NavMain.vue 组件

props 接收 list 数据 v-for 遍历出来内容 使用条件判断做呈现 <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> 暂无任务 </div> </div> </template> <script> export default { name: "navMain", props: { list: { type: Array, required: true, }, }, // 分发事件的属性名 emits: ["del"], setup(props, ctx) { // 删除任务 let del = (item, index) => { ctx.emit("del", index); console.log(index, item); }; return { del, }; }, }; </script> <style lang="scss" scoped> .container { margin: auto; border: 2px solid #ccc; width: 200px; margin-bottom: 20px; } .item { height: 35px; line-height: 35px; position: relative; width: 200px; button { cursor: pointer; position: absolute; right: 4px; top: 6px; display: none; z-index: 99; } &:hover { background: #ddd; button { display: block; } } } </style>

NavFooter.vue 组件

过滤出已完成的任务               ,获取到已完成任务的个数 过滤出未完成的任务                ,清除的时候保留未完成的任务 <template> <div class="container"> 已完成 {{ isCompelete }} / 全部 {{ list.length }} <span v-if="isCompelete" class="btn"> <button @click="clear">清除已完成</button> </span> </div> </template> <script> import { computed } from "vue"; export default { 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; }); // 清除已完成 let clear = () => { // 过滤未完成的 let arr = props.list.filter((item) => { return item.complete === false; }); ctx.emit("clear", arr); console.log("clear"); }; return { isCompelete, clear, }; }, }; </script> <style lang="scss" scoped> .container { text-align: center; } </style>

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

5                、写在最后的话

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

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

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

6     、附源码

声明:本站所有文章               ,如无特殊说明或标注           ,均为本站原创发布          。任何个人或组织     ,在未征得本站同意时               ,禁止复制     、盗用                、采集          、发布本站内容到任何网站     、书籍等各类媒体平台                。如若本站内容侵犯了原著者的合法权益           ,可联系我们进行处理     。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
怎么抓取网页的文字(如何抓取网页上的文字?) vue解决跨域(Vue实战——使用代理服务器解决跨域问题——No‘Access-Control-Allow-Origin‘ header is present on the requested resource)