为了账号安全,请及时绑定邮箱和手机立即绑定
3.1 微信小程序 API

uni-app 的 API 与微信小程序 API 基本一致。掌握微信小程序 API 对后面的开发很有帮助。微信小程序 API 文档:https://developers.weixin.qq.com/miniprogram/dev/api/

3.1 打包为微信小程序

注册微信小程序账号,获取到 AppID,我们后面配置的时候会用到。在 HBuilderX 工具栏,点击发行,选择小程序-微信。输入小程序名称和 AppID,单击发行就可以了。这样我们就会获得一个微信小程序的打包文件,接下来我们来发布微信小程序项目,打开微信小程序开发者工具,导入刚刚生成的微信小程序项目的打包文件,在微信小程序开发者工具中先测试一下,项目运行是否正常,项目测试没有问题后,点击右上角>>按钮,上传代码就可以发布微信小程序了,最后等待微信团队审核通过,别人就可以在线上访问到你的项目了。

6.2 新增联系人

function addUser(button){ var children = $(button).parent().children(); var name = children.eq(0).val(); var phone = children.eq(1).val(); var data = JSON.stringify({'name': name, 'phone': phone}); $.ajax({ 'url': '/users', 'type': 'POST', 'contentType': 'application/json', 'data': data, 'dataType': 'json', 'error': ajaxError, 'success': ajaxSuccess });}点击 “新增” 按钮后,执行函数 addUser(button),button 指向的是 “新增” 按钮。在 templates/index.html 中,按钮、联系人姓名、联系人电话于相同的 DIV 中,如下所示:<div class="row"> <input type="text" placeholder='姓名'> <input type="text" placeholder='电话'> <span class="button" onclick="addUser(this);">增加</span></div>在第 3 行到第 5 行,表达式的含义如下所示:表达式含义$(button).parent()指向按钮的父节点$(button).parent().children()表示 div 的 3 个子节点children.eq(0)指向联系人姓名children.eq(1)指向联系人电话children.eq(2)指向新增按钮在第 4 行,根据联系人的姓名和电话创建一个新联系人,将它作为参数、调用后端新增联系人的服务。在第 8 行,通过 jquery 的 ajax 函数调用后端服务,设置 url 为 ‘/users/’、type 为 ‘POST’ ,表示 RESTful 架构下的新增联系人。

新浪微博

咱们打开新浪微博,然后随便找个带皇冠的,按下F12键(Mac用户按command+option+i)然后选中控制台的箭头,再点击皇冠:再点开这个图片可以发现:可以看到那些大 V 图标皇冠图标以及各种微博认证等图标,都是放在了一张雪碧图里(即使再牛的大 V,身份标志也是放在雪碧图中的)。

3.5 更新联系人

@app.route('/users/<int:userId>', methods=['PUT'])def updateUser(userId): name = request.json['name'] phone = request.json['phone'] for user in users: if user.id == userId: user.name = name user.phone = phone break return jsonify({'error': None});在第 1 行,通过 PUT 方法访问页面路径 /users/userId 的处理函数是 updateUser,在 RESTful 架构中,PUT /users/userId 表示新增一个联系人。/users/<int:userId> 表示了一个动态路由,它可以匹配如下的路径:/users/1,id 为 1 的联系人对应的 URI/users/2,id 为 2 的联系人对应的 URI/users/3,id 为 3 的联系人对应的 URI对符号 <int:userId> 的解释如下:int 表示匹配整数,/users/<int:userId> 可以匹配 /users/1 (1 是一个整数),不能匹配 /users/tom (tom 不是整数);userId 表示匹配的值,/users/<int:userId> 和 /users/1 匹配后,userId 为 1,它作为参数被传递给页面处理函数 updateUser。在第 3 行和第 4 行,request.json 是一个字典,记录了客户端发送的 JSON 格式的参数:联系人的姓名和电话;在第 6 行,在全局变量 users 根据 userId 查找指定的 user 并更新;最后,使用 jsonify 将 JSON 格式的数据转换为字符串,{‘error’: None} 表示操作成功。

6.3 更新联系人

function updateUser(button, userId){ var children = $(button).parent().children(); var name = children.eq(0).val(); var phone = children.eq(1).val(); var data = JSON.stringify({'name': name, 'phone': phone}); $.ajax({ 'url': '/users/' + userId, 'type': 'PUT', 'contentType': 'application/json', 'data': data, 'dataType': 'json', 'error': ajaxError, 'success': ajaxSuccess });}点击 “更新” 按钮后,执行函数 updateUser(button, userId),button 指向的是 “新增” 按钮,userId 是需要更新的联系人 id。在第 3 行到第 5 行,获取需要联系人的姓名和电话,使用了和 6.2 小节相同的方法,请参考 6.2 小节。在第 8 行,通过 jquery 的 ajax 函数调用后端服务,设置 url 为 ‘/users/userId’、type 为 ‘PUT’ ,表示 RESTful 架构下的更新联系人。

