vue使用v-for渲染数据,并把的数据作为参数,调用methods方法进行新的异步操作,获取新数据

本文讨论了在Vue中如何处理v-for渲染数据时结合异步操作的问题。作者遇到的问题是,通过v-for循环渲染MV列表,需要在每次渲染时根据MV的ID异步获取额外信息,但遇到了因异步操作导致的数据获取不准确的难题。解决方案是利用Vue的响应式系统,先通过Ajax获取MV数据,然后遍历数组,针对每个MV对象使用Ajax获取详细信息,并使用Vue.set方法将新信息添加到MV对象中,确保视图的更新。最后,可以直接在模板中使用mv.likedCount等属性来展示新获取的数据。

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

问题

通过ajax获取mv列表到数组中,然后通过v-for渲染到页面上。此时,想要通过每次渲染时得到mv的id作为参数,传入一个函数中进行新的异步操作,但是遇到了问题。

<div class="card" v-for="(mv,index) in recommendMVs" :key="index">
        <div id="mv">
            <img :src="mv.picUrl" >
            <div id="infoOfMv">
                <span >{{mv.name}}</span>
                <span>by.{{mv.artistName}}</span>
            </div>
        </div>
        <div id="about">
            <img src="../assets/imgs/thumb.png" alt="" class="thumb cardIcon" >
            <span>{{mv.likedCount}}</span>
            <img src="../assets/imgs/commend.png" alt="" class="commends cardIcon">
            <span>{{mv.commentCount}}</span> 
        </div>
    </div>

代码中 recommendMVs 是获取到的mv数组,数组元素是对象。mv对象有id属性,可以通过这个id请求到mv的相关信息,如点赞数,评论数等。

原本想法是把mv.id作为参数,传入一个函数,像这样:

 <img src="../assets/imgs/thumb.png" alt="" class="thumb cardIcon" >
 <span>{{getInfoOfMv(mv.id)}}</span>
 ...
getInfoOfMv(id){
    return new Promise(function(resolve,reject){
        axios.get("https://autumnfish.cn/mv/detail/info?mvid=" + id).then(response =>{
            return response
        }).then(error => {

        })
    })
}

然后再这个函数中获取数据,但是因为ajax是异步的,并不能返回想要的数据,还没获取到就返回了

然后想要用Promise,这样可以保证再ajax异步操作结束后才会返回数据,保证能够得到数据。

  getInfoOfMv(id){
    this.getInfo(id).then(response => {
 			//这里不能使用return返回结果,只能传给其他量
       }).then(function(error){
        
       })
   },
   getInfo(id){
       return new Promise(function(resolve,reject){
           axios.get("https://autumnfish.cn/mv/detail/info?mvid=" + id).then(response =>{
               resolve(response)
           }).then(error => {

           })
       })
   }

但是Promise不能 return 结果,只能把结果传给在data中的其他数据。传给其他值的话,查值表达式中就要写那个数据,这里就不能写成这个函数的形式了,因为使用 {{getInfoOfMv(mv.id)}} 查值表达式的话,只能通过**getInfoOfMv(mv.id)**这个函数返回值来获取数据(计算属性类似)。

可如果把这里绑定给Promise中传给的那个data中的数据,就没法去调用这个函数了,异步就没办法执行。

总结下来,问题有这两个个:
1.只使用函数,会由于异步而取不到值
2.使用Promise的话,就不能使用函数返回值的形式获取数据,只能传给其他的变量,但这样就不能调用这个函数了,也就不能执行异步操作

解决

后来想起来之前写的一个demo中,给使用ajax获取的对象数据,响应式的添加了属性,所以这里也可以使用这种方法。

具体步骤就是:
1.首先使用ajax获取recommendMVs
recommendMVs是 v- for 渲染的基础数据,数组中的每个元素都是一个对象,对象包含了mv.id,可以通过 mv.id 获取想要获取的mv的相关信息,如点赞数,评论数等。

2.获取到之后,对每个数组元素进行遍历,遍历操作就是获取每个对象的mv.id,使用ajax,获取到对应的mv的相关信息

3。将获取到的信息,作为属性,添加到数组 recommendMVs 里对应 mv对象 中
这里注意:因为 recommendMVs 是第一个ajax操作得到的数据,所以这里算是对已有的对象添加响应式的属性。如果使用普通的方法直接添加属性,是不会更新视图的,因此要用Vue.set的方法给对象添加属性,具体可见Vue.js文档
([Vue响应的添加属性(https://cn.vuejs.org/v2/guide/reactivity.html#%E5%AF%B9%E4%BA%8E%E5%AF%B9%E8%B1%A1))

4.在view中,直接使用mv.likedCount (对象.属性名),就和其他原本就在recommendMVs数组里的对象的原有属性一样使用了。

代码:

//组件中
 methods: {
    async getMVs(){
         //获取推荐mv
         await this.$store.dispatch('getRecommendMVs')
         this.$store.dispatch('getInfoOfMVs')
     }
 }


 //actions中
 //第一个ajax,获取recommendMVs 
async getRecommendMVs({commit}){
       return new Promise((resolve,reject) => {
            axios.get(getRecommendMVs).then(function(response){
               let recommendMVs = response.data.result
               commit(GETRECOMMENDMVS,{recommendMVs})
               resolve()
           }).then(function(error){

           })
       })
   },
   //第二个ajax,对recommendMVs 中每个mv对象,通过mv.id来得到mv对应的相关信息
   getInfoOfMVs({commit,state},type){
       //对每个得到的mv,获取它的相关信息
       state.recommendMVs.forEach( (mv,index) => {
           axios.get(getInfoOfMVs + mv.id ).then(function(response){
               let likedCount = response.data.likedCount
               let commentCount =  response.data.commentCount
               commit(GETINFOOFMVS,{likedCount,commentCount,index})
           }).then(function(error){

           })
       })
       
   },

//mutations中

[GETRECOMMENDMVS](state,{recommendMVs}){
        state.recommendMVs = recommendMVs
    },
    [GETINFOOFMVS](state,{likedCount,commentCount,index}){
      /*
            这里如果用以下的方法给对象添加属性,不会更新视图,因为这是对已有的(上个ajax中获取到的)对象添加属性
            state.recommendMVs[index].likedCount = likedCount
            state.recommendMVs[index].commentCount = commentCount

            因此需要用 Vue.set 的方法给对象添加数据
        */
        Vue.set(state.recommendMVs[index],'likedCount',likedCount)
        Vue.set(state.recommendMVs[index],'commentCount',commentCount)

    }   


//view中
<div class="card" v-for="(mv,index) in recommendMVs" :key="index">
        <div id="mv">
            <img :src="mv.picUrl" >
            <div id="infoOfMv">
                <span >{{mv.name}}</span>
                <span>by.{{mv.artistName}}</span>
            </div>
        </div>
        <div id="about">
            <img src="../assets/imgs/thumb.png" alt="" class="thumb cardIcon" >
            <!--  这里就可以直接中 对象.属性名 的方式获取数据了,因为已经把数据作为属性传给了对象 -->
            <span>{{mv.likedCount}}</span>
            <img src="../assets/imgs/commend.png" alt="" class="commends cardIcon">
            <span>{{mv.commentCount}}</span> 
        </div>
    </div>
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值