1、请求200
但是请求回来的是html
网络里会写 200OK from disk cache
这个时候需要清除浏览器缓存
2、base64 引入失败 找一个js文件直接引入
require is not defined
import Base64 from ‘***’
https://blog.csdn.net/u011383596/article/details/116712729
3、promise
promise:异步编程解决方案
promise相当于一个状态机,拥有三种状态pending、fulfilled、rejected
(1)一个promise对象那个初始化的状态是pending,调用了resolve后会将promise的状态扭转为fulfilled,调用reject后会将promise的状态扭转为reject,这两种扭转一旦发生便不能扭转该promise到其它状态
(2)promise对象原型上有一个then方法,then方法会返回一个新的promise对象,并将回调函数return的结果作为该promise resolve的结果,then方法会在一个promise状态被扭转为fulfilled或rejected时被调用。then方法的参数为两个函数,分别为promise对象的状态被扭转为fulfilled和rejected对应的回调函数。
new Promise((res,rej)=>{})
Promise.all().then((res)=>{})
this.getFormData().then((res)=>{})
getFormData () {
return new Promise((resolve, reject) => {
this.$http.get('', {
params: { taskId: this.taskId }
}).then(res => {
resolve(res.data.result)
})
})
},
构造一个promise对象,并将要执行的异步函数传入到promise的参数中执行,并且在异步执行结束后调用resolve()函数,就可以在promise的then方法中获取到异步函数的执行结果
new Promise((res,rej)=>{
setTimeout(()=>{
resolve()
},1000)
}).then()
Promise.all接收一个promise对象数组作为参数,只有全部的promise都已经变成fulfilled状态后才会继续后面的处理。Promise.all本身返回的也是一个promise
const promise1 = new Promise((res,rej) => {
setTimeout(()=>{
resolve('promise1')
},1000)
})
const promise2 = new Promise((res,rej) => {
setTimeout(()=>{
resolve('promise2')
})
})
Promise.all([promise1,promise2]).then()
Promise.race和Promise.all类似,只不过这个函数会在promise中第一个promise的状态扭转后就开始后面的处理(fulfilled、rejected均可)
配合async await使用:现在的开发中我们大多会用async await语法糖来等待一个promise的执行结果。async本身是一个语法糖,将函数的返回值包在一个promise中返回。
const p=async function f(){
return '1'
}
p.then((res)=>{
console.log(res) //1
})
开发技巧:在前端开发上promise大多被用来请求接口,axios库也是开发中使用最频繁的库,但是频繁的try catch捕捉错误会让代码嵌套很严重。考虑如下代码的优化方式
const getUserInfo=async function(){
return new Promise((res,rej)=>{
//resolve()||reject()
})
}
//为了处理可能的抛错 将try catch套在代码外面
try{
const user= await getUserInfo()
}catch(err){}
//好的处理方法是在异步函数中将错误catch
async awite的写法在uniapp的文件上传中使用
// 获取上传状态
async select (res) {
console.log('选择文件:', res)
await this.uploadFile(res.tempFilePaths[0]);
},
uploadFile (tempFilePaths) {}
使用async关键字可以让函数具有异步特征,但总体上其代码仍然是同步求值的。而再参数或闭包方面,异步函数仍具有普通js函数的正常行为。下面的foo()函数仍然会再后面的指令之前被求值。
async function foo(){
console.log(1)
}
foo()//1
异步函数如果使用return关键字返回了值(如果没有return则会返回undefined),这个值会被Promise.resolve()包装成一个期约对象。异步函数始终返回期约对象。在函数外部调用这个函数可以得到它返回的期约。
async function foo(){
console.log(1)
return 2
}
//给返回的期约添加一个解决处理程序
foo().then(console.log)
console.log(3)
//1
//3
//2
当然直接返回一个期约对象也是一样的
async function foo(){
console.log(1)
return Promise.resolve(3)
}
拒绝期约的错误不会被异步函数捕获
async function foo(){
Promise.reject(3)//Uncaught (in promise):3
}
因为异步函数主要针对不会马上完成的任务,所以自然需要一种暂停和恢复执行的能力。使用await关键字可以暂停异步函数代码的执行,等待期解决。
let p=new Promise((resolve,reject) => setTimeout(resolve,1000,3))
p.then((X) => console.log(x)); //3
使用async/await可以写成这样
async function foo(){
let p=new Promise((resolve,reject) => setTimeout(resolve,1000,3))
console.log(await p)
}
foo()//3
async function bar(){
return await Promise.resolve('bar')
}
bar().then(console.log)//bar
等待会抛出错误的同步操作,会返回拒绝的期约
async function foo(){
console.log(1)
await (() => {throw 3;})
}
//给返回的期约添加一个拒绝处理程序
foo().catch(console.log)//3
单独的Promise.reject()不会被异步函数捕获,而会抛出未捕获错误。不过,对拒绝的期约使用await则会释放(unwrap)错误值(将拒绝期约返回)。
async function foo(){
console.log(1)
await Promise.reject(3)
console.log(4)//这行代码不会执行
}
//给返回的期约添加一个拒绝处理程序
foo().catch(console.log)
console.log(2)
//1
//2
//3
async/await中真正起作用的是await。async关键字,无论从哪方面来看,都不过是一个标识符。异步函数如果不包含await关键字,其执行跟普通函数基本上没有什么区别。
js运行时在碰到await关键字时,会记录在哪里暂停执行。等到await右边的值可用了,js运行时会向消息队列中推送一个任务,这个任务会恢复异步函数的执行。即使await后面跟着一个立即可用的值,函数的其余部分也会被异步求值。
如果await后面是一个期约,则问题会稍微复杂一些。此时,为了执行异步函数,实际上会有两个任务被添加到消息队列并被异步求值。
async function foo(){
console.log(await Promise.resolve('foo'))
}
async function bar(){
console.log(await 'bar')
}
async function baz(){
console.log('baz')
}
foo()
bar()
baz()
//baz
//bar
//foo
串行执行期约
function addTwo(x){ return x+2 }//或者 async function addTwo
function addThree(x){ return x+3 }
function addFive(x){ return x+5 }
async function addTen(x){
for(const fn of [addTwo,addThree,addFive]){
x=await fn(x)
}
return x;
}
addTen(9).then(console.log)//19
这里await直接传递了每个函数的返回值,结果通过迭代产生。当然,这个例子并没有使用期约,如果要使用期约,则可以把所有函数都改成异步函数。这样它们就都返回期约了。async function addTwo(x) {return x+2;}
- 举例
//for循环不影响执行顺序 异步请求需要等待请求结果时影响 但使用方法类似
var sum = 0
function testAsync() {
return new Promise((resolve, reject) => {
for (var i = 0; i < 10; i++) {
sum += i
}
resolve(sum)
});
}
function callerFun() {
console.log("Caller");
await testAsync().then((res) => {
console.log(sum)
});
console.log("After waiting");
}
callerFun();
//等待请求结果
async loadData (arg) {
let data= await this.searchData(arg)
//findnode需要searchData的请求结果
await this.findnode(data).then((resolve)=>{
//获取数据
this.dataSource=resolve
})
},
searchData (arg) {
return new Promise ((resolve,reject)=>{
getAction(this.url.list, params).then((res) => {
if (res.success) {
resolve(res.result.records)
} else {
reject()
this.$message.warning(res.message)
}
})
})
},
findnode (data) {
return new Promise((resolve, rej) => {
data.map((i,index) => {
let param = {}
param.id = i.id
getAction('/jeecg-system/sys/ext/queryByDataId', param).then((res) => {
console.log(res)
if (res.code == "200") {
i.assignee_dictText = res.result.assignee_dictText
i.nodeName = res.result.nodeName
}
//在循环结束后返回结果
if(index==data.length-1){
resolve(data)
}
})
})
})
},
4、缺少npm环境
5、
网页弹窗 会在当前浏览器窗口弹出一个新的浏览器窗口(iframe跨域问题不能直接访问某些链接比如百度)
showModal(location) {
var wid = 800;
var hgt = 600;
var href = api.InforSystem;
var x = (screen.width - wid) / 2;
var y = (screen.height - 20 - hgt) / 2;
var winstyle = 'width=' + wid + ',height=' + hgt + ',left=' + x + ',top=' + y + ',status=no,menubar=no,scrollbars=yes,toolbar=no,resizable=yes';
lastopenwin = window.open(href + location, '_blank', winstyle, true);
lastopenwin.focus();
},
6、import {***} from和 import ** from (带不带大括号的问题)
//1
import { commonMixin } from
export const commonMixin = {}
//2
import ReimburseBpmMixin from
const ReimburseBpmMixin = {
data() {
return {
}
},
methods: {
}
}
export default ReimburseBpmMixin;
7、uniapp获取不到路由参数时(当然有可能是这个项目有问题)
window.location.href
路由参数乱码时
//如果data是一个对象就JSON.stringify
url: '/pages/12323243?item='+encodeURIComponent(JSON.stringify(data))
let url=window.location.href
let index=url.indexOf("=")
let urldata= url.substring(index+1,url.leng)
8、遍历Object属性
https://segmentfault.com/a/1190000041977281
遍历两个数组寻找一个对象中的key与另一个对象中value匹配的值
data.map((obj) => {
Object.keys(obj).forEach(akey => {
this.columns.map((i) => {
Object.keys(i).forEach(item => {
//如果column的align的值==obj里的key 就把 column里的title汉字 在obj里存为汉字
if (item == 'dataIndex') {
if (i[item] == akey) {
debugger
console.log(i[item] + "------" + akey + "---------" + i.title)
//wkflwID------wkflwID---------流程定义号
let key = akey
let value = i.title
this.translate[key] = value
}
}
})
})
})
})
//v-for遍历数据要使用translate对象中的key遍历时要写item[xxx] 而不是 item.xxx
<view class="cu-item"
v-for="(item,index) in tableData"
:key="index">
<view class="content"
style="left: 24px;">
<view class="text-grey">
<span v-for="(a,b) in translate"
:key="b"
style="font-size: 13px;">{{a}}:{{item[b]}}</span>
</view>
</view>
</view>
9、动态设置style的值
:style="{'height':`${cardeleH}px`,}"
10、uniapp跳转页面传参
https://www.jianshu.com/p/0f4959df7abb
11、子组件input通过v-model传值
https://www.jianshu.com/p/854fc40cf0b4
当父组件调用子组件包含的input输入框时 需要将子组件input输入框的值绑定给父组件的v-model 不再需要用$emit向父组件传值
//父组件
<view class="cu-form-group ">
<view class="title"><text class="text-red">*</text><text space="ensp">报销科目:</text></view>
<OnlineSelectTree
v-model="model.subject"
name="input" />
</view>
//子组件
<input v-model="selected"
placeholder="请选择"
readonly
disabled="true" />
<Zpopup :value="openPop"
@change="onChange"
:type="'bottom'">
<view class="pop-box">
<view class="pop-title">
</view>
<view style="overflow: scroll;"
class="popup_content">
<LyTree ref="xyTree"
:treeData="treeData"
@cnecked="treeChecked"></LyTree>
</view>
</view>
</Zpopup>
methods:{//给子组件的input赋值时给父组件传值
treeChecked (data) {
this.selected=data.name
// this.$emit('treeChecked',data)
this.$emit('input', this.selected);
// #ifndef MP-WEIXIN
this.$emit('change', this.selected);
// #endif
},
},
model: {//与methods同级
prop: 'value',
event: 'input'
}
12、cascader级联的问题 tree应该也会有同样的问题:children.filter not a function 和 options not array数据不是数组形式就装不进去
13、uniapp的form表单可以验证表单规则
https://uniapp.dcloud.net.cn/component/uniui/uni-forms.html
<uni-forms ref="form"
:model="model"
:rules="rules"
validate-trigger="bind"
err-show-type="undertext">
<uni-forms-item name="proposer"
label="申请人"
:required="">
//不写require就没有必填的星号 rules里写true也不行
<input v-model="model.proposer"
placeholder="请输入"
name="proposer" />
</uni-forms-item>
</uni-forms>
rules: {
age: {
rules: [{
required: true,
errorMessage: '请输入年龄'
},
{
format: 'number',
errorMessage: '年龄只能输入数字'
},
{
minimum: 1,
maximum: 200,
errorMessage: '年龄范围{minimum}~{maximum}'
},
]
},
},
14、uniapp给上级页面传递信息 除了$emit之外
//子页面
survyData(data){
let pages = getCurrentPages()
let prevPage = pages[pages.length - 2]
prevPage.$vm.getValue(data, 'survy')
this.close();
},
//父页面
getValue (data, type) {}
15、在循环结束后根据循环的结果进行处理 async await promise
async submit () {
let status = await this.checkTable()
this.$refs['form'].validate()
.then(result => {
console.log("验证通过", result);
if (status == true) {
this.submitForm()
}
})
.catch(errors => {
this.$tip.toast('信息未填写完整,请检查!');
console.log("验证不通过=>", errors);
return
})
},
checkTable () {
return new Promise((resolve, reject) => {
this.$store.state.operateList.map((i) => {
if (i.subject == undefined || i.subject == null) {
this.$tip.toast('报销明细(票夹信息)信息未填写完整,请编辑!');
resolve(false)
return
}
})
resolve(true)
})
},
另一种 文件上传时
// 获取上传状态
async select (res) {
console.log(this.attachment)
console.log('选择文件:', res)
await this.uploadFile(res.tempFilePaths[0]);
},
uploadFile (tempFilePaths) {}
16、uniapp返回上一级是重载上一级的表单
如果不是foot页 可以使用
let pages = getCurrentPages();
let prevPage = pages[ pages.length - 2 ];//上一页
console.log("prevPage===>",prevPage)
prevPage.$vm.downCallback()//调用上一页的方法