开发者学堂课程【高校精品课-上海交通大学 -互联网应用开发技术:微信小程序3】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/76/detail/15778
微信小程序3
内容介绍
一、问题讲解
二、小程序的启动
三、页面的启动
四、最常用的 API
五、Book Store Sample
一、问题讲解
第一个问题是数据库设计至少应该有4张表。应该有一张用户的表。至少应该有一个用户的表。订单有一个外界的关联,订单会关联一些订单项。
因为一个订单里面可能会买若干种不同的书,应该一种书一条。 order -item 这边会跟这边的 order 外键进行关联,它会有一个外键指向 order 的主键, order 的一个外键会指向 user 的主键。还有一个有关书的 order-item 它是一种书一个,所以在这边去关联他,它也有一个外键关联这个,它有俩个外键。
有些同学是没有 order-item 。这个问题就会变成一个订单里面就将来只有一种书。无法区分有多少条。这是一种表现,是没有 order-item 。第二种表现是没有 order 。只有 order-item 。
就记录下来这本书是谁买的,他买了多少本,有两本,有一个时间戳说写个 time进去。怎么知道哪几本书是一个订单下了的。这时如果时间戳一样,认为是一个订单。
这个设计有问题。第一个这些东西往里写无法保证一个订单写进去的时间戳是一样的。即使能保证这一点,在找一个订单的时候,需要在这个表里面去扫描所有的机构。因为并不知道哪一些时间戳一样。每找一个订单要把这个全表做一次扫描,就看到时间戳一样的东西再去做,一张表里面去找时间戳一样,规模很大,扫描一遍不能扫描完,是 n 平方的操作。
因为不知道个时间戳在哪里会碰上这一系列问题,没有这个order所有东西全在 order-item 里面。有 order-item ,没有了 order 表可以这样做。在这边加一个属性,比如说是 order 的 id 一个订单。第一个订单他买了哈利波特买了两本。一个订单买了指环王买了一本。现在主键应该怎么去设计显然这个订单的 id 是不能当主键的,因为不能唯一区分。如何区分,你是在有一个订单的这张表整个有一个主键1,2这样去区分。还是把他俩当成一个联合主键。如何去区分。同样的道理。如果能区分开,碰上另外一个问题。
这数据算冗余的数据。做这个数据库设计中,应该充分去利用关系型数据库他能给你提供的便利。即基于关系做的一些数据。无论是查找还是更新,还是删除这一列,这一系列东西。需要设计出一个合理结构才可以,至少分成4个表。可以看到很多他的这种参考资料或者是其他的一些网站都是这样做的,无论怎么设计,脱离这个是有问题的。你至少应该是有4个表了。然后在这基础上再去做 OR 映射。 OR 映射的时候是没有 order-item 。应该是一个order里面有有它的一个组件。
OR 映射是面向的应用。在应用的角度应该是只有用户订单和书三类东西。第二个问题是如果从底下开始算最底下有 entity 。通过 OR 映射在做数据库的映射,上面这一层Repository.他在考虑数据的这个是怎么去访问数据库的可以算是 DAO 的一部分 。在上面有个 DAO 这一层。原因是 mongodb 告诉你的数据可能来自于不同的地方。 Repository 只能对一种数据库操作。
DAO 需要把完整的比如说 person 要给他组装出来对上上面层,比如说 service 或者是 controller 。他们在处理这个 person 是不应该在看到 person 数据来自于什么具体的位置,来自于两个地方。需要靠 DAO 去屏蔽它, DAO 里面给的 mongodb 例子实际上是在对两个 Repository 处理,一个是 MySQL 一个是 mongodb 。这是基本的一个结构。问题出有的同学在 DAO 里面去写一些 service 做的工作就是一些业务逻辑在里头。但是 DAO 从字面含义看它叫数据访问对象,是不包含业务的。
所谓的业务上举个例子。假设说要下订单,下订单这个动作应该包含至少两个东西。第一个往订单表里写一个东西,操作订单个对象,订单和订单的 item 是在做一对多的关联,是在做关联操作,所以实际上 order-item 也就一起写进去。这是你做的第一个动作,第二个动作需要把书的库存给它减一。如果说买了一本,数量减一。下订单包含对两个逻辑的操作。
如果写在 DAO 层这个动作应该是在 order 的这个 DAO 里头,还是在 book 的 DAO 里。问题出现在选一个就把他放在 order 的 DAO 。这个 DAO 这里除了要写 order 还要写 book。就会发现是在两个不同的 DAO 对象里面在都可以写 book 。都可以对 book 操作。这个分类有漏洞。更重要的一点是现在下订单说有管理员他在管理这个库存。他要写 book 这个这个数据库,把库存做比如加一或者加 n 的操作。
假设我们整理库存还要做一个动作就是把 order 也做一个相关的处理,比如老的订单删掉。现在写修改库存的这个代码里出现了两个地方。一个是刚才你把下订单这个动作这个逻辑放到这个订单的 DAO 里。你就在订单的 DAO 里面就出现了修改库存的逻辑。你在管理库存的这个地方又出现了修改这个书的库存的这个逻辑,就修改 book 的逻辑。
这逻辑一定会重复。从代码的角度来说只要你写重复的代码,这个框架这个开发工具,它自动就会提示你有重复,是否把它独立成一个函数。反过来下订单放书的库存里一样的, order 的操作其实也是有两个地方的操作。
所以 DAO 是对这个数据做增删改查的动作。把这种需要对多个表来完成操作的多种实体完成操作的这种逻辑给它封装的 service 。这样就看到如果是修改库存是调 book 的修改库存代码去实现。无论是上面有多少个服务再调这个代码,这个代码本身只有一处。实现这种封装就是把业务逻辑放在 DAO 。
带来的问题就是 DAO 不纯。可能很多的逻辑不是在操作一张表,而是在操作n张表,代码一定会重复。一旦重复代码维护就比较差,也就是再修改任何一个地方,需要改 n 个地方。所以这个逻辑不应该放在第一位,现在来看接受一个请求之后就在这里面处理回去。比如说下面这个动作就在 controller 里做。在 controller 里面做的问题是下订单要做这样的一个操作。
去写数据库,这个 order对象,写 book 对象就是改变他的状态。完成一个下单的动作。这个逻辑如果放到 controller 里,下订单的逻辑要变一下。先去查一下这个用户他存不存在,是否有余额。假设说里面有他储卡的余额。
也就是这个逻辑业务逻辑可能会发生变化。或者说要求先改书的库存,再下订单,这个顺序变一下,必须改这个 controller 。如果放了 service 层,但是 service 层是暴露了一个接口给 controller 的。只要这个接口不动 Service 不用去改,直接换一个实线就可以。有两种不同的实线去实现它去换一个。把业务代码耦合到 controller 里面。
第一个就是去做这种替换的时候,这种改动就必须要改这种源码。第二个是跟 DAO 道理一样,比如服务的一些操作。如果是多个 controller ,都有可能去用。最典型的例子,如果你在 service 里面有一个查询。给定时间段范围内的所有订单,这样一个服务。比如说管理员面对的发了一些请求的就是 controller 。以及用户发的请求过来的这个 controller ,他们都会调这个。
他们都想去看一下自己的订单。你把这个逻辑封装到 controller 他俩之间就重复代码。你把它放到一个 service ,只能让其分别去调就没有重复代码。可以看到所有的分层的目的就是要逐层抽象。然后在每一层里面专门做一件事情或者叫做一类事情。目的就是要剔除掉代码当中所有的用重复的代码,提高代码的复用度。提高代码的复用度,把所有需要修改的地方集中到一点就是所有重复的代码几乎都没有。
这样才能保证未来系统在做演化的时候,要去修改这个系统中。你可以把修改集中在一点上。就像刚才查找订单,如果把它放在 controller 也能拿到。这个逻辑一旦发生变化,就跟着 controller 全都要变,全部代码都要改。所以编程的时候,复用在整个软件工程这个这个这个领域,或者说计算机软件的领域里面。要遵守一个基本原则你只要写重复的东西是错的。
所以这里应该是一个最小的分层结构。 MySQL , mongodb 这两个东西因为是要依靠 Spring 它的 Repository 帮我们来实现对这两种数据库的操作。所以在上面又加了个 DAO 。是为了向上层去屏蔽掉这个数据的来源。所以你可能看其他的一些参考资料,它就告诉你这个 Repository 就是 DAO 。因为它里面可能只有1种数据源,就是 MySQL 。它不存在另外一部分存在 mongodb ,或者让我们都在 mongodb 。所以他不需要这个 DAO 。再做一层 Repository 就是他就把这 Repository 当 DAO 了。
所以分层架构一定还是要满足的。因为我们这个是你大脑逻辑要对,然后在功能的话应该是符合一般的电商购物网站的一个操作员一个惯例。这是这个这个分层架构里面。现在通过这个解释,希望大家能理解为什么需要这样一个分层的结构。主要的问题就是一个数据库的设计。前后台交互的时候你前后台交互不知道用阿贾克斯然后传过来后你在后台处理。在处理后台的这个逻辑需要去通过写数据库等等。构件有一个 scope 。
能看到有些人写的这些东西 scope 就是在处理在决定。比如 Controller . service , DAO 的对象.大家在运行的时候,整个系统的运行过程当中, Controller 有几个对象你写的代码都是在写类。你写了一个类。类本身他需要实例化成对象,然后被调。因为考虑过这些你写的类都被实例化了多少个地方,比如有一个专门去接受下订单的这个 Controller 了。
Controller 到底在他们开的没有几个对象。是康凯的创建这个对象,他是整个应用在运行生命周期里面就一个。还是说有多少客户端他就创建了多少个。如果拿三个浏览器不同浏览器去访问,他里面会有三个 Controller 。这个问题跟 scope 设置有关。
二、小程序的启动
上节课我们讲了一个小程序。我们讲这个例子就是该跑起来看到个例子。
重要东西回顾一下就是小程序里面这个配置文件里头。看到配置里面会把所有的配置都罗列一下。其中第一个就是默认首页。然后这个 app json 就在这个目录上。
它对应的还有一点 js 。它里面呢就会有一个小程序出发以后。 On launch 是小程序出发以后会去执行的代码。通常我们看到了才会去要求认证你的这个用户名密码去获取你小程序的信息,所以我们跑起小程序的时候,你看到上面有你的头像或者用户名从哪来,就在 On launch 里获取。
三、页面的启动
然后在小程序里面,每个页面分了4个文件。 json 是这个配置。这个 WXML 就是你页面里面的内容。你在画这个页面的结构。 wx ss 就是微信的样式表。
这边是微信的标记语言描述的结构。 wx ss 就类似于 Css ,对应它还有1个 js 文件,现有1个页面,分成这4个。把它们合起来就是你看到的。之前在浏览器里看到的框架的 react 或者是 vue 做这个设计一样,但是在 react 或者是 vue 里面我们也鼓励你把 Css 和 gs 独立出来分别存储。
其实原来做这个前端设计中就这么做,会觉得他没什么大的差异,只不过微信小程序强制要求。就说1个页面,它一定在4个文件。4个文件的名字是一样,后面不一样。
就是我们看到的这个 js 文里面。它会有一个刚才说的 on launch 这些所有的方法以及数据。这个数据就类似在 react 的看到一些 practice 和这个 state 这样的东西。
四、最常用的 API
重要的东西是你前端要给后端交互要发请求出去。就是用的这个微信 request 的方法,它类似于 fetch 或者是请求。或者用 query 这样的东西再发请求。
首先是这个 url 。这样对应到你后台的 url ,所以你的后台始终是一个。你的浏览器和微信小程序和移动 app 的访问的时候发出来的都是相同的 url 。
post 过去要改参数,参数就用户名和密码。然后用户头输入,我发出去的内容是 json 。这个是微信小程序默认就设成他。然后继续输入。如果成功,拿到这个 response 看里面的状态。如果是正常的会怎么做,如果是异常的或怎么做。
它里面用的是 set data ,这样的东西都类似于 react 里面的种.这里面是如果成功,就要把这个 Cookie 服务器端给你建了一个 session 对象,算是对象的里面这个对象的 id 会通过 response 写回来。
在这个 response 里面去拿到这个 ID 把它存到本地。未来 cookie 在访问的时候, cookie 就可以把这个 session 再拿走发给客户端。发给服务器端服务器端就可以拿到跟你相关的 session id 。然后再往下一个是想在这个请求来了之后,要去做界面的一个跳转。就用的是个 navigate to 。
后面跟着的就是相对于你当前这个页面。这个页面是在 Index js 相对于这个页面的个路径。点就是上一层,就在 Index 的上一层找到 books 。然后进去以后是 books 这个页面所以就跳到这。因为 books 的只能就是 books 这个页面。它包含了这4个文件而已,所以这样去指定这个 books 的里头的个 books 里面就跳转过去了。
五、Book Store Sample
经常会用到的两个一个是在跟后台交互,一个是在实现前端的页面的这个导航。然后这个小程序跑起来就是用户名密码输入之后。它可以进到这里。
这个摄像头是一个广告业一样。这个地方是一个跑马灯。底下是书的列表。
书的列表里面每一个事都放了一本书和它的题目。在底下还有一个工具条。这个工具条里面包含4个选项。
当你点某一个书的时候,不是导航到一个新的页面,而是出了一个遮盖照,它就像服装一样浮出来的显示这本书的这个详细信息。
然后在底下这个条就会覆盖掉变成了一个加入购物车的一个购买。你点些都能点动,只是我们给的例子没有继续去做,下订单其实就是全部留给大家自己去做。
在这里面你点这两个按钮是一种情况,这边的这两个图标是另外一种情况。这样就是这个例子就跑到这里为止。
微信的小程序开发工具上节课我已经讲了一部分,我们回顾一下。来进来这个 app , json 是整个的这个配置。可以看到这个页面就是 index , Books 然后是 addCartPage 。这个叫 book 的东西。就是这4个文件都要不加,这个叫 books 点什么,所以这3个页面第一个是 index ,它是首页。
剩下是一些全局性的配置,从这里看到的最温柔的一些样式的设置。用到了哪一些需要用到的空间。这里面这个我们底下的这一层呢这个工具栏。
然后这一层里面4工具栏的是这个叫做 paper item 的东西就是遮蔽罩。就是让你去点这个书的时候,它出来的这个东西。就是包括这个购物车什么的这些东西。底下就写他主要是在做全局配置,先导入这些东西。
然后因为这个地方是首页是 index 。所以跳转到 Index 。Index 这个 json 再导入她需要用到的东西。它的配置用到的是这个 field 是输入框和按钮。这是输入框,就是按钮。
所以导入这样的然后这个页面会被加载页面里面的内容。他在这个 json 文件里面。就是它对应的这个 json 文件里面,导入这个 field 就用到这里。 Field 就是让输入用户名和密码。然后他俩都有站位服务,就是当你什么都不输入它要显示灰颜色字体。就是看到什么都不输,它显示性输入密码。
这样的话登录进去刚才这个输入用户名和密码的东西,在这里输入往其他地方一点,他离开这个刚才的这个空间。他要去调用这两个分别用这两个方法。
然后这两个方法自然就会在刚才看到的这个 js 文件里面。这个 js 文件一致性。所以就是给我展示用户名和密码有两个框。
底下有个按钮。按你的名字登录。这是我们导入的这个就是在它的前面 Infield 。
没有太多的东西。看第三个方法。
这三个方法一个是当你用户名输入,你的这个光标或者焦点离开的时候做的事情。他就把这个用户名设成了当前。你在用户名这个按钮,离开这个事件就是光标离开他的这个事件是从这个用户名的这个输入里发出了,所以把这个event调他的 detail 或者是 value 就得到了这一个空间里面输入的值。
底下的这个密码也是类似的。是把产生这个事件的个对象的值取出来赋值给了密码,之后用的是 setData 。这个 setData 和 setSate 一样,修改他的状态。只要这个光标离开这个这个输入框。它的值就会被赋值一次。
所以当你去点登陆的时候。其实他俩就可以保证一定是赋值了用户名和密码。而用户密码是当前就是这个 index 页面里头它的 data 。在初始的时候用户名密码。还有一个 error message 都是空。所以用户名密码里面是没有内容的,它是会出现站位服务。然后 error message 现在是没有。
在没有它会显示空,所以看不到任何 error message 。在这个 js 文件里面刚才的按这个按钮是 bindViewTap 。你拿手去触碰这个 tap 就是跟这个计算机上 click 的区别就是手机,所以我们一般是拿手机触碰到 tap 下面。指定的函数他到后台就发一个验证请求出去。然后用的是post。参数就给了 user name 和 password 。 password ,把这个当前这个页面 Data user name , password 带进去。
因为刚才已经通过这里的设置了,所以现在把用户名密码给发走。发送以后有了请求回来之后如果成功了就显示是把这个 session 给它存到本地。就找到了这个 books 里面,如果不成功,用户名把这个密码删掉。
不对点一下就走到了底下。 error message 设了一下。即用户名密码错。因为 setData 会触发这个页面重绘。所以他重复了一下。重复的话只有 error message 发生了变化。在这里这底下就是 field 。
他在底下会出现一个 error message 。它的发生变化重复的出现了,这里我们看到红颜色的部分把它输入正确的都可以跳转到这个页面。看到第一个页面。看看这个第二个页面 Books 。 Books 刚刚说了,分了几个东西。
第一个上面有个输入的一个搜索框。第二就是底下有一个来回滚动的像走马灯一样,然后底下有一行字,这个走马灯,可在这不断的走。往下是列表,每一本书首页和他的名字,再往下是工具栏。
看它的组成。整个大的有一个 view 。上面有个搜索框,搜索框用的是 van-search ,所以在他的这次的 json 文件里面,它引入了 swiper ,然后在一开始的我们看到这里引入了 van-search ,所以你可以在一个工程里面去用它。页面最上面是一个 search 的值。将来是你输入的,会用这个值。
所以 search value 一定是他的 data 之一。然后我们再看这个搜索框下来是一个跑马灯。跑马灯这个东西是我们自己定制的。定的就是在这里一个控件,因为它只是控件所以放到 components 的这样他不是个完整的页面,用 swiper 就是可以不断地滑动的东西。里面他会去写的给我一组这个 url ,用微信的 for 循环去呈现它。
对于每一张图片做这个动作,他会 swiper 的 item 就是哪一张图片里面。你在滚动中每一张图片他这个内容就是一个具体 img 。这个 img 都来自于你这个给的这一组链接里面的东西。
这组链接来了里面需要索引的,所有每次拿出来指定索引的这张图片给它呈现一下。所以在 books 这边走马灯就是做的事情就,把你这个 imgurl 给你。
这 img ,url 变量都在 json 定义。你现在看到4张图片指定了叫做 assets 的这个里面,这个是要给 Custom swiper 给这个这个页面上一层目录在这里,在上一个工作在这里。跟他平级了才能找到 assets ,所以说有两重。