3.4 新增联系人

@app.route('/users', methods=['POST'])def addUser(): name = request.json['name'] phone = request.json['phone'] user = User(name, phone) users.append(user) return jsonify({'error': None});通过 POST 方法访问页面路径 /users 的处理函数是 addUser,在 RESTful 架构中,POST /users 表示新增一个联系人。在第 3 行和第 4 行,request.json 是一个字典,记录了客户端发送的 JSON 格式的参数:联系人的姓名和电话;在第 6 行和第 7 行,将新建的联系人加入到全局变量 users;最后,使用 jsonify 将 JSON 格式的数据转换为字符串,{‘error’: None} 表示操作成功。

4.2 新增联系人

<body><h1>通讯录</h1><div class="row"> <input type="text" placeholder='姓名'> <input type="text" placeholder='电话'> <span class="button" onclick="addUser(this);">增加</span></div>新增联系人的界面包含 3 个部分:一个文本字段用于填写姓名;一个文本字段用于填写电话;一个按钮,用于增加联系人,设置按钮的 onclick 函数,点击按钮时执行函数 addUser(this),其中 this 指向按钮对应的 DOM 元素。

4. 列出联系人

本小节实现列出所有联系人的功能,如下所示: def list_person(self): for person in self.persons: print('%s,%s,%s' % (person['name'], person['address'], person['phone']))在第 1 行,定义函数 list_person,实现列出所有联系人的功能在第 2 行,遍历列表 self.persons,循环变量 self.persons 是一个字典在第 3 行,打印变量 person 的内容对每个联系人打印输出一行,假设通讯录中已经存储了张三和李四两个联系人,输出如下:C:\> python addressBook.py1. create person2. list all persons3. query person4. delete person5. quitEnter a number(1-5): 2张三,南京,12306李四,北京,10086在第 7 行,用户选择执行功能 2在第 8 行,打印联系人张三的信息在第 9 行,打印联系人李四的信息

5.2 读取联系人

其他的代码和读取短信一样,修改的部分就是onClick()中的部分,主要是权限申请和数据读取,修改 onClick() 中的代码如下:if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { int hasReadSmsPermission = checkSelfPermission(Manifest.permission.READ_CONTACTS); if (hasReadSmsPermission != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, 100); return; }}ContentResolver resolver = getContentResolver();Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;Cursor cursor = resolver.query(uri, null, null, null, null);while (cursor.moveToNext()) { String cName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); String cNum = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); Log.d(TAG, "姓名:" + cName); Log.d(TAG, "号码:" + cNum); }cursor.close();然后在 AndroidManifest.xml 中加入读取联系人的权限:<uses-permission android:name="android.permission.READ_CONTACTS"/>第一次点击的时候同样会弹出以下权限申请弹出,授予之后即可拿到具体的联系人信息。掌握了这两种 Content Provider 的使用,其余的像新增联系人、查询具体联系人等等其实都是换汤不换药,核心思路就是两步:1、申请权限(Android 6.0 以上需要动态申请);2、通过 URI 读取数据。

3. 列出联系人

本小节实现列出所有联系人的功能,如下所示:elif choice == '2': for person in persons: print('%s,%s,%s' % (person['name'], person['address'], person['phone']))在第 1 行,如果 choice == ‘2’,则执行列出所有联系人的功能在第 2 行,遍历列表 persons,循环变量 person 是一个字典在第 3 行,打印变量 person 的内容对每个联系人打印输出一行,假设通讯录中已经存储了张三和李四两个联系人,输出如下:C:\> python addr-manage.py1. create person2. list all persons3. query person4. delete person5. quitEnter a number(1-5): 2张三,南京,12306李四,北京,10086在第 7 行,用户选择执行功能 2在第 8 行,打印联系人张三的信息在第 9 行,打印联系人李四的信息查询联系人本小节实现查询联系人的功能,如下所示:elif choice == '3': name = input('name: ') for person in persons: if person['name'] == name: print('%s,%s,%s' % (person['name'], person['address'], person['phone']))在第 1 行,如果 choice == ‘3’,则执行查询联系人的功能在第 2 行,获取用户输入的 name在第 3 行,遍历列表 persons,循环变量 person 是一个字典在第 4 行,如果用户输入的 name 和循环访问 person 的 name 相同,则表示找到指定的 person在第 5 行,打印变量 person 的内容

