# kill-coronavirus **Repository Path**: lxsee/kill-cronavirus ## Basic Information - **Project Name**: kill-coronavirus - **Description**: 疫情防控下核酸检测结果查询和预约诊断等功能 - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2021-12-11 - **Last Updated**: 2021-12-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # kill-cronavirus ## 进行中 #### 介绍 疫情防控下核酸检测结果查询和预约诊断等功能 实现自己和家人检测和预约信息的查询和管理 开发流程大致:创建可复用组件->布局组件->数据库设计->接口开发->网络请求->优化->部署上线。 #### 软件架构 ##### demo1 初始化目录结构 ``` src assets 管理静态资源 css 管理css文件 image 管理图片资源 iconfont 管理iconfont上下载的字体图标 components 管理小型组件 common 管理可在其他项目中复用的组件 content 管理和本次业务相关的组件 network 管理与网络相关的资源 router 管理路由相关资源和配置 store 管理vuex相关资源 views 管理本项目中的大型组件 2views 管理二级页面 App.vue main.js ``` ##### demo2 使用normalize.css,创建base.css并在全局下使用 ``` css normalize.css base.css ``` 在base.css中导入normalize.css,在App.vue中使用base.css 防止css串扰可以使用scoped,但我更习惯维护一张记录了所有类名的表格or科学设计类名 ##### demo3 设计可复用tabbar 通常tabbar的高为49px ``` components common tabbar TabBar.vue TabBarItem.vue ``` TabBar中预留插槽放TabItem TabItem中预留两个具名插槽放图片文字,任何传入的图片大小都适应为25px*25px 技巧:给插槽设计样式的方式是给slot标签套上一层div,把样式加在div上 在content中利用common中的可复用组组件创建适用于本次业务的的tabbar组件,命名为THTabBar.vue 将THTabBar.vue使用在App.vue中 ``` components content tabbar THTabBar.vue ``` tabbar隐藏规则:THTabBar.vue的included中不包含的路由下,tabbar会被隐藏 ##### demo4 tabbar实现路由切换 首先要创建三个大组件:home|erweima|profile ``` views erweima Erweima.vue home Home.vue profile Profile.vue ``` 再对组件绑定点击事件,编程式的路由跳转 编程式的路由跳转返回的是一个Promise,最好catch一下该promise,以防止跳转到相同路由时console.error 由于是一个tabitem对应一个路由,因此tabitem应该接收path_作为参数 个人习惯在参数的命名末尾加上_ 路由采用懒加载,默认路由为/home对应路由。模式采用history tabbar中的路由是不可回退的,若某些情况下想要回退,请使用backbtn中的重定向 ##### demo5 tabbar提供个性化设计 设计tabbar使得用户可根据喜好调整背景、文字颜色,激活时样式切换。 在tabitem中加color_|activeColor,img_|activeImage_。 ``` 文字: :style="{color: isActive ? activeColor_ : color_}" 图片: 父组件把图片路径作为参数给子组件时,子组件会当作普通字符串而不是当作路径,导致子组件无法正确显示图片。 因此,父组件在传路径时要结合v-bind和require :image_="require('@/assets/image/vue.png')" 子组件中: :src="isActive ? activeImage_ : image_" ``` 激活条件:当前活动组件路由等于组件参数中的path_,该Boolean类型设置为计算属性。 ##### demo6 允许tabbar中间的item为圆形按钮 传入circle_这个布尔值给tab-item,true则显示circle样式,否则显示普通样式 注意在传boolean值时,要结合v-bind,如:circle=true,否则子组件拿到的是字符串 ``` :class="[circle_ ? 'circle' : 'tab-item']" ``` ##### demo7 设计顶部导航navbar NavBar设置3个插槽,可以填充任意组建,如burger、描述等信息,三个插槽采用三栏布局,两边宽高固定,中间自适应 navbar高度一般都为44px ``` components common navbar NavBar.vue ``` 提供个性化改变navbar背景的功能 将导航栏用于本项目时,要考虑插槽中个性组建的设计,以及随路由切换的样式变换。 ##### demo8 不同页面对应不同导航栏的实现 因为不同tab页有不同的navbar,因此要多次使用navbar标签,同一时刻只选其一渲染。 为了避免App.vue代码量由此变很大,可以将这多个标签封装在一个组件中,由条件分支语句控制渲染。 ``` components content navbar THNavBar.vue ``` ##### demo9 导航栏中常用组件设计--burger菜单栏、回退按钮 通过一个按钮决定菜单的显示与否 样式上,菜单未打开时,按钮的样式为两条杠,打开时样式为叉号,其中的动画效果由transition控制 菜单的展开动画由变原点的absolute和transition实现,菜单宽高由calc计算得来 可以个性化设计杠和叉号的颜色、菜单颜色,菜单预留插槽用于功能扩展 ``` components common burger Burger.vue ``` 回退按钮可以指定默认返回路径,也可以重定向 ``` components common backbtn BackBtn.vue ``` ##### demo10 创建导航组和导航条,提供个性化设计,为导航条添加跳转功能,将burger和导航组合在一起用于本项目业务 ``` components common navigation NavGroup.vue NavItem.vue ``` 导航组中提供插槽放导航条,导航条底部有用scale实现的0.5px的伪元素线条,以及用伪元素设计的箭头 箭头采用字体图标 [伪元素中使用字体图标](https://www.jianshu.com/p/495ea1826920) 导航条提供三个插槽,采用三栏布局,可以插入文字、图片等 导航条的伪元素线条可设置取消,但由于该线条是伪元素,因此需要通过v-bind结合css变量来控制线条的显示 ``` :style="{'--display-type': showLine ? 'block' : 'none'}" data() { return { "--display-type": "" } }, props: { showLine: { type: Boolean, default: false } } display: var(--display-type); ``` 同样的思想,可以实现个性化设计底线和箭头颜色的能力 导航条统一跳转至二级页面(tabbar会被隐藏,navbar提供关闭按钮),使用编程式的路由跳转 组件设计好,就可以组合在一起用于本次业务了 ``` components content burger THBurger.vue ``` ##### demo11 完成“首页”和“我的”两个页面、以及涉及到的所有二级界面 用之前创建好的组件进行布局即可 ##### demo12 修改密码时的popup弹出层设计 给自定义组件添加原生事件使用.native修饰符 ``` ... ``` popup背景有一个遮罩层,点击遮罩层可以销毁popup popup组件自身的点击事件会触发父组件有关值的改变,此处需要子传父通信 ``` 子:this.$emit("hidden") 父:... popUpClose() { this.isPopupShow = false } emit触发close事件,close事件调用popUpClose方法 ``` 点击子组件时,会触发父组件的点击事件,为了阻止事件冒泡,需要使用.stop修饰符,且子组件的点击事件绑定到一个空函数上 ``` @click.stop="doNothing" doNothing() {} ``` 动效:popup中的卡片有渐入渐出的效果,可用vue的transition过渡配合实现 popup组件中有控制卡片显示与否的状态,默认为假,mounted时改为真,这会触发enter-active过渡钩子,触发进入时动效 当遮罩层被点击时,先不触发hidden事件,而是改状态为false触发leave-actice钩子,过度结束后再触发hidden ``` 延迟触发hidden的处理: let timer = setTimeout(() => { this.$emit("hidden") clearTimeout(timer) },200) ``` ##### demo13 v-for渲染自定义组件 项目中多次用到v-for,此处举例message-cell的渲染 加v-bind:key解决节点复用时的性能问题,且vue建议不要给key对象类型, 和微信小程序不同,vue中元素属性赋值无须mustache语法 ``` ``` ##### demo14 keep-alive下的路由传参 从AppointList跳转到Appointment时,要携带一些数据给Appointment 但由于设置了keepalive防止组件被频繁创建和销毁 因此下一次跳转到Appointment时不会重新开启生命周期,则数据不会重新渲染 所以可以在keepalive上加exclude ##### demo15 slide-select组件设计 样式设计上,采用单元滚动效果,当滚动范围超过单元的一半时自动滚全 关键代码 ``` 父盒子:scroll-snap-type: y mandatory; 子盒子:scroll-snap-align: start; 解决移动端的小bug:pointer-events: none; 需注意的是scroll-snap-type很新,兼容性不是很好,但移动端没问题~ ``` 使用选择器组件时,只需传入数组和指定的选项即可 在组件创建时,会筛选并去重传来的数组(采用映射和集合类),得到的结果作为真正用于渲染的数组 ``` createItemList() { let temp_arr = this.list_.map(item => item[this.key_]) this.item_list = [...new Set(temp_arr)] } 在created生命周期内调用该createItemList ``` 如何判断选中了谁呢? 首先是给可滚动元素a添加ref以便于操作它的dom 点击确定时获取a的scrollTop,scrollTop是指a中内容的顶部减去a顶部的差值,或者说滚动条和顶部的距离 用该差值处以选项的高度,就可以得到选项的索引 再到选项列表中找到选中的值即可 ``` mounted时: this.main = this.$refs.main 点击确定时: let result = this.item_list[this.main.scrollTop / 40] this.$emit("onselected",result) ``` 举例:在Result组件中使用SliderSelect组件 点击确定后渲染筛选后的结果 ``` startFilter(key) { let temp_arr = this.detail_list.filter(item => item[this.key] == key) this.detail_list = temp_arr this.hiddePopup() } ``` 双向绑定原理: 父组件传参数给selector,selector调整scrolltop到参数指定位置 子组件通过$emit让父组件知道选中了哪一项 ##### demo16 分析各个组件之间数据的联系 注册页面需要的信息: 证件类型、证件号、姓名、性别(自动识别)、年龄(自动识别)、检测地点所属市区、电话、密码 登陆界面: 手机号、密码 AppointmentList中: 姓名、预约日期、检测地点、状态 根据名字筛选 MakeAppointment.vue: 姓名、检测地点、检测地点所属市区、预约日期、预约时段 FamilyMember.vue: 姓名、电话、证件号 AddNewMember.vue: 姓名、与当前用户关系、证件类型、证件号、电话 Result.vue: 姓名、检测地点、检测单位、预约日期、样本类型(检测项目)、报告完成状态 根据名字筛选 ResultDetail.vue: 姓名、证件号、采样时间、检测地点、样本类型(检测项目)、检测单位、检测日期、检测方法、检测结果 Erweima.vue: 姓名、证件号、当前datetime 能切换家庭成员 Profile.vue: 姓名、电话 UserInfo.vue: 姓名、性别、年龄、电话、地区邮编、检测地点所属市区、信息登记时间 可改电话和所属地区 ##### demo17 设计数据库 后台开发流程可看我的另一个仓库,本仓库只说明前端相关的内容。 ##### demo18 发送网络请求,引入vuex 使用axios发送网络请求,一个页面对应一个封装了网络请求的js文件 举例: 登录时发送请求验证,验证通过后返回用户信息,由于用户信息在多个组件中都会被用到,因此存入store中 ##### demo19 修改密码处自定义组件的双向绑定 子组件中使用v-model,用watch监听data中双向绑定的那个值,当该值发生变化时,触发父组件改值事件 ##### demo20 完成所有的网络请求 #### 安装教程 1. xxxx 2. xxxx 3. xxxx #### 使用说明 1. xxxx 2. xxxx 3. xxxx #### 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request #### 特技 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md 2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) 6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)