VUE 学习中的疑问

在Vue学习过程中,遇到了异步操作的困惑,如async/await和Promise的使用。理解到async函数返回Promise,await用于等待Promise结果。在多个异步请求不相关时,用Promise.all()更合理。此外,深入学习了fetch API的响应处理。在组件交互方面,探索了slot和slot-scope的概念,包括默认插槽、具名插槽和带数据的插槽的用法。同时,开始使用debugger进行代码调试以提升问题解决效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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依赖result1result3依赖result2的结果,为了结果能输出req03req02req01req02req01,这里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的内容,需要赶快把代码读通

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值