3.2 联系人数据库

class User: nextId = 0 def __init__(self, name, phone): self.id = User.nextId User.nextId += 1 self.name = name self.phone = phonetom = User('tom', '10086')jerry = User('jerry', '12306')users = [tom, jerry]使用类 User 描述一个联系人,每个联系人包含有 3 个属性:id、name、phone。User.nextId 记录了下一个可用的用户 id,在 User.__init__ 中,使用 User.nextId 作为当前新建用户的 id,然后使用 User.nextId += 1 更新下一个可用的用户 id。在第 10 行和第 11 行,创建了两个联系人: tom 和 jerry。使用全局变量 users 记录全部的联系人,将 tom 和 jerry 加入到列表 users 中。

4. 列出联系人

本小节实现列出所有联系人的功能,如下所示:def list_person(): for person in persons: print('%s,%s,%s' % (person['name'], person['address'], person['phone']))在第 1 行,定义函数 list_person,实现列出所有联系人的功能在第 2 行,遍历列表 persons,循环变量 person 是一个字典在第 3 行,打印变量 person 的内容对每个联系人打印输出一行,假设通讯录中已经存储了张三和李四两个联系人,输出如下:C:\> python addr-manage.py1. create person2. list all persons3. query person4. delete person5. quitEnter a number(1-5): 2张三,南京,12306李四,北京,10086在第 7 行,用户选择执行功能 2在第 8 行,打印联系人张三的信息在第 9 行,打印联系人李四的信息查询联系人本小节实现查询联系人的功能,如下所示:def query_person(): name = input('name: ') for person in persons: if person['name'] == name: print('%s,%s,%s' % (person['name'], person['address'], person['phone']))在第 1 行,定义函数 query_person,实现查询联系人的功能在第 2 行,获取用户输入的 name在第 3 行,遍历列表 persons,循环变量 person 是一个字典在第 4 行,如果用户输入的 name 和循环访问 person 的 name 相同,则表示找到指定的 person在第 5 行,打印变量 person 的内容

6.4 删除联系人

function deleteUser(button, userId){ var children = $(button).parent().children(); var data = JSON.stringify({}); $.ajax({ 'url': '/users/' + userId, 'type': 'DELETE', 'contentType': 'application/json', 'data': data, 'dataType': 'json', 'error': ajaxError, 'success': ajaxSuccess });}点击 “删除” 按钮后,执行函数 deleteUser(button, userId),button 指向的是 “新增” 按钮,userId 是需要更新的联系人 id。在第 3 行到第 5 行,获取需要联系人的姓名和电话,使用了和 6.2 小节相同的方法,请参考 6.2 小节。在第 8 行,通过 jquery 的 ajax 函数调用后端服务,设置 url 为 ‘/users/userId’、type 为 ‘DELETE’ ,表示 RESTful 架构下的删除联系人。

2.1 微框架

Flask 是一个 Python 实现的 Web 开发微框架,但是这个“微”并不代表着 Flask 功能比较简陋、有所欠缺。微框架中的 “微” 意味着:Flask 旨在保持核心简单而易于扩展;Flask 不会替用户做出太多决策,比如使用何种数据库;Flask 的选项(比如使用何种模板引擎) 通常有多个,用户很容易替换。默认情况下,Flask 不包含数据库抽象层、模板引擎、身份认证或其它任何已有多种库可以胜任的功能,如下图所示。然而,Flask 支持用扩展来给应用添加这些功能,应用程序可以很方便的集成这些扩展。众多的扩展提供了数据库集成、表单验证、上传处理、各种各样的开放认证技术等功能。

3. 增加联系人

本小节实现增加联系人的功能,如下所示: def create_person(self): name = input('name: ') address = input('address: ') phone = input('phone: ') person = {'name': name, 'address': address, 'phone': phone} self.persons.append(person)在第 1 行,定义函数 create_person,该函数实现增加联系人的功能在第 2 行,获取用户输入的 name在第 3 行,获取用户输入的 address在第 4 行,获取用户输入的 phone在第 5 行,根据用户输入的 name、address、phone 创建一个字典,用于描述该联系人在第 6 行,将联系人加入到 self.persons 中

3. 增加联系人

本小节实现增加联系人的功能,如下所示:def create_person(): name = input('name: ') address = input('address: ') phone = input('phone: ') person = {'name': name, 'address': address, 'phone': phone} persons.append(person)在第 1 行,定义函数 create_person,该函数实现增加联系人的功能在第 2 行,获取用户输入的 name在第 3 行,获取用户输入的 address在第 4 行,获取用户输入的 phone在第 5 行,根据用户输入的 name、address、phone 创建一个字典,用于描述该联系人在第 6 行,将联系人加入到 persons 中

