VueJS:仅在计算内部未定义变量

Posted

技术标签:

【中文标题】VueJS:仅在计算内部未定义变量【英文标题】:VueJS: variable is undefined inside computed only 【发布时间】:2018-10-19 23:28:54 【问题描述】:

我正在尝试使用 Vue、Nuxt、Axios 和 Buefy 进行异步自动完成输入。它基本上可以工作,但是当用户刚开始输入并且没有任何内容可显示时,以及没有找到此类请求时,我需要使用不同的字符串。

如果输入值不为空,我将检查计算变量,如果找不到请求地址,axios 返回空数组进行处理。但它会导致错误

无法读取未定义的属性“长度”

奇怪的是,address 变量在我的组件的其他部分成功使用。

我的vue文件如下:

<template lang="pug">
b-field(label="Your address?")
    b-autocomplete(
    rounded,
    v-model="address",
    :data="data",
    placeholder="Start typing",
    icon="magnify",
    @input="getAsyncData",
    @select="option => selected = option",
    :loading="isFetching"
    )
        template(slot="empty")  dummyText 
</template>

<script>
import axios from 'axios'
import debounce from 'lodash/debounce'

export default 
    data() 
        return 
            data: [],
            address: '',
            selected: null,
            isFetching: false,
            nothingFound: false,
            test: false
        
    ,

    computed: 
        dummyText: () => 
            if (this.address.length > 0 && this.nothingFound)  // This will return error
                return 'There is no such address'
             else 
                return 'Keep typing'
            
        
    ,

    methods: 
        getAsyncData: debounce(function () 
            this.isFetching = true

            axios.post('https://suggestions.dadata.ru/suggestions/api/4_1/rs/suggest/address', 
                "query": this.address,
                "count": 8
            , 
                headers: 
                    'Authorization': 'Token sometoken',
                    'Content-Type': 'application/json',
                    'Accept': 'application/json',
                
            )
                .then(response => 
                    this.isFetching = false
                    this.data = Object.values(response.data.suggestions)
                    if (response.data.suggestions.length===0) this.nothingFound = true
                    console.log(this.address.length) // This will work
                )
                .catch(error => 
                    this.isFetching = false
                    console.log(error);
                )
        , 300)
    

</script>

这与 s-s-r 无关,我尝试在挂载的钩子中初始化组件。认为我错过了一些明显的东西,但我已经花了几个小时试图解决这个问题,但没有成功

【问题讨论】:

您可以拥有一个名为“数据”的数据字段吗?听起来您可能会意外清除擦除其他数据字段,这就是为什么在使用 v-model 设置地址之前未定义地址? @AaronPool 刚刚尝试重命名“数据”,没有效果 【参考方案1】:

不要对computed使用箭头函数()=&gt;,这会导致错误的上下文(不是当前的Vue实例)。

更改为function () 然后它应该可以正常工作。

对于methodswatch,您应该遵循相同的规则。

computed: 
    dummyText: function ()  // change to function () 
        if (this.address.length > 0 && this.nothingFound)  // This will return error
            return 'There is no such address'
         else 
            return 'Keep typing'
        
    
,

【讨论】:

【参考方案2】:

您也可以使用 es2015 简写方法函数:

computed: 
    dummyText() 
        return this.address.length > 0 && this.nothingFound ? 'There is no such address' : 'Keep typing';
    

【讨论】:

Eslint 预计:Expected method shorthand【参考方案3】:

Vue Documentation 声明不要在属性或回调上使用箭头函数。

您遇到此错误是因为箭头函数不会将 this 绑定到您为其定义计算属性的 vue 实例,因为箭头函数绑定到父上下文并且 this.address 未定义。如果您对方法使用箭头函数,也会发生同样的情况。

使用正则函数:

dummyText: function () 
    console.log(this.address)

或者使用 ES5 简写:

dummyText() 
    console.log(this.address)

或者如果你想继续使用箭头函数,你可以将组件实例(this)作为参数传递,因为计算属性接收组件实例作为它们的第一个参数。 :

dummyText : ctx => console.log(ctx.address)

【讨论】:

以上是关于VueJS:仅在计算内部未定义变量的主要内容,如果未能解决你的问题,请参考以下文章

Vuejs-nuxt(s-s-r 模式)无法通过插件内部的 getter 获取 UserUUID。它显示未定义的 GetUserUUID

VueJS 进程显示未定义

在计算属性中使用 $refs

Pyspark UDF 广播变量未定义仅在由单独脚本导入时

Vue js 子组件中未定义的道具。但仅在其脚本中

视图laravel内部未定义的变量