00:00
上节课我们已经完成了数据的动态显示,我们把todo list数据放到了APP组件中,有APP组件传给他的子组件list,在list中进行数据的一个显示,那这一块我们继续完成todo list的其他的功能。接下来写一个添加的功能,也就是我们在这个输入框里去输入任务的名称,然后按回车键添加,诶比如输完任务名称之后,按回车键就添加到这个下面啊,我们来想一想啊,你要想在这里面输入任务名之后按回车添加,是不是我要给这个input绑定一个键盘事件,对不对,当我触发这个回车按键的时候,诶,我拿到我输入的这个值给它放到这个里面对吧?那我们现在就开始写,先找到这个引input的框。引input的框是在这个header组件里面。诶,那我给他一个键盘事件啊。K up啊,推荐使用这个k up,因为这个k up的话,它是这个键盘,我们完全按压以及释放完成。来给它绑定一个函数。
01:02
This handle。可以up啊,处理键盘按下的一个事件,这么一个函数,在这里来定一下这个函数。我们自己定义的用于做这个事件回调的这个函数啊,一定要用这个负值加箭头函数,这样你可以解决这个this指向的一个问题啊,这里再强调一下啊,我们把这个注释也写一下啊。键盘。事件。键盘回调函数来,因为触发这个事件的这个元素引input的和我们要获取它的这个值是同一个元素,对吧?我们是不是要拿这个隐的值,所以我们不用去绑定这个iff,直接用这个事件就可以了,对吧。先输出一下啊。第二,Target。点value看一下我们输入这个键盘,能不能拿到我们按的键盘这个值来输入这个值。
02:08
来打开这个调试。找到这个conrlo把它先清空一下啊,那我在这里来输入一是不是有234好,现在我们至少能输入这个值了啊,但是哎,我们现在有问题,我们不能说我一输入你这边就拿到这个值就去更新它,对吧,但我想要什么呢?只有我按下回车的时候才去,哎,输出这个值。才去获取这个值,也就是说我并不是按下所有键都去来获取这个值,只有按下回车的时候才获取,那这时候我们是不是要对我们的按下的这个键做一个判断,对吧?那我们怎么对按下的键做一个判断,那每个键我们都知道它是不是有一个唯一的这个编码,我们只要获取到这个回车键的这个编码,然后对它进行判断是不是就可以了?好,那怎么获取这个键的一个编码呢?哎,这是GS基础的一个知识啊。在这里啊,我来再打印一下啊。
03:01
获取键盘它的这个编码,哎,可以使用这个事件上面的K扣的这么一个属性来看一下啊。来刷新。现在我接着输一,哎,可以看一输出的49是不是二三,然后A,哎后面的这些,这个就是我们每个不同的键,它所对应的一个键盘的一个编码。那我们是不是判断这个值就可以了,接下来我来按下回车,我们看看是多少,是不是13,是不是只要判断这个13就可以了,哎,只有当它等于13的时候,我们才要这个值对吧?那反过来想,如果你的这个按键的这个编码值不等于13,那我直接就给你返回,我不做任何处理行不行,来写代码。在这写啊。如果按下的不是。回车键。直接返回。If if谁是不是这个你按下的这个键对吧,不等等于13,哎不是回车键,那直接掉可以吧,来看一下效果。
04:11
放心。好,那我现在随便输入是不显示,只有我按下回车的时候是不是拿到一只了,好,我们第一个需求已经完成了。哎,接下来看一看,呃,首先哎这个。K扣是它上面的一个属性,而我们拿着这个target也是它上面的一个属性,这时候是不是可以使用这个?结构赋值。Light。Target get。以及K扣的。啊,从什么从这个事件身上去解构啊,那这样的话。这个事件是不是就可以省略了,哎,我们这样写是不是简单一点。好,看一看效果啊。一样的啊。那接下来。这个值我们已经拿到了,接下来到了最关键的一个地方,我们既然拿到了这个值。
05:06
好。我们想要做的是什么?是我们在这里去输入了内容之后,然后回车是在下面。这里面去添加一条对吧,那我们想一想下面的这些数据是从哪来的,是不是副组件APP组件传给他的,哎,这里我画一下图,再给大家分析一下啊。我们最外层是不是有一个这个。APP组点。画小一点,最外层是不是有一个这个APP组件,对不对,那APP组件呢,数据,我们的todo list数据是不是都在这个APP组件上呢?对吧,那list它要做这个数据的一个展示,是不是从这个APP组件传给了这个list组件。来,我把这个第四元画一下,是不是给到他。对不对啊,那现在我hier组件我输写入了一个内容,一个数据,现在我想让这个数据给到谁,其实是给到副组件对吧,因为我们知道我们的这个数据,哎,我们的状态是在这个APP副组件里面,当我们的这个状态数据发生改变的时候,组件就会形成渲染,也就是说如果我能把hi里面我输入的这个数据我给副组件,副组件他去把自己维护的这个状态,维护的这个数据去更新一下,就会驱动。
06:16
这个数据的渲染是不是现在,所以我们要解决的问题是如何把这个数据。副组件啊,给这个。F组件啊。在这写下。对不对。你看APP把数据给到他做显示,那我这个harder里面,我添加的数据,我怎么把数据给到这个APP组件,让APP组件去更新这个状态,或者更新这个数据,因为你状态一发生改变,你会驱动的页面重新呈现吗,是不是?来,我们来想一下啊,那。Hier组件是不是APP的子组件,那list是不是也是APP的子组件对吧?那你APP你既然能给list的传数据,那你APP你父组件能不能给hier传数据?当然能了。啊,那我们来写一下看一看啊。
07:02
看一下代码在这个。APP组件里是吧,你既然能给这个历史的组件你传这个数据,你可不可以给这个还组件你传数据。对吧,比如我传一个AA等于什么A等于啊z.a来这里,我是不是需要一个A对不对。啊,那我直接定一个A等于一行不行。我在这里定义了A等于一这么一个数据嘛,然后我把这个数据,哎,通过这个呃,标签的,通过组件的属性传给这个header。看跟这个是不是一样,它这里面是不是就可以用pro接收了,来看一看啊。找到我们的组件啊。在这啊。那我在这里面就输出啊。输出谁呢?类似点purpose.a我看一下我副组件传递给他的这个A有没有拿到,好吧。来刷新。是不是看是不是数数一。啊,如果你感觉不太清晰,那我在这里再加一个hi。
08:04
加个大写的吧。是不是有还点一对吧,那说明什么。说明。APP既然作为这个副组件,我往你的这个哈点这个子组件里面,我传数据是没有问题的,我可以给你传,兄弟们我可以你传专业,那我既然我能传一个值过去。我可不可以传一个函数过去?对吧。你无非你你就是可以向子组件传东西吗?你管我传的是什么,我能给你传那个字符串,能传整形我为什么不给,能不能给你传函数可不可以啊,那我来看看,那肯定是可以的呀。这里看是不是传了一个函数过去好。传函数过去啊来,那既然我给你传了一个函数。你这边你是不是就相当于你这里是A,你是一个函数,接收到了一个函数对吧。那你这里这个A既然是一个函数,函数能不能执行?函数啊,当然是能执行了,我加个括号不就执行了吗?来我们验证啊,在这个APP这个组件里,哎,这个函数里面我输出什么。
09:05
点log。哎,我输出一个APP,嗯。就输出APP吧。方形A啊,就是APP里面的这个A。就这么就这么输出吧,来,那我既然是把一个函数我传给你这个子组件了,你子组件你这个你接收的A就是一个函数清楚了吗。啊,那你函数要执行怎么办?是不是要加括号。是不是?来。我直接在下面执行啊。上面我继续去输出我传的这个内容,下面我来执行这个函数,好吧,来看一看啊。发心有点多啊。好,这个是我header里面的输出,你看header里面是不是输出了我传的这个函数对吧,那这个f.a它为什么能输出,是不是因为我在这个header里面。
10:01
这个你看header JS,我是不是执行了这个,呃,我purpose里面我接触的副组件传的这个函数。看吧,那我们至少哎捋清了一件事情,就是说我呃父组件你给了我一个函数,我在子组件里面我是能执行的。对吧,好,那我们知道函数它有一个什么特性,函数是不是可以传参。对不对,你看这个括号。五号内容是可以传参数对吧,那比如我传一个AAA,呃,你既然你子组件里面你调用这个函数,你传了一个AA,那副组件我们这个函数定义的地方是不是要有一个。要有一个变量来接收。是吧,要有个变量来接收你,你传的这个参数啊。我来逗号打印你传的这个参数,看看能不能。获取到我这里传的这个A,哎,来,我们先猜想一下,如果出现什么结果就对了,你看我这里调用了这个函数传的这个AA对吧,那这里这个函数干什么?输出了这个APP,然后输出了传的值,也就说浏览器这个控制台里面如果能输出这样一个APP,然后连连上我传的那些A是不是就正确了,来看一下啊。
11:10
是不是输出了?我把它清空,再刷新一下。好,是不是输出了。那我们得出一个什么结论?首先第一个结论,哎,我们一步一步推演,就是父组件,你可以通过这个组件的这个属性往子组件里面去传数据,对不对?子组件里面可以用purpose去接收这个数据,对吧?这个是我们之前学过的,哎,组件的核心属性。这就明白了是不是,那接下来我们再往下接着推,你既然能传数据。能传这个字符串,能传整形,能传对象。那我为什么不能传函数呢?是不是我传一个函数过去,我就传了,怎么了,我们也验证了,你看传了函数,你是不是也接收到函数了?好,那既然父组件能把函数传给子组件,子组件是不是能通过prop接收到负组件传的函数,我既然能接收到这个函数,你是一个函数,你是函数为什么不能不能让我执行呢?对吧,那我就执行这个函数。
12:03
好,我执行了这个函数。可以执行,那我们又知道函数又可以有参数,那我在执行这个函数的时候,我是不是还可以再给你一些参数。看到了吧?啊,大家一定要把这个问题搞明白。因为我父组件如果想要向子组件传递数据,我直接通过这个属性是吧,通过这个purpose就可以了啊,但是如果你子组件你要想把数据传给父组件。那你没办法呀,你只能去借助这个函数,哎,父组件给子组件一个函数,然后子组件去调用这个函数,通过函数参数的形式把数据给回传给父组件,只能这么来。清楚了吧,啊好,那既然这个可以了,那我这里我既然可以传这个AAA是不是,而且我这个函数是在什么re的时候就调用,那我不render不在re的时候调用,我在只有你按照这个回车键的时候调用,可不可以?是不是,那我不传AA,我传你输入的这个值可以吧,然后把它改一改。
13:01
啊,那这里是不是就可以拿到你输入这个值,还有我们都叫A不不好不好听啊,我们改成data来,你输入这个值。好,来看一下啊。刷新。啊,我正常的输入肯定是没问题的啊,因为我只有按下回车的时候才会去获取这个值,并且。再看一下代码,并且干什么。并且去呃执行。负组件传过来的这个函数对吧,那这个函数呢,我们把这个我们获取的输入这个值作为参数传给这个函数,这个函数里面就可以拿到这个参数来验证一下啊。回车是不是拿到了,你看APP里面是不是输出了它。这个是hard里面输出的吗?这是个F输出的啊。接下来我们再想啊。呃,现在至少我们在这个APP组件里面,我们能拿到输入这个值,对吧,那你能拿到这个输入的值,你去更新一下自己的这个组件的状态不就完了吗?你把你输入的,哎,我们输入的这个值再给它加一条不就完了吗?对吧,那你状态组件的状态你改变,你是不是就驱动的这这个子组件也会发生改变。
14:06
对不对。哎,我父组件的我这个状态发生改变了,那你子组件你用到我这个状态了,你子组件是不是也会发生改变,那整个页面的数据是不是就会出现渲染会改变。是不是这样的啊。那么把名字改一改,那叫A肯定不合适啊,我们叫ADD todo,好吧。来艾特图do。那这里,哎。就不是this purpose,是todo。那爱的出入。接下来接着说我们的这个问题啊,我们这边既然拿到这个输入的数据了,哎,是不是要给他去增加一条就可以了啊,但是啊。你注意啊,我们拿到的是什么?拿到的是一个字符串,看到了吧,啊。我们这个数据它是什么,它是一个对象。所以呢,你在这里去封装这个对象是吧,那或者说呢,我们干脆不在这里,哎,我这个副组件我就比较任性,你给我的数据必须是我直接能用的,你要给我对象才行,哎,你直接给我封装好这样一个形式你给我。
15:04
清楚了吧?那我们先说这个数据的事儿,我们先把这个爱的todo。这个逻辑给写完,接下来再说这个数据类型的问题啊,先把这个注释写上啊,添加一条。添加一条todo啊。来,一步一步写,第一步先干什么?是不是先获取?原来的。Todo啊,我就这里说todo啊,Light。土豆子。等于谁是不是this state里面去结构。哎,从这里面去得到这个todoth对吧,那我为什么要获取了原来的todo,因为我要给它增加一条,我就先打先打拿到这个原来的是吧,啊来。新的。
16:01
To,毒死啊。再定一个新的todo。为什么要定一个新的?这是原来的,我要给它增加一条,那增加增加一条以后是不是可以得到一个新的来,我们来分析一下原来它是一个什么,是一个数组,我们怎么给数组去增加一条。是不是可以直接用?展开运算符,把这个,呃,我们原来的这个先给它展开,对不对,那我新的这一条啊,新的这一条。要往谁上面加,是不是要往它上面加,我把它加在这个前面清楚了吧?啊复制错了啊是对啊。对吧,啊,那我们如为了区分我们的数据,把它给,嗯,再加个OBG啊对象啊。对象数据啊。我们等会再处理这个组件去,哎,传这个对象数据的一个问题,我们先把这个添加一条todo给写好,好吧。来先获取原来的,接着呢,我来先定一个新的,新的等于什么,新的等于原来的,加上我们新增的这一条,而且我们把新增的这条放到了前面,对吧,那接下来是不是该更新状态了,更新。
17:11
组件状态,哎,怎么更新,是不是this set state?哎,更新谁是不是更新这个todo啊,就等于这个new todo。这样是不是就完成更新了。那接下来就开始,呃,考虑我们这个数据的问题了,哎,我们说了,你不能直接给我一个字符串,你给我一个字符串,我这边还得处理,那我想要的话,你就直接给我一个这么完整的一个对象。清楚吧,啊,那这里我们就不能直接给这个一个Y轴了,要给什么给一个对象啊。来对象,对象有什么,有一个ID对不对。好ID,这些ID呢,我们尽可能保存,唯一现在,呃,我们先随便写啊,先写个004,等会我们再说这个ID的一个问题,接着一个Y6。哎,不是y title。Title就是我们输入的这个,哎,Todo,我们要做的一个事情,最后还有一个什么属性,还有一个。
18:04
这个啊,但那你新添加的肯定是没有完成的呀,那就是for呗,对吧,那你只有勾选完成才能完成,所以现在这个我们先写的for啊,这个ID我们先不用管,先写四我们看看这个数据能不能给加上啊,那这个输出也不要了啊。嗯,先看效果吧,等会再补注释啊,刷新来。现在我输入一个AA。报错了啊,他说这也不是一个函数啊。来,这就说明这个问题,这不是一个函数对吧,那我们这个函数明明改过来,为什么它不是函数呢?注意啊。你改的什么,你改的是这里,以及改的是这里,然后还改了这里,但是purpose他接的是谁?他接的是我们前面传的这个K啊,是他。对吧,名字他是去找他,我们这里pro,他找的是这个,哎属性。不是值,是找到这个属性清楚了吧,哎,所以这里也要改来再试一下啊。好,把它清空下来是A。
19:02
是不是天天上来了?啊,而且这个是我们APP这个组件里面的一个输出,对吧,那接下来我们来考虑一下这个ID的一个事情,我们肯定不能把这个ID写死,那你再添加一条。你ID写死了,你ID都一样了,这里啊,直接就给你报错了,你用了相同的一个K14对吧?啊所以说。呃,因为历史里面做了这个。一个便利嘛,而且每一条的这个ID,这个K都不能相同,对吧,就是这里嘛,你看我们这里就做了这个便利,这个K你不能相同,所以我们得保证这个ID是不同的,你不能这么写死啊,那怎么不同?我们来怎么写?你想到什么,比如说想到用这个时间窗,那时间说你你看的是不会相同,哎很快,但是你保不齐你这个项目啊,一秒有几百万人访问,几十万人访问,那你一秒可能有很多的这个。同样的时间说写进来,所以时间轴并不靠谱啊,你用随机数也不靠谱,你再大的随机数它也可能出现重复的时候。
20:00
清楚了吧,啊,这时候给大家说用于什么呢?用一个呃,这个UUID啊,UUID呢。看着挺长,但。我们来看一下它的解释啊啊,它其实就是呃,唯一的一个ID啊,UUID,它会通过一系列的算法给你生成一个全世界都不重复的一个ID。啊,通用唯一识别码。哎,它就是通过一些特定的算法,就是给你生成这种全世界都不会重复的一个。一个这个ID啊,当然它是一个字符串类型的啊,好,如果你要使用这个UUID呢,你要去安装这个UUID的一个库。哎,亚ADUUID,但是啊。这个ID呢,它比较比较庞大,那我们用什么呢?用一个比较小一点的啊,比较迷你的一个nano ID,嗯,这个呢,它也会生成一个唯一的ID,但是它会比UUID啊要精简一些,我们就使用这个啊。亚NDD,哎,你如果是使用的是NPM,没有装这个亚,你就是NP mi。
21:06
那个ID啊。这只是装一个扩展而已,装一个库而已,来。我们先把它装上啊,那先让他装着,我们把那个注释补一补啊,等他装完我们再说啊。这个是调用。附组件。副组件。传递的函数啊。将。获取。God。将输入的数据吧。通过函数参数啊传递给。副组件,好,这个注释已经写的很详细了啊。这个已经安装完了是吧,那我们看看它怎么用啊。首先你要使用它,你得先哎引入它啊,注意我们引入这个顺序,你不能说你这个下面顺手,你就在下面去引入了,这个引入顺序呢,有一定的这个啊规则也可以说是约定啊,虽然说你执行代码你怎么引都行,但是我们还是按照一定的约定来啊,就说第三方的一些,首先我们放上面,我们自己写的放中间C还是放后面清楚吧,那这一个第三方呢,我们就放到最上面啊。
22:23
引入。哪种ID,哎。From哎,其实刚才我在打的时候呢,他已经在给我提醒了是吧,你看就直接会from他啊,但是你全部你手打打完也行,诶他呢,就是使用分别暴露的方式,就暴露一个拉ID哎这么一个函数。对吧,每次我们执行这个函数,都会给我们生成唯一的一个ID,我们来试一下啊,在哪试呢?直接在这个render里吧,对吧,因为render的话一渲染它就会执行嘛,来。Log。Nano ID,哎,它是一个函数,我们要执行啊,来,我给大家输出三个,大家看一看啊。
23:00
刷新。没有启动啊。刚才安装组件,我把它给停了。再启动一下。这里是不是输出了三个。这个对吧,那我再刷新一下。可以看到是不是不一样,哎,每次它执行这个函数都会生成不一样的一个ID,那既然它是唯一的,我是不是可以用它做ID就比较。好了。来,那我把这个删了啊。直接剪切一份。这个ID就不写死了。把它给写上。接下来回过头来刷新。哎,其实不刷异型,它编译完成会自动弹新,那我们填一个A。签个B是不是不会出现报错了,而且ID每个都不一样,对不对,你通过这个工具我们来看一看。你看这个结构还是比较清晰的,你看APP组件包含了这个header list和foot,对吧,那list里面也包含了这个item,每一个的item它都有自己的这个ID啊,ID还都不一样。
24:09
而且看下面的这个细的这个数据,我们加的这个数据也会在里面,哎,我们再加一条,比如C也会出现在这里面,是不是好,那这样的话我们添加数据就写完了,哎,但是会有一些小问题,什么问题呢?我们来看一看。第一个问题,我现在什么都不输入,哎,是空的,你看空的也能听见。对吧,那我们得做一个一个非空的一个判断,对不对,如果你是空的就就不让你添加啊。判断啊,如果没有输入任何内容。直接啊提示。If。
25:01
点八六啊,等等于空。就先用A了吧,啊,请输入内容。哎,之后一定要记得return掉啊。你不掉它下面还会继续走,兄弟们接下来看一看啊。现在我输入内容正常来,如果不输入内容,你看是不是弹出请输入内容,好接下来还有什么问题呢?就是你看一下我输完这个内容之后,哎,B这里面还留着呢,我们是不是输完之后要把它给清空量,哎,清空比较简单啊,那清空就是呃,在你调完这个啊副组件的函数传完数据之后,那我就清空已输入啊,清空已输入的内容,诶清空的话呢,直接让这个。他点Y6等于空就可以了啊,这样就行了。看看一下啊,那我输个A是不是清空了,哎,如果空的话也不能输出,那这样的话,这个添加就完成了啊,最后再给大家总结一下。
26:09
最外面是一个诶APP组件对吧,那数据我们的状态就是保存在这个APP组件里面,谁来做展示的,是list的做展示,所以直接通过purpose传给这个list,对不对,现在。就是例子啊,那我们在这个header组件里面写了内容之后,想要把数据嗯给到这个副组件,让副组件去更新它的状态。那你怎么把数据给到副组件?哎,这时候,哎负组件。我既然你是我的子组件,我可以给你传数据对吧,那我给你传什么,我给你传一个函数对不对,你通过调用这个函数给我传参数的形式,把数据给我拿回来。是不是好,那我把这个文字给大家写一下,大家看一下啊。通过purpose,哎,传什么呢?传那个历史的数据过来,是不是传那个todo。
27:01
啊,绿。这时候他就可以做展示了,对吧,那我APP组件。那我给你hi的组件,我传什么呢?也是传了一个purpose,但是这个purpose它不是一个todo list,哎,我给你传什么。Purpose,这个purpose呢,它是一个function。清楚吧,啊,我给到这个哈的组件,哈的组件怎么办哈组件可以去哎,调用这个function写。对吧,调用这个函数的时候呢,可以把这个数据给到这个副组件,是不是这么一个流程。啊,这个就是呃,子组件如何向父组件去传递这个数据。最后来看一下代码。我们确实也是这么做的是吧,你看传了一个函数,诶,在这个子组件里面去执行这个函数,把需要的数据,哎,子组件通过这个函数的参数去传给这个副组件,然后在父组件里面接收到这个数据,就可以做一些操作了。
28:03
这样添加to list就写完了啊,把这个输出给删掉。
我来说两句