2.1 微前端

微前端 尚处在发展时期,其核心概念和 微服务 相似。现阶段较为常用的微前端框架为 single-spa 和 qiankun,后者是基于前者实现的。该技术能做到 技术栈无关,即一个应用,能由多个不同技术的子应用构成,同时做到子应用的相互隔离,这里的隔离就可以选择采用 Web Components 实现。

2. 增加联系人

本小节实现增加联系人的功能,如下所示:if choice == '1': name = input('name: ') address = input('address: ') phone = input('phone: ') person = {'name': name, 'address': address, 'phone': phone} persons.append(person)在第 1 行,如果 choice == ‘1’,则执行增加联系人的功能在第 2 行,获取用户输入的 name在第 3 行,获取用户输入的 address在第 4 行,获取用户输入的 phone在第 5 行,根据用户输入的 name、address、phone 创建一个字典,用于描述该联系人在第 6 行,将联系人加入到 persons 中

2.2 描述所有联系人的数据结构

程序将所有联系人信息存储在列表中,即通讯录是一个列表、列表的元素是字典。假设通讯录中有两个人,它们的信息如下所示:姓名地址电话张三南京12306李四王五10086本节使用面向对象的上设计方法实现通讯录,使用一个类 AddressBook 描述通讯录,类 AddressBook 的核心成员是一个列表,该列表保存了所有联系人, 代码如下:class AddressBook: def __init__(self): self.persons = [] def addPerson(person): self.person.append(person)addressBook = AddressBook()zhangSan = {'name': '张三', 'address': '南京', 'phone': '12306'}liSi = {'name': '李四', 'address': '北京', 'phone': '10086'}addressBook.addPerson(zhangSan)addressBook.addPerson(lisi)在第 1 行,定义了类 AddressBook 描述通讯录在第 3 行,定义了成员变量 persons,它是一个列表,记录了所有的联系人在第 5 行,定义了成员方法 addPerson,它将单个联系人加入到联系人列表中在第 8 行,使用类 AdressBook 创建一个对象创建两个联系人在第 9 行,变量 zhangSan 的类型是一个字典,描述了张三的信息在第 10 行,变量 liSi 的类型是一个字典,描述了李四的信息将联系人添加到通讯录中在第 11 行,将联系人 zhangSan 添加到通讯录中在第 12 行,将联系人 liSi 添加到通讯录中

6. 删除联系人

本小节实现删除联系人的功能,如下所示:def delete_person(): name = input('name: ') for person in persons: if person['name'] == name: persons.remove(person) break在第 1 行,定义函数 delete_person,实现删除联系人的功能在第 2 行,获取用户输入的 name在第 3 行,遍历列表 persons,循环变量 person 是一个字典在第 4 行,如果用户输入的 name 和循环访问 person 的 name 相同,则表示找到指定的 person在第 5 行,使用方法 persons.remove(person), 从 persons 中删除元素 person在第 6 行,退出 for 循环

2.1 描述单个联系人的数据结构

程序使用字典描述一个联系人,假设某个联系人的信息如下:姓名地址电话张三南京12306使用字典描述该联系人如下:>>> person = {'name': '张三', 'address': '南京', 'phone': '12306'}字典有三个键:name、address、phone对应的值分别为:张三、南京、12306

5. 查询联系人

本小节实现查询联系人的功能,如下所示: def query_person(self): name = input('name: ') for person in self.persons: if person['name'] == name: print('%s,%s,%s' % (person['name'], person['address'], person['phone']))在第 1 行,定义函数 query_person,实现查询联系人的功能在第 2 行,获取用户输入的 name在第 3 行,遍历列表 self.persons,循环变量 self.persons 是一个字典在第 4 行,如果用户输入的 name 和循环访问 person 的 name 相同,则表示找到指定的 person在第 5 行,打印变量 person 的内容

4. 删除联系人

本小节实现删除联系人的功能,如下所示:elif choice == '4': name = input('name: ') for person in persons: if person['name'] == name: persons.remove(person) break在第 1 行,如果 choice == ‘4’,则执行删除联系人的功能在第 2 行,获取用户输入的 name在第 3 行,遍历列表 persons,循环变量 person 是一个字典在第 4 行,如果用户输入的 name 和循环访问 person 的 name 相同,则表示找到指定的 person在第 5 行,使用方法 persons.remove(person), 从 persons 中删除元素 person在第 6 行,退出 for 循环

3.3 展示所有的联系人

