VUE 学习中的疑问
今天重看了昨天的任务,发现了代码中的bug,目前思路是要读懂接口,将接口读出来的id和text显示。没接触过大项目,发现思路不清晰很多知识都不了解。逐步解决自己看代码的疑问
tip1:async和await
这个确实比promise简洁容易理解一点。async await要放在一起用,async用来表示函数异步,定义的函数会返回一个promise对象,可以用then方法添加回调函数,单独的await是用不了的。
如果await后面是promise对象会造成异步函数停止执行并且等待promise的解决,如果等的是正常的表达式则立即执行
//setTimeout 模拟异步请求
function sleep(second, param) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(param);
}, second);
})
}
async function test() {
let result1 = await sleep(2000, 'req01');
let result2 = await sleep(1000, 'req02' + result1);
let result3 = await sleep(500, 'req03' + result2);
console.log(`
${result3}
${result2}
${result1}
`);
test();
//req03req02req01
//req02req01
//req01
这个结果中result2
依赖result1
,result3
依赖result2
的结果,为了结果能输出req03req02req01
和req02req01
,这里test()
里面一定要顺序执行。结果也看到确实是如此。
但是这个代码还不能完全取代promise()
,如果遇到多个异步请求互不关联,但在所有请求结束以后要输出一行,那么这里如果套用多个await就不合适了,就会让三个异步请求阻塞浪费时间。
function sleep(second) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('request done! ' + Math.random());
}, second);
})
}
async function bugDemo() {
await sleep(1000);
await sleep(1000);
await sleep(1000);
console.log('clear the loading~');
}
bugDemo();
这个方式就不太合理,所以可以用promise.all()
async function correctDemo() {
let p1 = sleep(1000);
let p2 = sleep(1000);
let p3 = sleep(1000);
await Promise.all([p1, p2, p3]);
console.log('clear the loading~');
}
correctDemo();// clear the loading
tip2: promise
function multiply(input) {
return new Promise(function (resolve, reject) {
log('calculating ' + input + ' x ' + input + '...');
setTimeout(resolve, 500, input * input);
});
}
// 0.5秒后返回input+input的计算结果:
function add(input) {
return new Promise(function (resolve, reject) {
log('calculating ' + input + ' + ' + input + '...');
setTimeout(resolve, 500, input + input);
});
}
var p = new Promise(function (resolve, reject) {
log('start new Promise...');
resolve(123);
});
p.then(multiply)
.then(add)
.then(multiply)
.then(add)
.then(function (result) {
log('Got value: ' + result);
});
上面的代码很简单。setTimeout就是为了模拟网络时延,这个结果就是实现了顺序执行
function getNumber(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
var num = Math.ceil(Math.random()*10); //生成1-10的随机数
if(num<=5){
resolve(num);
}
else{
reject('数字太大了');
}
}, 2000);
});
return p;
}
getNumber()
.then(function(data){
console.log('resolved');
console.log(data);
})
.catch(function(reason){
console.log('rejected');
console.log(reason);
});
这里catch
除了用来指定reject的回调,还会在执行resolve的回调时,若抛出异常,就进入catch方法。
关于promise.all()
和Promise.race()
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P2');
});
// 同时执行p1和p2,并在它们都完成后执行then:
Promise.all([p1, p2]).then(function (results) {
console.log(results); // 获得一个Array: ['P1', 'P2']
});
Promise.all([p1, p2])
内部是在异步执行的,但是会等内部任务执行完才继续。
如果想要里面比较快的就用Promise.race()
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P2');
});
Promise.race([p1, p2]).then(function (result) {
console.log(result); // 'P1'
});
p1
执行快一点,所以p2
就被丢弃了
tip3:fetch
fetch返回的是一个promise
对象,这个promise
会在请求响应后被 resolve
,并传回 Response
对象。
tip4:slot与slot-scope
slot:插槽,是组件的一块HTML模板,其显示与否或者怎样显示取决于父组件
非插槽模板指的是html模板,指的是‘div、span、ul、table’这些,
插槽模板是slot,它是一个空壳子,因为它显示与隐藏以及最后用什么样的html模板显示由父组件控制。但是插槽显示的位置确由子组件自身决定,slot写在组件template的哪块,父组件传过来的模板将来就显示在哪块。
默认插槽
<template>
<div class="father">
<h3>这里是父组件</h3>
<child>
<div class="tmpl">
<span>菜单1</span>
<span>菜单2</span>
<span>菜单3</span>
<span>菜单4</span>
<span>菜单5</span>
<span>菜单6</span>
</div>
</child>
</div>
</template>
<template>
<div class="child">
<h3>这里是子组件</h3>
<slot></slot>
</div>
</template>
<child></child>
里面写了html模板,子组件的匿名插槽就是这里面的内容
具名插槽
插槽加了name属性
<template>
<div class="father">
<h3>这里是父组件</h3>
<child>
<div class="tmpl" slot="up">
<span>菜单1</span>
<span>菜单2</span>
<span>菜单3</span>
<span>菜单4</span>
<span>菜单5</span>
<span>菜单6</span>
</div>
<div class="tmpl" slot="down">
<span>菜单-1</span>
<span>菜单-2</span>
<span>菜单-3</span>
<span>菜单-4</span>
<span>菜单-5</span>
<span>菜单-6</span>
</div>
<div class="tmpl">
<span>菜单->1</span>
<span>菜单->2</span>
<span>菜单->3</span>
<span>菜单->4</span>
<span>菜单->5</span>
<span>菜单->6</span>
</div>
</child>
</div>
</template>
<template>
<div class="child">
// 具名插槽
<slot name="up"></slot>
<h3>这里是子组件</h3>
// 具名插槽
<slot name="down"></slot>
// 匿名插槽
<slot></slot>
</div>
</template>
带数据的插槽
匿名插槽
<slot></slot>
具名插槽
<slot name="up"></slot>
要在插槽上面绑上数据,得这么写
<slot name="up" :data="data"></slot>
export default {
data: function(){
return {
data: ['zhangsan','lisi','wanwu','zhaoliu','tianqi','xiaoba']
}
},
}
<child>
html模板,这个是父组件决定子组件的样式
</child>
插槽绑定了一套数据,父组件可以拿来用。那么样式父组件说了算,但内容可以显示子组件插槽绑定的。
<template>
<div class="father">
<h3>这里是父组件</h3>
<!--第一次使用:用flex展示数据-->
<child>
<template slot-scope="user">
<div class="tmpl">
<span v-for="item in user.data">{{item}}</span>
</div>
</template>
</child>
<!--第二次使用:用列表展示数据-->
<child>
<template slot-scope="user">
<ul>
<li v-for="item in user.data">{{item}}</li>
</ul>
</template>
</child>
<!--第三次使用:直接显示数据-->
<child>
<template slot-scope="user">
{{user.data}}
</template>
</child>
<!--第四次使用:不使用其提供的数据, 作用域插槽退变成匿名插槽-->
<child>
我就是模板
</child>
</div>
</template>
上面父组件没提供数据,提供了三个样式,数据是由子组件提供的
<template>
<div class="child">
<h3>这里是子组件</h3>
// 作用域插槽
<slot :data="data"></slot>
</div>
</template>
export default {
data: function(){
return {
data: ['zhangsan','lisi','wanwu','zhaoliu','tianqi','xiaoba']
}
}
}
tip5:使用debugger来调试代码,这个自己之前竟然不知道。
今日任务:
今天找到了bug的位置,可还是没有把bug解决,基本上读几行代码就发现是自己没见过的VUE的内容,需要赶快把代码读通