Vue3.x 项目实战(一)

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

文章目录

  • Vue3.x 项目实战(一)
    • Vue3.x 实现 todoList
      • 1、前言
      • 2、项目演示(一睹为快)
      • 3、涉及知识点
      • 4、项目详情
      • 5、写在最后的话
      • 6、附源码

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,并且使用
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) {// 调用 mutationstore.commit("addTodo", {title: value.value,complete: false,});}};// 删除任务let del = (val) => {// 调用删除的 mutationstore.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"><inputtype="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、附源码



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

  1. Vue项目实战——实现一个任务清单(学以致用,两小时带你巩固和强化Vue知识点)

    Vue2.x 项目实战(一) 内容 参考链接 Vue2.x全家桶 Vue2.x 全家桶参考链接 Vue2.x项目(一) Vue2.x 实现一个任务清单 Vue2.x项目(二) Vue2.x 实现Git ...

  2. vue 将字符串最后一个字符给替换_前端开发:Vue项目实战-Music

    大家好,我来了,本期为大家带来的前端开发知识是"前端开发:Vue项目实战-Music",有兴趣做前端的朋友,和我一起来看看吧! 主要内容 项目环境搭建 路由导航实现 ListVie ...

  3. vue 动态添加class_前端开发:Vue项目实战-Music

    大家好,我来了,本期为大家带来的前端开发知识是"前端开发:Vue项目实战-Music",有兴趣做前端的朋友,和我一起来看看吧! 主要内容 项目环境搭建 路由导航实现 ListVie ...

  4. 【VUE项目实战】1、学习目标以及概述

    之前我们分别学习了ES6和Vue的基础,下面新开启的系列,是从0开始通过Vue搭建一个电商管理系统,从而学习Vue的具体实战. 以下博文记录,均参考黑马程序员(www.itheima.com)Vue项 ...

  5. 1.vue项目实战笔记(已完结)

    vue项目实战笔记 目标 目录 1.项目概述 1.1电商项目基本业务概述 1.2电商后台管理系统的功能 1.3电商后台管理系统的开发模式(前后端分离) 1.4电商后台管理系统的技术选型 1.前端项目技 ...

  6. 【VUE项目实战】68、使用pm2管理项目

    接上篇<67.上线-开启gzip和配置HTTPS服务> 上一篇我们学习了如何开启gzip配置来减少文件访问体积,并配置HTTPS服务.本篇我们讲解一下如何使用pm2管理项目. 本篇是该系列 ...

  7. 【VUE项目实战】32、权限管理-实现角色列表

    接上篇<31.权限管理-实现权限列表> 上个阶段我们完成了权限管理模块,本篇我们来介绍用户.角色和权限三者的关系,并完成角色管理列表模块. 一.权限管理业务分析 通过权限管理模块,控制不同 ...

  8. 【VUE项目实战】64、CND优化ElementUI以及首页内容定制

    接上篇<63.指定打包入口及加载外部CDN资源> 上一篇我们为开发模式与发布模式制定不同的打包入口,然后为项目加载外部CDN资源.本篇我们来学习通过CND优化ElementUI的打包,以及 ...

  9. vue 打开html流_在vue项目中添加一个html页面,开启本地服务器

    在vue项目里新增一个不需要登录的页面,那么我只能新增一个html页面了,不经过路由,直接在浏览器输入路径打开,那么就需要用到本地服务器, 1.vue里面的html页面最好放过在public文件夹里面 ...

最新文章

  1. eclipse折叠所有代码快捷键
  2. 树的先序遍历,中序遍历,后续遍历(递归和非递归实现)
  3. us域名在哪里注册_独立站如何选择一个合适的域名?
  4. 力扣538.把二叉搜索树转换为累加树(JavaScript)
  5. java类转换异常,java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
  6. LODOP批量打印多页模版进行维护
  7. Linux开机自动启动python脚本程序,或 Jetson nano或Jetson Xavier NX开机自动启动python脚本程序
  8. react梳理之redux
  9. 河南省周口市安吉软件测试培训中心第一次软件测试课程-计算机基础理论论篇
  10. 计算机系统基础实验2——bomb
  11. 学术Assignment写作怎么了解文献内容?
  12. 开关控制灯实验C语言编程,指示灯开关控制器实验.doc
  13. Spark创建hive表报错 ROW FORMAT DELIMITED is only compatible with ‘textfile‘, not ‘orc‘
  14. as打开时出现The environment variable JAVA_HOME (with The value of C:\Java\jdk1.8.0_101\bin) does not poin
  15. SpringBoot 全局事务配置
  16. SharePoint中在线编辑文档
  17. 如何利用Excel快速批量创建文件夹
  18. 二叉树的度为2的节点和叶子节点的关系
  19. vue3 操作修改数据
  20. mysql小练习--有题有数据

热门文章

  1. 总线宽度为32bit,时钟频率为200MHz,若总线上每5个时钟周期传送一个32bit的字,则该总线的带宽为 (4) MB/S。...
  2. 笔试强训48天——day29
  3. 【苹果相册推】怎么操作呢?是什么意思?
  4. Python读取两个txt文件内容,重新写到新的txt文件
  5. easypoi导入校验跳过空行_Easy-POI是一款Excel导入导出解决方案组成的轻量级开源组件...
  6. win7系统下阿里旺旺无法登陆怎么解决
  7. 漫谈程序员(十)大白菜装机版安装win7系统使用教程
  8. linux(四) -- 常用基本命令
  9. 头条号文章原创权益再降低申请门槛,人人都可以申请
  10. Python+PyQt5实现灭霸响指