00:01
来,我们先来把我们。昨天讲的东西给过一下,昨天我们主要做了这么几个事情,第一个事情去实现了我们的什么,是不是登录的功能,也就是我们涉及到是不是前后的交互呢?这是第一个,第二个呢,是我们整个后台管理界面的一个结构,是不是搭起来了。以及它里面的路由这个结构里面就包含它里面嵌套的子路由啊,最后一个就是去写了这一个左侧导航的这个主页。啊好,我们来看一下。那首先做的第一个事情呢,是我们要去启动我们的什么后台应用,其实我们后台应用是不是已经写好了,而且我们当前是用GS写的吧,但是你们公司的后台一定用G吗?其实有关系吗?没有。
01:00
因为我们最终需要的就是一些接口吧,他无论是用什么语言写的,最后我们去发请求和接收的基层数据是一样的吧,没有区别,能听懂不好,那我们后台应用呢,其实我们已经写好了,也就我们的这个serve搞白了。那我们要做的是不是将这个后台应用给他什么启动起来,记住一定要将后台应用启动,你才能访问。啊好,但是这里要注意我们因为我们用到了芒果,所以需要用了芒GODB啊,需要把芒果DB的服务给了什么,先启动上。好,一旦我们的应用启动以后,那也就说,比如说我们现在的应用是不是就已经启动了呀,后台应用程序已经启动了,那它是不是就提供了一些接口让我们去访问,那到底提供了哪些接口,我怎么知道的呢?看什么,是不是看接口文档对吧?那也就是说公司会给你提供一些啊一个接口文档,让你去看当前项目里面到底有哪些接口是不是。
02:13
这能听懂吧,啊来啊,那接口文档的形式,也就是什么类型的文件,其实不关键,关键是你要知道。接口文档里面是不是应该描述的是项目中所有接口的一个信息。那某一个接口的信息有几个部分组成呢?四个部分组成,对吧,有三个是决定请求的URL,请求方式以及什么请求参数的格式,对吧?第四个是什么响应数据格式。那一说文档里面就是描述这些信息的,对不对。其实你要知道这些东西,你就换成什么文档,你应该都能看得懂。
03:00
啊,这是这个。那我们后面就有一个很重要的操作,我们是不是要测试接口文档跟我们的真实接口是否一致吧,那我们去测试的时候用什么工具呢?我们是不是用的是一个工具叫什么postman对吧。那测它的时候注意啊,就有一点,有一个特别的地方,就在于它的那个post的请求,请求参数的设置方式跟我们平常的不太一样啊,跟get的请求是不太一样的,大家注意这一点,还有我们测试的结果可以是吗?保存起来是不是。那我们保存的所有接口啊,是可以把它导出吧,导出以后其他人还需要一个一个添加吗?不需要了。嗯,这个需要去知道怎么回事啊,他正在登录,那就能看到我当前的某一个接口的情况,昨天我们不是测试了那个登录的请求吗?一定要保证啊你。
04:02
啊,昨天就有同学是这么写的,写了5000,怎么可能成功呢?能听懂吧,啊,这个不用背,其实这这没什么好背的,就是你要知道我请求地址是多少,根据文档来操作就行是不是。嗯,这里面刚才说过了,唯一要注意的就是我的显示参数是放到这个里面,也选择第二个是吧。嗯,昨天就有同学把这个信息参数放在这个头里面了。对吗?不对,是要放到请求体里面是不是。啊,你现在犯一错误很正常,这个这没关系啊,我去提这个事,并是并不是为了批评你或者打击你,我这个是意思啊,就现在犯任何错误都都是大家一个成长的一个过程,没关系的。啊,这个。要注意一下啊,行,Postman的基本使用技巧大家需要去会,到了公司必然会用到啊。
05:02
好,这是这个好,那接口都测试通过以后,那后面我们是不是要去写代码去发请求。那写代码发请求,首先我们会封装一些请求的一些代码。啊,当然,首先我们说一下我们应用中用的是哪个库来发加请求。Access对吧,那我们最终调用是不是应该我们是在组件中是不是要触发发请求的一个操作,那我们是在组件中直接使用action发请求吗?在写前面写学技术的时候,学基本技术的时候,就这么做的吧,就是这么做的,在组件里面直接用XS发就。但是真实项目中肯定要做一些什么封装,就定义一些更加好用的函数,是不是来进行处理,那我们其实我们的这边进行了两层封装,两层。
06:06
先封装的一个函数,我叫它什么呢?X函数,这个函数专门用来干嘛呢?把请求的,也就是说任意啊接口的这请求是不要都要通过调度函数,那他要接收几个参数。是不是三个呀,因为我们的请求需要三个条件嘛,是不是啊,请求URL,请求方式以及请求参数对不对。啊。但是这这层做了这一项封装就够了吗?还不够,这样的话,我到每个接口是不是都要去传他请求的地址,请求的方式对不对。但是每某一个接口,它的地址以及请求方式应该是什么?特定的也就是固定的对不对,比如说登录的接口,它的地址以及请求方式会变号吗?
07:02
不会,所以我们在这一层上面再做了一层封装,叫接口请求函数,对吧,这是不是加请求函数啊。啊,下面针对某个接口来写一个接口请求函数。能听到吗?啊,就是说先要理解我们会有两层封装。这两层封装是不是就对应我API里面的两个模块啊,这一个对应的是第一层封装啊,封装的是一个通用的请求函数,对不对啊,第二层封装是我们的这个接口请求函数吧。每一个接口是不是都有自己对应的请求函数对不对啊,这样能看懂啊,就先要有有这个意思。就是这个东西,你这个意思很重要,可能大家前期的时候觉得啊,学语法特别费劲,各种语法很难记。
08:03
其实你取到之后,你就发现是语法是次要的。啊,你有没有这个思维很重要啊,好。来啊,那在这个啊,先说一下它,嗯,它我们说过,我们这里面用到了XS没问题,用了XS,也就是X本身是不是有promise,但是我们在外层是不是又包了一个promise。对是吧,我们包一个promise的作用有哪些作用。第一个就是我们是出于什么原因来包一个promise,它本身不就好promise。啊,我们是不是想统一集中式处理我们的请求错误,或者叫请求异常啊,那如果外面不包我这里没法统一处理吗?啊,这个需要去知道这样一个事情,同时我还做了第二个优化,第二个优化是个小的优化啊,就是我们本来他一步给我返回来是不是个response,但我想要的是什么response里面的什么date date数据结合数据是吧,那我每一次都response.delete是不是有点反呢?那我希望是一个什么效果?
09:21
义务给我反馈的不是response,而是response date,那这个事情其实也简单,就在于你是不是对的使用。已经搞错了,这就是这其实pro最最基本的一些使用啊。这听到吧,嗯,就这一个,还有一个事啊,千万千万别忘了,你要是这里没写有用吗?没用那你什么,那你这个new promise就了,听懂不?你一定要去这个什么promise对象也就我们呢,呃,这形函数返回的是个什么?
10:00
Promise对象,好,这是我们的第一层封装,那第二层封装是接口请求函数,我们是不是相当于对这个函数又进行了一种封装?是针对某个所有每一个接口是不是定义个对应的函数,把它的那个请求地址和请求方式是不是已经确定下来了。唯一欠缺的是什么?是不是需要把参数数据?能听到吧,嗯,行,这是这一个。好,那有了它之后啊,有了它之后来。后面我们就会发现事情在他环境里面基本上都会存在呃,价值跨域的问题是吧,因为我们做前后台分离的应用嘛,后台一个应用,前台一个应用,他们基本上是跑在两个端口下的,对不对。即使都跑到本地,也是跑到两个端口下来吧,那这个时候就有问题了,那是不是因为端口不同而跨域了,比如说一个是3000,一个是5000,那是不是就跨域了呀。
11:11
那跨域在开发中,我们最最常用的解决方式很简单,使用什么代理服务器?是不是有带点服务器来帮我们去转发请求,那对于浏览器来说,他发的是一个跨域请求吗?不是。能听懂吧,好,配置代理都很简单,主要是因为我们的这个脚手架创建的环境里面实际上已经有代理服务器了,听懂吧。啊,我大家。等会呢,我来说一下代理的一个理解啊,再去说这个事情先要知道怎么做,做很简单,是不是配置一下就可以了,这个配置实际上告诉了代理服务器一个什么事情。是不是一个目标地址,他转发是不是转发到某一个目标地址去,目标地址就是我服务器应用的地址吧,啊好,但同时呢,大家需要对代理有一个基本的理解,首先它是一个什么东西。
12:07
哎,我这里说的是具有特定功能的程序,那个功能我们就要说他。是用来去啊,监视并拦截我们的请求,最后帮我们去转发请求的,这是它的功能,最后实现啊一个解决跨域的一个目标。啊,什么意思啊,来我给大家看一下。这里面我要说一个包啊,叫one pack。杠DSO,这个有没有见过?我们现在我们说一个概念,经常是不是说叫开环境生产环境开环运行,其实本质上用的就是这个包。你翻译过来吗?叫外pad开发服务器是吧,也就我们开法运行m start用的就是这个包,听到包,而这个包它会干嘛?
13:04
他会去在内存中记住啊,分为两步,第一步在内存中对我们的项目进行编译打包,生成内存中的打包文件,这是第一步。第二步,启动服务器,运行打包文件。听懂了吧,那最后啊,甚至它是不是还自动启动浏览器来运行这个项目,那运行的是源源码项目吗?不是源码项目不能运行对不对,运行的是不是打包以后的代码,人家说老师打包以后代码我怎么没看见呢?他没有生成本地的打包文件,只在内存中生成的,对不对,这能听到吧,当然它同时是还包含了一个代理服务器。只是啊,我们不配置它是起不了作用的啊来。打开来,再打开它这里面这个看到的是什么,是物外派的内幕,会依赖用到的一些模块,在这个里边就有一个这个模块。
14:13
这是什么一个模块,看名字很重要,HTTP是HP请求啊,也就说那个这请求啊,而这请求是不是HP请求是。它是一个特别的H请求。啊好,那prox是不是代理的意思,也就是说对我们的请求是不是进行代理的一个什么明什么东西中间线,诶,就是靠它来实现对我们的请求的一个什么代理的操作,当然首先的前提是你的代码请求的是当前应用,因为它监示,比如说我当前应用运行的是3000端口,而服务器运行的是5000端口,我代码请求还是得请求什么3000,听懂不?
15:02
你要请求,事先他会帮你处理吗?不好意思,不会。那你就必然化育了,是不是能听到吧,但是你真正能请求到,真正最后是3000给你返回的资源吗?不是,是这个服务器啊,代理服务器来帮你转发到5000上面去,他去请求5000。其实对浏览器来说,他知道这个事情的存在吗?他不知道听懂了吧,浏览器就是发一个3000的请求。只是由带点服务器来帮我们处理了啊,他去帮我们去请求5000,接着得到数据后又给我们返回,那我的浏览器是不是得到了想要的数据?从五千三得到数据,但是他知道是从五千三得到了吗?他不知道,因为是3000的这个服务器处理你的利息,就现在不这个代理服务器嘛,代理服务器它也是服妻啊。
16:01
他带替谁,是不是带进了乳腺啊,这个能懂吧,大概能懂啊,就他。它运行在哪端这个地方,我们这里面的带进服务器,我们这个配置带进去用服务器,大家要知道啊,无论是前台应用还是后台应用,它要想运行是不是都要有服务器的存在,这个懂不懂,也就是说你一旦通过虚拟地址。去访问某一个资源,必然是不有服务器的存在,是吧?而现在是谁帮我提供服务器运行我的,是不是就是这个我们刚刚说的外派d server。我们刚刚说了嘛,它是先第一步去在类型中打包,是不是第二步是不是启动服务器运行能听到不说白了里面有。能理解吧,里面还有express。而那个一运行的账号就是3000,所以我们看到的这个例子就什么3000或者3001是不是,嗯,这个需要有一个理解啊。
17:09
记住,只在开发所使用啊。好,下面我们的作用刚才说了,目标是不是解决,而这请求发育的问题,它如何解决了,监视被拦截请求,也就处理你这个请求给解称为最后,但是他是真正他处理吗?也不是他去请求谁。是不是4000或者5000能听到不啊。好,而我们现在做的事情很简单,对不对?只需要干嘛?配置一下,告诉代理服务器说我们转发的目标地址是多少啊配的这个。这个是不是基于我们RA的脚架做的配置,那是所有的脚趾架到时候都这么配吗?那也不一定。听懂不只是他现在是这样一个配置啊,封装好的。
18:01
啊,配置呢,就是告诉代理服务器一些信息转换到目标地址啊开环境呢,我们现在就可以配了,但生产环境啊,很多时候需要后台工程设备,那如果需要我们配也其实可以配的,不过呢,现在我们到最后才跟大家,到时候会跟大家讲,因为涉及到后面我们会去对我们项目进行打包运行。到时候再跟大家去啊,再说一说生产环境打包以后如何来做啊,先我们把开发环境的问题给解决掉,OK吧,因为我们现在毕竟在开发的阶段啊,到时候再说。好,那。这这一个,那后面呢,我们给大家去讲一下think wait的问题啊,这个地方首先要知道它的作用是什么,对吧,在接着要知道在哪里去使用这两个关键字是不是,那我们think为了做到什么。啊,首先你you用think,手里得有什么?Promise对象。
19:01
是吧,有了promise象以后,我们是不是采用好,那也就是说我们的是用来简化,谁来使用的promise的使用的,那简化体现在哪呢?怎么个简化法,你告诉我。也就说你想说你变好了,你变强大了,你怎么向证明你变强大了,我就说我有多厉害吧,这个会那个会,这也会,这也不能说明你变强大了,你可能以前就这么强大是不是?你应该怎么才能证明你变强大了?应该说以前怎么着是吧,现在怎么着?两者一对比就发现,哦,确实变强了。有对比是不是才能知道你是变好了吧?那同理也是一样,你现在说简化promise的使用对不对?以前他怎么用。是不是点认指定成功和失败的回调函数,当然也可以通过派去指定是吧?那现在用上位的时候还需要去通过点认来指定回调函数吗?
20:08
是无效的呀,啊,如果用上以后,相当于我在后面是不是就直接得到了他异步给我返回的结果数据。那当然是简化啦。是不是?好,那再一个更加抽象一点说,我渗位是用来干啥的呢?以同步编码的方式来实现什么呢?程序的义务执行流程就程序是义步执行的,但是我们的代码看起来是没有回调函数的吧,没有回调函数其实就是一种同步变的方式。啊,这个需要去知道一下,好,下面哪里有呢?我们wait是写在谁的左边。Promise对象的左边,也就是我应该有一个表达式,有一个表达式,它返回的就是个什么。
21:04
方面对象,那我后面按出来说是不是应该点认了,但我想点任吗?不行,我是不是想直接去得到他义务给我返回的结果。那你说我想用一个产量或者一个变量是不来接收这个值,听懂了吧,那直接这么写行吗?不行,直接这么写得了谁?是吧,我们得在这个左侧加一个什么。Wait。是吧,一旦加上wait,哪里要加所在函数定义的什么左侧是都是左侧呀。嗯。这个咱是专门去说过的,你啊首先要知道它作用,记得要说怎么用啊,语法其实真的不难。二。但是你也要说出来,要会用啊。
22:00
好,那后面呢,我们去实现了登录的功能,当然这个登录最后肯定要包含一个什么自动登录免登录的功能是不是。啊,这里面涉及到几个文件啊,注意首先我们是登录的这一个组件,那肯定要去调用接登录的接口吧。对吧,要发请求嘛,那发请求是不是有可能成功,有可能失败。那如果失败了怎么办?请求如果如果这个失败啊,指的是登录失败,而不是请求出异常,懂不懂登录失败了怎么办?那不很简单提示嘛,对不对,那好了,那如果成功了呢,我应该干嘛呢?那用户看到效果是不是跳到了我们的是吧。是不是后台管理界面,当然背后还要做一个什么事,保存一个信息,哪个信息有着用户信息对不对,那保存哪个问题了,这个地方啊,我们这一次不是用的cookie。
23:05
对吧,我们不是用,我们是用local,就保证里面去吧。能听懂吧,当然也是可以用酷作答,后面酷筛选的使用方式啊,我们在new项目中再去用,先用一种方式,我们多种方式都用一用,这能听懂吧,啊我们这次啊保存有两个地方,一个是logo里面,这是不是19号保存。你就关掉电脑,是不是还在呀?好,而再一个再累你保存内分。内存里面,内存的保存是后面是不是很方便的去从内存的读取。能听到不好。这是这个要保存,那要往这个logo里面保存,我们是不是专门写了一个。工具模块去处理,对不?我们要在类型找,是不是也写了一个专门的工具模块。
24:01
去往内存中存数据,对不对?一个往logo中存数据,一往内存存数据。当然这个地方就有个事情啊,有几个事啊,有几个关于登录的事情,比如说我们要问他一下。我们登录完了以后啊,我一刷新是不是还需要是登录的状态。那这个怎么做呢?这个得说我们其实是在路口JS里面去做了一个很重要的事情,从log中读到者保存了什么内存里面去。是吧,那这样的话,我们我们的me干了个什么事,是不是去判断内存中有没有user者,如果有说明已经登录了吧,那如果没有了,自动跳转到什么登录界面。但是我的登录界面就一定能显示吗?什么情况不应该显示登录界面?
25:03
如果我已经登录啦。即使你去请求登录界面,我能显示吗?不能,你得退出登录以后才显示吧。这能听懂不?你得先退出登录才再显示你的登录界面,听懂不啊,就是这里面我们在登录组件里面也需要去判断。啊,这里面有很多读取和判断相关的操作。主要是把流程搞,把逻辑搞清楚,这靠背吧,不行,你得想想清楚这个里面为什么写,写的目的是什么,有什么用。啊,我们有好几个地方在读啊,在判断在保存。啊,组合在一起才能形成一个完整的功能,你缺一个都有可能功能是有问题的。啊,这是这一个来,那有了这些后面呢,我们是去搭建我们管理界面的整个整个结构,那整个结构我们是用的谁的组建起来。
26:07
是不是D的布局组件,它是不是有一个layout的组件嘛。通过内的是不是形成了一个左右结构,右边是右方为上中下三个部分。能看到吧,其实很轻松对不对,也就用它的几个组件是不是就搞定了,但同时我们是把左侧单独拆分出来定成了一个组件,将右侧右侧的上部分是不是拆分出来定义成组件了,这里面是不是要定义两个组件吧?啊,一个叫这个名字叫什么的?Never是个左侧导航嘛,是吧,而上面这个叫什么。拍打头部是不是没问题?接着我们还要去定义什么呢?子路由,也就是说我们这片区域是不是二级路由显示区域,那我们最终切换这些东西,实际上是不是就切换路由的显示。
27:06
啊,这个应该是没问题的啊,这个也并不难,好,下面我们去写了这个level,这个其实是有点难度的啊,基本的显示其实没什么问题,这个基本的显示用的是不是它的这个menu组件,Menu里面是不是item以及上me。是吧,整个是一个什么menu,哪个是个啊。有子列表的这个。只要你有子列表是不就是个上了,那哪个是卖了,没有那么一项,这都是什么卖哀。这些其实都是根据文档去写的吧,啊好。那下一个啊,还要说这里面涉及到我们这里面肯定会用到路由相关的操作吧。会用了吧,会用到那路由相关操作,这里面存在几个是啊,存在几个是几个,哪几个是了啊,首先我们这里面每一个是不是都是路由链接,那路由链接用到一个组件叫什么是宁可就行,没问题吧,没问题,好这是一个。
28:20
还有一些事情啊,我们在这里面如果想通过GS来控制路由跳转,我该怎么做呢?我们是不是要去得到那个黑水对象?才能进行啊,GS的方式路由跳转吗?或者说我想得到当前请求的路径怎么得呀?那得是不是需要另外一个属性叫什么呢?它是不是一个pass呀,那这些我的这个有吗。本身是没有的,为什么它没有,因为它不是什么路由组件,听懂不,它不是路由组件,所以得不到是不是?那好了,那下面就要说了,我怎么样让一个非路由组件能够得到这三个属性呢?啊,用微给它包装一下是不是并传入这三个属性,我是不是就可以操作了呀?
29:14
听懂吧,好,这个中间其实涉及到我们是不是用到了这样一个方法。下看外,这是不是组建了两个生命周期方法,一个是外一个什么第中间会执行哪个方法对很重要。第一次的认。是不是第一次render,那我们以前用的最多的是不是,我们在这里面干嘛?是不是发请求启动定时器的异步操作,也就说初始的异步操作都在这里做是不是?那好了,这一次我们是不是用了它呀。对不对,我们用它是干嘛很固定,为第一次认做一个什么呢?准备一个东西,准备数据,或者做一个准备工作,但是这个准备工作是异步的行吗。
30:07
那就没有任何意义。因为你要是义务的准备工作,那必然是在render之后执行是不是?那你放到D里面就可以。那我们说里面执行一步的操作能听到不?我们这一次啊,用它做了个什么事了,我们是不是有一个操作,叫根据数据的数据生产了一个menu里面节点的标签的数据,这个事情是同步操作的,听懂不?能理解吧,啊,这是一个同步的准备工作,而且是不是第一次问的时候,这个节点数组是不是这个返回的,这个节点数组是不需要的,必须要有吧,要没有的话我就没办法写,知道吗?所以我这个时候就是最终啊,是在我们的y mount里面去处理的。
31:01
最先我们在哪执行的,还记得吗?最先我们是写在哪个里面,写在里面的。是吧,那写在里面的不好的地方就在于,只要更新它是不是就重新渲染,那是不是重新调用,那我这个调用提示。是不是叫一次?听懂吧,直教一次,这个要注意啊。嗯,这是这个。好,下面啊,我们最终呢,还要刚刚说过了,根据我们的那个数据,我们是不是定义了一个叫menu的模块是吧,里面是不是用来生成我那个列表的那个数组吧。我是不是要根据这个数组数据生成menu item,或者上menu的一个数组,那这个时候我们用到了这么几个技术。两种方式,一种是用麦加什么递归来生成一个什么呢?叫多级菜单列表,现在我们是几级?
32:07
是个两级,那我能不能整成三级的。可以,因为我是什么地轨交用三级,那我的数据应该是怎么样操作的。是这个某一个children里面是不是他应该又有children听懂我意思吧,但是一般不会理,一般没有这么多层,一般情况下是不会保持很深层次的层次的,该不太方便听懂了吧,但是我们有这个能力吧。因为我递归嘛,是不是再一种用的什么加递归来实现多级菜单列表。它们的作用是一样的,对不对,实际效果一样,但是啊,Map和reduce使用的方式还是有不同的。啊,这是这一个,最后我们有两个问题需要解决,第一个问题就是我刷新的时候如何选中啊对应当前的菜单项,也就是说我无论在哪个录音上刷新当前菜单项总是能够选中的吧。
33:10
那这个地方实际上我们要确定一个什么东西,确定一个一个概念叫K。啊,是不是要确定一个需要选中的K啊,那个K实际上是谁,是当前请求的什么pass,能听懂不?这能理解吧?好,那这个也就是涉及到了我怎么样去得到当前请求的pass吧,当前请求它是通过哪个得到?是不是?啊,我把重点的说一下啊,细节我就不再说了,下面一个稍微难的大一些,也就是说什么意思呢?比如说啊,如果我当前请求的是这个,那我一刷新它默认要展开这个列表。
34:06
听到吧,要展开这个列表,展开列表实际上要指定一个什么呢?指定一个叫open k吧,那open k为谁呢?首先我当前我这种情况应该是这个商品的配吧,对不商品配,那也就是说啊,大家看看。是首先是不是要去得到它。得确定他是某一个什么子列表的K吧。是不是也就是说啊,当前啊,就是一级啊,列表下的某个子列表下。指向子菜单下啊。子菜单项是。
35:04
当前对应的菜单项。也就当前菜单项,因为这里面是不是有个K的匹配的问题,那如果有这个条件,那当前这个一级菜单项,它的那个K是不是就是open k。听到了吧,最后指定那OPPOK指到属性里面去就可以。那这个肯定是要有个查找的过程,对吧。啊好,那主要的就是这样一些啊行,那我们这个就。
我来说两句