今天做了一个案例,可以好好做做能够将之前的内容结合起来,最主要的是能对组件化编码流程有一个大概的清晰认知,这一套做下来,明天自己再做一遍复习一下,其实组件化流程倒是基本上没什么问题了,主要是很多vue的方法需要多熟悉一下,毕竟打破了之前的一些对于传统js的认知,还需要多熟悉一下。
这两天可能内容不是很多,因为有点感冒了,状态不是很好,不想学多了怕接受的是不是很好。
六.TODOList案例
做这个案例主要是为了能够熟悉组件化编码流程,刚开始学做一个项目最好按照以下三个步骤来
1.实现静态组件
先把一个项目抽取组件,使用组件实现静态页面
比如这个案例App的子组件就可以拆分为三个上面输入框,中间列表展示,下面总结栏,其实组件的划分就是按照他的功能点来划分的,
比如子组件按照功能划分了三个组件,list里每一个item是不是有自己的功能可以勾选,可以删除,所以又可以进一步细分组件(如果你拆完一个组件发现很难起名字,说明你拆的不是很合理)
- 既然已经拆分好组件了,就可以去vue项目里面写我们的组件了,创建、导入、注册三步曲完成
-
接下来应该有我们的静态模板了,是这样的,一般情况下我们的一个项目大多数已经完成了一些了,所以不会从零开始,这个时候老板派给你个任务叫你把这个实现组件化开发,你就直接把html先一股脑的塞到 App.vue里面,可以启动服务器看到整体的一个效果,然后再去一步一步把代码拆分进我们的组件里面去
注意:有很多问题是语法报错,将那个lintonsave关闭即可
-
然后就可以开始拆分了,其他不说这个list里面每一条数据看出了拆分组件的重要性,我直接在list组件复用item就可以了
-
css拆分时要注意:base等公共样式放在App.vue,其他各自的样式各回各家但是要注意添加scoped
2.展示动态数据
将我们项目中需要动态真实的数据存起来 一般是数组加对象的的形式,一个对象一条数据里面有id、name等等
那么数据一般保存在哪里? 回顾一下之前props的案例,我们的数据是不是写在父组件里面的,通过子组件标签传给了他,子组件才能用props来接受外部传来的数据,所以我们的数据要定义在每条数据这个组件的父组件
在我们定义数据这里几个注意点:
- id为什么用字符串,因为数值型会有上限,字符串没有
- 既然数据都有了,所以这里就不用一个一个去写子组件标签了直接v-for列表渲染
- 最关键的:我们要将数据传到子组件里面去吧,这里不再是像以前那样,一个一个传,这里直接是传的一个对象,而且还是遍历出来的每一条对象,还必须要动态绑定,不动态绑定这里就是一个字符串
子组件这边,注意一下props接受参数要用引号包裹,然后就是怎么来让我们的复选框动态的获取到有没有勾选,让其动态绑定值为我们数据里面的值即可
3.添加
首先我们实现回车添加数据的逻辑,肯定是要生成一个对象然后添加进那个数组里面,这里的id由于灭有数据库支持,就采用了一个包,uuid可以生成全球唯一id,但是他体积表较大,这里用的是另一个体积小一点的 nanoid
接下来问题就来了,我们这个数据是在header里面添加的,而我们的数据是在list,我们学过父组件给子组件传数据(props),但是没有学过兄弟关系来传数据吧,这里才去最基础的方法来实现
我们吧list里面定义的数据data放到app组件里面去,然后app通过动态绑定将数据传到list的组件标签,这个时候list用props来接受传过来的值
最主要的是怎么把子组件header传到父组件app里面去:我们在app定义一个函数然后接受形参,将这个函数动态绑定给到header,header通过props就能够得到这个函数,然后重要的一步 我将这个函数写在键盘事件里面,同时参数是我们的创建的数据,就相当于调用了这个函数,调用不要紧,关键是这个函数式app送给你用的,你调用(送给你用的所以拿过来是存在于vc实例对象上)拿我app不就拿到了这个参数吗所以,app现在又有参数,又定义了数据,那么添加的逻辑就开始了
4.勾选
我们要在item里面来勾选,从而影响到数据里面的completed这个选项,我们的数据是定义在App里面的,有一句话叫做 数据在哪里,那么处理数据的方法就写在哪里,所以这里好像又要用到子组件给父组件东西了,给什么?我勾选的状态实在item里进行的,我必须拿到勾选的这一个id,才能在处理数据的方法里面以id为参数对数据记性遍历找到对应的那一个将他的completed的值改为非值
这里有一个注意点,把我们之前这个勾选的所有逻辑推翻,直接在item的input标签里面写一个v-model,我们说复选框v-model默认收集的是checked的值,如果我把v-model设置为todo.completed是不是就让我们的checked动态绑定了,他为true,checked就为true,第一步初始化数据的勾选完成了,这里还有一个更重要的,你该数据也同样可以改到data里面的数据,因为v-model本身就是双向绑定,但是我们前面也说过,props接收到的数据不能改,这里很明显是通过props传过来的数据改到的,为什么这里没报错呢,因为vue对于对象改动的检测有点类似于 const,一般数据确实数据变了就是改动了,但是数组和对象通过属性名或者下标去改某一个值并不叫改动,要变动整个数组和对象才叫改动,所以这里没有报错,这个方法是简单但是,官方定义的props传过来的数据不能改,最好还是不要改,万一哪天这个数据不是对象里的值了,就麻烦了,最好还是按照语法规则来
5.删除
主题逻辑刚上面差不多,点击删除返回id,app传过来一个函数接受这个id,然后数组的筛选方法filter让我们的数据等于筛选出来的新数组,这里就不考虑性能问题了,假装是个标记删除吧,删除了虽然还在但是也永远不会给你显示出来了,所以可以直接把他赋值给这个原数据,还有一个点confirm确认框,会弹出一个对话框内容为你传进去的参数,配合if来使用可以达到只有你点击确定了才会执行后面的逻辑
6.底部统计
既然是统计,那肯定要用计算节点来做,这里用到了数组的reduce方法,要注意的是,prev每次返回要等于他自己
7.底部交互
先完成我们点击了所有的勾选框,下面全选会勾上,但凡少勾选一个都不会钩上的逻辑,其实很简单,将我们全部的这个数量也弄成一个计算属性,然后将我们全选动态绑定,且返回值也由计算属性来决定,直接去比较已完成和全部是否相等
探后就是我们的全选功能,逻辑是这样,点击一下,通过e获取他的checked的值,然后又要动到数据了,需要app里面对数组做一个循环对所有的数据的completed的值都等于这个checked的值
但是这样有一个bug,当我们删完后,会是勾选状态,应该为不勾选并且隐藏掉
在我们刚才完成点击点击上面,下面全选也会对应去勾选上那里的逻辑完善一下,因为原来的写法,就是当已完成和总数一样的时候就会勾选上,那么最后删完了,也是一样的所以不行
通过v-if添加在footer即可
好了,可以忘掉这一章节实现的功能了,简便方法他来了
我们这里的全选框有些啥子东西,一个管初始化读取数据的,一个改数据的,又是input,读写,想到他没有v-model
我们用v-model去绑定isAll的值也就是判断有没有全选的值,即可完成读的操作,仔细想想是不是
但是这里改的话会报错,为什么?
因为我们的isAll是计算属性,你改动他的值,你setter都没有怎么改,所以这里要这么做,定义一个setter,并且把这个值给到我们刚才定义的循环让所有值都等于这个checked的App组件上的函数
为什么这里可以使用v-model前面是因为那个值时props传过来的值肯定不能改,而这里是我们写在这个组件的计算属性属于自己的
8.清除已完成的任务
最后一个功能,很简单直接一个点击事件,在app这边做一个数组筛选,筛选的是completed没被选中的
9.总结
组件化编码流程
- 拆分静态组件,按照功能拆分
- 实现动态组件,考虑好数据的位置,如果数据是一个组件在用就放到这个组件,如果数据是一些组件在用,就放到他们的共同的父组件(这种方法也叫做状态提升)
- 实现交互(从绑定事件开始)
- props不仅适合父给子传数据,还可以子给父传数据(父会给子一个函数)
- v-model注意修改的值是不是props过来的,不是他过来的还是可以用的还是很方便的
- 修改对象里面的值跟const一样改单个值不会被发现,要修改整个对象