@app.route('/')def index(): return render_template('index.html', users = users)设置页面路径 / 的处理函数 index,函数 index 渲染模板文件 index.html。将全局变量 users 传递给页面模板,users 中记录了所有的联系人,因此页面中会展示所有的联系人。

6. 删除联系人

本小节实现删除联系人的功能,如下所示: def delete_person(self): name = input('name: ') for person in self.persons: if person['name'] == name: self.persons.remove(person) break 在第 1 行,定义函数 delete_person,实现删除联系人的功能在第 2 行,获取用户输入的 name在第 3 行,遍历列表 self.persons,循环变量 self.persons 是一个字典在第 4 行,如果用户输入的 name 和循环访问 person 的 name 相同,则表示找到指定的 person在第 5 行,使用方法 self.persons.remove(person),从 self.persons 中删除元素 person在第 6 行,退出 for 循环

3.6 删除联系人

@app.route('/users/<int:userId>', methods=['DELETE'])def deleteUser(userId): index = 0 for user in users: if user.id == userId: del users[index] break index += 1 return jsonify({'error': None});if __name__ == '__main__': app.run(debug = True)在第 1 行,通过 DELETE 方法访问页面路径 /users 的处理函数是 deleteUser,在 RESTful 架构中,DELETE /users/userId 表示新增一个联系人。/users/<int:userId> 表示了一个动态路由,在 3.5 小节进行了详细的解释。在第 4 行,根据 userId 在全局变量 users 中查找相应的 user 并删除;最后,使用 jsonify 将 JSON 格式的数据转换为字符串,{‘error’: None} 表示操作成功。

4.3 展示所有的联系人

<div> {% for user in users %} <div class="row"> <input type="text" value="{{user.name}}" placeholder='姓名'> <input type="text" value="{{user.phone}}" placeholder='电话'> <span class="button" onclick="updateUser(this, {{user.id}});">修改</span> <span class="button" onclick="deleteUser(this, {{user.id}});">删除</span> </div> {% endfor %}</div></body></html>Flask 程序将全局变量 users 传递给渲染模板文件 templates/index.html,全局变量 users 包含有所有的联系人。在第 2 行,逐行展示所有的联系人,每个联系人包括 4 个部分:一个文本字段展示姓名,值为 user.name;一个文本字段展示电话,值为 user.phone;一个按钮,用于修改联系人,点击按钮时执行函数 updateUser(this),其中 this 指向按钮对应的 DOM 元素;一个按钮,用于删除联系人,点击按钮时执行函数 updateUser(this),其中 this 指向按钮对应的 DOM 元素。设置按钮的 onclick 函数,点击按钮时执行函数 addUser(this),其中 this 指向按钮对应的 DOM 元素。

3.1 关于微服务监控平台

技巧 1如果我们的微服务监控平台没有任何数据,或者说,在打开微服务平台之后,各参数一直处于 loading 状态,这个时候,我们只需要在服务端调用任意一个服务接口即可,这样在微服务监控平台,我们就能看到被监控实例的参数了。技巧 2如果我们在访问 /actuator/hystrix.stream 路径时,系统找不到对应的路径,即报 404 异常,那么我们需要在对应项目的启动类中添加一个 Bean :@Beanpublic ServletRegistrationBean hystrixMetricsStreamServlet() { ServletRegistrationBean registration = new ServletRegistrationBean(new HystrixMetricsStreamServlet()); registration.addUrlMappings("/hystrix.stream"); return registration;}这样我们就能正常访问 /actuator/hystrix.stream 下的路径了。

3.3 近于实时的补偿性

我们都知道,什么事情都不可能是十全十美的。抛开 RabbitMQ 不说,在互联网行业中的其他工具,也不能百分百保证每时每刻都在正常工作,更何况是涉及到消息通信的工具。RabbitMQ 在传递消息时,由于一些客观原因或者是其本身的原因,可能会出现,在有大批量消息传递时,所有的消息不能百分百传递到目的地的问题。RabbitMQ 在设计之初就考虑到了这个问题的出现,所以,RabbitMQ 提供了内置的消息补偿机制,这里我们简单做一下介绍。当存在大批量的消息都需要经过 RabbitMQ 来投递时,RabbitMQ 会将这些消息划分成若干组,然后通过为组设置顺序的方式,来依次投递这些消息。如果在任意一组中,出现了消息未能投递到目的地的现象,那么, RabbitMQ 会将该条消息进行短暂的存储,待其他消息都到达目的地后,RabbitMQ 会重新将该条消息进行投递,然而,这个过程执行的时间是微乎其微的,几乎近于实时。

首页上一页1234567下一页尾页
直播
查看课程详情
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号