【问题标题】:Vue v-model data is from ajax undefined valueVue v-model 数据来自 ajax 未定义值
【发布时间】:2023-03-17 08:32:01
【问题描述】:

我使用的是vue 2。我有一个来自ajax的数据,这是我的代码示例:

<template>
    <div>
        <input type="input" class="form-control" v-model="siteInfo.siteId">
        <input type="input" class="form-control" v-model="siteInfo.info.name">
        <input type="input" class="form-control" v-model="siteInfo.accountData.name">
    </div>
</template>

<script>
export default {
    name: 'Site',
    data() {
        return {
            siteInfo: {},
            /* siteInfoName: '', */
        }
    },
    /*computed: {
        siteInfoName: function() {
            return siteInfo.info.name || '';
        },
        ...
    },*/
    methods: {
        getData() {
            // do ajax get data
            this.$http.post('URL', {POSTDATA}).then(response => {
                /*
                   response example
                   { body: 
                       data: {
                           sitdeId: 1,
                           info: { name: 'test'},
                           accountData: { name: 'accountTest'},
                       }
                   }
                */
                this.siteInfo = response.body.data;
            })
        }
    },
    mounted() {
        this.getData();
    }
}
</script>

我收到了一条交战信息

[Vue 警告]:渲染错误:“TypeError:无法读取属性‘名称’ 未定义”

  1. 我可以使用computed来修复它,但是如果我有很多模型,我应该 写很多计算。
  2. 我应该为这些模型创建大量数据吗?
  3. 我不应该使用对象来绑定批次模型吗?

对于这种情况,它有其他解决方案吗?谢谢你的帮助。

【问题讨论】:

  • “URL”应该是这样的吗?还是只是为了躲避 SO?以防万一。
  • 我添加了响应数据samepl
  • 我只是想知道这个案例有什么好的解决方案。

标签: vue.js


【解决方案1】:

在数据加载之前siteInfo.info 将是undefined,因此您无法在v-model 中访问name

v-model="siteInfo.info.name"

siteInfo.accountData.name 也是如此。

我的建议是将siteInfo 的初始值设置为null,然后将v-if="siteInfo" 放在主div 上。或者,您可以将v-if 放在单个input 元素上,以检查siteInfo.infositeInfo.accountData

您可能还需要考虑在数据加载时显示替代内容,例如加载掩码。

【讨论】:

    【解决方案2】:

    不用担心 v-model 太多 - 您可以在 Object 上进行迭代 - 就像 Object.entries()

    Vue.component('list-input-element', {
      props: ['siteLabel', 'siteInfo'],
      template: '<div><label>{{siteLabel}}<input type="input" class="form-control" v-model="siteInfo"></label></div>'
    })
    
    new Vue({
      name: 'Site',
      el: '#app',
      data() {
        return {
          siteInfo: {},
        }
      },
      methods: {
        getData() {
          // using mockup data for this example
          fetch('https://jsonplaceholder.typicode.com/todos/1')
            .then(response => response.json())
            .then(json => {
              console.log(json)
              this.siteInfo = json
            })
          // do ajax get data
          /*this.$http.post('URL', {
            POSTDATA
          }).then(response => {
            this.siteInfo = response.body.data;
          })*/
        }
      },
      mounted() {
        this.getData();
      }
    })
    div {
      display: block;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="app">
      <list-input-element v-for="siteInfo in Object.entries(siteInfo)" :site-label="siteInfo[0]" :site-info="siteInfo[1]" />
    </div>

    四舍五入

    因此,当您创建单个文件模板时,请使用 computed 值,并从中返回一个 Object

    将您的 v-for 建立在该计算的之上,您不会有任何问题。

    类似这样的:

    <template>
        <div>
            <input type="input" class="form-control" v-for="infoEl in siteInfoComputed" v-model="infoEl">
        </div>
    </template>
    
    <script>
    export default {
        name: 'Site',
        data() {
            return {
                siteInfo: {},
            }
        },
        computed: {
          siteInfoComputed: function() {
              // you could check for all the keys-values you want here, and handle
              // 'undefined' problem here
              // so, actually you "create" the Object here that you're going to use
              let ret = {}
              // checking if this.siteInfo exists
              if (Object.keys(this.siteInfo).length) ret = this.siteInfo
              return ret
          },
        },
        methods: {
            getData() {
                // do ajax get data
                this.$http.post('URL', {POSTDATA}).then(response => {
                    /*
                       response example
                       { body: 
                           data: {
                               sitdeId: 1,
                               info: { name: 'test'},
                               accountData: { name: 'accountTest'},
                           }
                       }
                    */
                    this.siteInfo = response.body.data;
                })
            }
        },
        mounted() {
            this.getData();
        }
    }
    </script>
    

    【讨论】:

      猜你喜欢
      • 2017-11-07
      • 2020-09-24
      • 2018-11-02
      • 2020-09-13
      • 1970-01-01
      • 1970-01-01
      • 2020-03-15
      • 2021-03-19
      • 1970-01-01
      相关资源
      最近更新 更多