选项卡数据填充
1.创建云函数,
将上面返回的数据格式化一下,
那么,客户端应该怎么使用上面获取到的数据呢?
如下,新建getLabel方法,通过get_label这个云函数名字来调用它,
下面是返回的结果,如果结果不对,需要再将云函数重新部署一下即可,就是右键点击,选择部署。
遇到的问题1:
遇到的问题2:uniCloud提示"应用未关联服务空间"
这个错误是在获取数据库中数据的时候,在网页调试界面里面报错的。重启hbuilder就好了。
如何将返回的数据传给页面。
新增数据
将上面的代码改成如下也是可以的
下面这个是没有把数据给页面,而是直接给了组件属性。从而显示出来。
这里有个很奇怪的问题,
如下图获取数据,如果我按照注释的代码写法,log中可以获取到数据,但是界面是空白的,不显示。
如果我按照第二种then的方式,log也有数据,界面是正常显示的。
搜索gittee上的代码,发现其他人都是第二种写法。不知道第一中哪里出错了。
要是有谁知道,麻烦评论指点一下,谢谢了。
封装数据请求
将上面的数据请求的代码进行优化,封装成api.期望的是如下这样的简洁的调用效果。
首先common下面创建api文件夹,在里面创建index.js。在这里面获取数据,这个函数通过export导出
如下导入,
Vue.prototype.$api = api 给所有组件注册了一个属性 $appName,赋予初始值 'api' ,所有组件都可以用 this.api 访问此变量;
页面使用的地方
至此,完成阶段性的胜利。
下面继续优化,先看看改成下面这样是否可以正常运行,创建如下文件
list.js中
export const get_label = (data) =>{
// wq:这里没有看懂
return new Promise((reslove,reject)=>{
uniCloud.callFunction({
name:'get_label',
data
}).then((res)=>{
// .then
if(res.result.code == 200){
reslove(res.result)
}else{
// .catch
reject(res.result)
}
}).catch(()=>{
reject(err)
})
})
}
index.js中
import {get_label} from './list.js'
export default{
get_label
}
大致意思就是把原先index.js中的实现放到list.js中,并export直接导出。然后index.js中导入并导出。
经实践,是可以正常获取数据的。
现在我们再加一个云函数,来看看是怎样的添加流程。
首先 list.js中追加
export const get_list = (data) =>{
// wq:这里没有看懂
return new Promise((reslove,reject)=>{
reslove({data:'请求成功 get_list'})
})
}
index.js中追加
vue页面调用:
这样添加教程说还是比较麻烦。但是我感觉挺清晰的。继续学,看看更高级的方法是什么。当然,或许不好理解。
因为get_list和get_label,它发送数据请求的时候是类似的,所以可以用统一的封装。
在common文件夹下增加http.js文件。
里面内容如下,将调用云函数的部分进行封装。
export default function $http(options){
console.log(options)
const {url,data}=options
return new Promise((reslove,reject)=>{
uniCloud.callFunction({
name:url,
data
}).then((res)=>{
// .then
if(res.result.code == 200){
reslove(res.result)
}else{
// .catch
reject(res.result)
}
}).catch(()=>{
reject(err)
})
})
}
list.js导入上面文件中的函数,并对外暴露。
import $http from '../http.js'
export const get_label=(data)=>{
return $http({
url:'get_label',
data
})
}
index.js (下面的get_list应该删掉的)
import {get_label,get_list} from './list.js'
export default{
get_label,
get_list
}
main.js保持不变。index.vue页面删除get_list函数的调用。这样运行,还是可以加载数据。
整体思路概括为:index.vue页面调用this.$api.get_label,
而这个来自于main.js,是从api文件夹的index.js来的,然后绑定到Vue上的。
import api from './common/api'
Vue.prototype.$api = api
index.js来自于list.js的通用数据请求函数。
其实这样感觉index.js只是中转了一下而已,没有什么用。
如果在上面代码基础上,把index.js文件删掉。在list.js中添加
export default{
get_label
}
在main.js中改这句 import api from './common/api/list.js' 。一样是可以的。
这里如果写做 import api from './common/api 意思是从api/index.js里面导入。如果是/api/list.js就是制定从这个文件中导入。
开始试验时候没有加export default语句,会出错。因为这句是在main.js导入的时候不指定接口名字的,可以在导入的时候随便起名字。
如果写成export test。则在导入这个js的时候,必须制定test这个名字,不能改成其他的,所以出错了。
这里还是恢复,以便和视频教程一样去写。
再继续升级。。。
上面基础上,如果增加函数的话,比如get_lsit,需要修改list.js和index.js两个文件。所以希望进一步优化。
index.js 自动获取api文件夹中的js文件并导出
const requireApi = require.context(
//api 目录的相对路径
'.',
//是否查询子目录
false,
//查询文件的一个后缀
/.js$/
)
let module = {}
requireApi.keys().forEach((key,index)=>{
if(key === './index.js') return
console.log(key)
// 对象合并
Object.assign(module,requireApi(key))
})
console.log(module)
export default module
其他的没有什么保持一样就行了。以后如果再增加新的云函数。只需要增加list.js中调用云函数即可。
下面是关于新知识的附录。
1.require.context是什么
require.context函数接受三个参数
- directory {String} -读取文件的路径
- useSubdirectories {Boolean} -是否遍历文件的子目录
- regExp {RegExp} -匹配文件的正则。
理解就是读取某路径的文件,返回文件列表。
keys -返回匹配成功模块的名字组成的数组
2.Object.assign是什么作用
概括:将后面对象中的可枚举的值拷贝到前面对象中,不重复的拷贝。有重复则覆盖。
Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。Object.assign(target, ...sources) 【target:目标对象】,【souce:源对象(可多个)】举个栗子: const object1 = { a: 1, b: 2, c: 3 }; const object2 = Object.assign({c: 4, d: 5}, object1); console.log(object2.c, object2.d); console.log(object1) // { a: 1, b: 2, c: 3 } console.log(object2) // { c: 3, d: 5, a: 1, b: 2 } 注意: 1.如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。后面的源对象的属性将类似地覆盖前面的源对象的属性 2.Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象。该方法使用源对象的[[Get]]和目标 对象的[[Set]],所以它会调用相关 getter 和 setter。因此,它分配属性,而不仅仅是复制或定义新的属性。如 果合并源包含getter,这可能使其不适合将新属性合并到原型中。为了将属性定义(包括其可枚举性)复制到 原型,应使用Object.getOwnPropertyDescriptor()和Object.defineProperty() 。