在mounted中发起请求是否会取不到值

1.我要再组件里使用res.data.list这时是否是取不到值?一直报错

Error in render: "TypeError: Cannot read property 'list' of undefined"

2.过滤的函数是不是哪里写错了,好像不起作用,要的效果是取到的值包含要搜索词标为蓝色,之前没用vue还可以来着,改写过来不知道是哪里出错,没有效果

   <template v-if="res.data.list" v-for="item in res.data.list">
          <lists v-bind="item" :searchkeyword="keyword"></lists>
   </template> 
     
let vm = new Vue({
    el:'#app',
    data:{
        res:{},
         keyword: base.getQueryString('search'),
        type: base.getQueryString('type'),
        send_data: {},
        pages: 1,
        size: 15,
},
methods:{
    resultSuccess(rs) {
            this.res = {
                ...this.res,
                ...rs.data
            };
            //此处可以取到值
            console.log(this.res.data.list);
        },
},
mounted(){
    base.getData('GET', 'url', this.send_data = {
            ...this.send_data,
            ...{
                page: this.pages,
                size: this.size
            }
        }, this.resultSuccess, this.resultError);
        //报错找不到list
    console.log(this.res.data.list);
},
components: {
        'lists': lists
    }
});

let lists = {
    props: ['id', 'title', 'searchkeyword'],
    inheritAttrs: false,
    template: `
    <div class="result-list-content">
                <div class="article-text">
                    <p class="article-title">
                        <a :href="href">{{title|noticeWord}}</a>
                    </p>
                </div></div>            
    `,
    data() {
        return {
            search: this.searchkeyword,
            href: './a.html?id=' + this.id,

        }
    },
    filters: {
        noticeWord(value) {
            console.log('sfksjlfjs');
            if (!value) return '';
            return value.replace(eval('/' + this.search + '/g'), '<span style="color:#70adff;margin:0;">' + this.search + '</span>');

        }
    },
    beforeCreate() {
        $('.result-list').html(`<p>loading...</p>`);
    },
    mounted() {
        $('p').remove();
    },
}
   
let base = {
    getData: (type, url, dataObject, okcallback, ercallback) => {
      if (String(type).toLowerCase() == 'get' && dataObject) {
         axios.get(url, {
               params: dataObject
            }).then(okcallback)
            .catch(ercallback)
      } else if (!dataObject) {
         axios.get(url).then(okcallback)
            .catch(ercallback)
      } else {
         axios.post(url, qs.stringfy(dataObject)).then(okcallback).catch(ercallback)
      }
   },
getQueryString: (name) => {
      let result = window.location.search.match(new RegExp("[\?\&]" + name + "=([^\&]+)", "i"));
      if (result == null || result.length < 1) {
         return "";
      }
      return decodeURIComponent(result[1]);
   },
}

第二版本

Multiple root nodes returned from render function. Render function should return a single root node.
    <template>
        <lists v-bind="res" :searchkeyword="keyword"></lists>
    </template>
     
let vm = new Vue({
    el:'#app',
    data:{
        res:{},
         keyword: base.getQueryString('search'),
        type: base.getQueryString('type'),
        send_data: {},
        pages: 1,
        size: 15,
},
methods:{
    resultSuccess(rs) {
            this.res = {
                ...this.res,
                ...rs.data
            };
            //此处可以取到值
            console.log(this.res.data.list);
        },
},
mounted(){
    base.getData('GET', 'url', this.send_data = {
            ...this.send_data,
            ...{
                page: this.pages,
                size: this.size
            }
        }, this.resultSuccess, this.resultError);
        //报错找不到list
    console.log(this.res.data.list);
},
components: {
        'lists': lists
    }
});

let lists = {
    props: ['list', 'searchword'],
    inheritAttrs: false,
    template: `
     <template v-if="list" v-for="item in list">
        <div class="result-list-content">
                <div class="article-text">
                    <p class="article-title">
                        <a :href="href">{{item.title|noticeWord}}</a>
                    </p>
                </div></div>           
        </template>      
    `,
    data() {
        return {
            search: this.searchkeyword,
            href: './a.html?id=' + this.id,

        }
    },
    filters: {
        noticeWord(value) {
            console.log('sfksjlfjs');
            if (!value) return '';
            return value.replace(eval('/' + this.search + '/g'), '<span style="color:#70adff;margin:0;">' + this.search + '</span>');

        }
    },
    beforeCreate() {
        $('.result-list').html(`<p>loading...</p>`);
    },
    mounted() {
        $('p').remove();
    },
}
   

第三版本

Cannot use <template> as component root element because it may contain multiple nodes.
Multiple root nodes returned from render function. Render function should return a single root node.
<template>
   <lists v-bind="res" :searchkeyword="keyword"></lists>
</template>
let CommentA = {
    props: ['list', 'searchword'],
    inheritAttrs: false,
    template: `
     <div class = "result-list-content" >
         <div class="article-text">
             <p class="article-title">
                 <a :href="href">{{item.title|noticeWord}}</a>
             </p>
         </div></div>         
    `
}
let vm = new Vue({
    el:'#app',
    data:{
        res:{},
         keyword: base.getQueryString('search'),
        type: base.getQueryString('type'),
        send_data: {},
        pages: 1,
        size: 15,
},
methods:{
    resultSuccess(rs) {
            this.res = {
                ...this.res,
                ...rs.data
            };
            //此处可以取到值
            console.log(this.res.data.list);
        },
},
mounted(){
    base.getData('GET', 'url', this.send_data = {
            ...this.send_data,
            ...{
                page: this.pages,
                size: this.size
            }
        }, this.resultSuccess, this.resultError);
        //报错找不到list
    console.log(this.res.data.list);
},
components: {
        'lists': lists
    }
});

let lists = {
    props: ['list', 'searchword'],
    inheritAttrs: false,
    `
        <template v-if="list" v-for="item in list">
            <component-a v-bind="list" :searchkeyword="searchword"></component-a>       
        </template>
     
    `,
     components: {
        'component-a': CommentA,
    },
    data() {
        return {
            search: this.searchkeyword,
            href: './a.html?id=' + this.id,

        }
    },
    filters: {
        noticeWord(value) {
            console.log('sfksjlfjs');
            if (!value) return '';
            return value.replace(eval('/' + this.search + '/g'), '<span style="color:#70adff;margin:0;">' + this.search + '</span>');

        }
    },
    beforeCreate() {
        $('.result-list').html(`<p>loading...</p>`);
    },
    mounted() {
        $('p').remove();
    },
}
   
阅读 4k
4 个回答

老哥,给res一个data属性

res.data && res.data.list

首先,VueJs的生命周期里mounted是可以获取的this对象的,而且data属性已存在,所以是可以对接口的请求的。其次你data对象中res属性是没有必要的,既然你这里是一个列表的数据,那么直接定义一个数组类型的属性就行,比如叫list:[],其次在VueJs中:

<template v-if="res.data.list" v-for="item in res.data.list">
          <lists v-bind="item" :searchkeyword="keyword"></lists>
   </template> 

类似这样的代码,进行循环的时候,由于res.data.list层级很多,你最初的res对象里是没有data属性,故v-for="item in res.data.list"会报list未定义的错误。再者,一个组件里的最外层的template不要这样去加v-if。你可以这样弄:

<template >
          <div v-if="res.data.list" v-for="item in res.data.list">
              <lists v-bind="item" :searchkeyword="keyword"></lists>
          </div>
   </template> 

这么多代码看着头疼

推荐问题