VueJS:变量在仅计算内部未定义
VueJS: variable is undefined inside computed only
我正在尝试使用 Vue、Nuxt、Axios 和 Buefy 进行异步自动完成输入。它基本上可以工作,但是当用户刚开始输入时我需要有不同的字符串,但还没有显示任何内容,并且当没有找到此类请求时。
如果输入值不为空,我将检查计算变量;如果找不到请求地址,我将检查 axios returns 空数组来处理。但它会导致错误
Cannot read property 'length' of undefined
奇怪的是 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>
这与 ssr 无关,我已经尝试在 mounted 钩子中初始化组件。我想我错过了一些明显的东西,但我已经花了几个小时试图解决这个问题但没有成功
不要为computed
使用箭头函数()=>{}
,这会导致错误的上下文(不是当前的Vue实例)。
更改为 function () {}
然后它应该可以正常工作。
对于 methods
、watch
,您应该遵循相同的规则。
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'
}
}
},
你也可以使用 es2015 shorthand 作为方法函数:
computed: {
dummyText() {
return this.address.length > 0 && this.nothingFound ? 'There is no such address' : 'Keep typing';
}
}
Vue Documentation 声明不要在 属性 或回调中使用箭头函数。
您遇到此错误是因为箭头函数不会将 this 绑定到您为其定义计算 属性 的 vue 实例,因为箭头函数绑定到父上下文并且 this.address未定义。如果您对方法使用箭头函数,也会发生同样的情况。
使用正则函数:
dummyText: function () {
console.log(this.address)
}
或使用 ES5 shorthand:
dummyText() {
console.log(this.address)
}
或者如果您想继续使用箭头函数,您可以将组件实例 (this) 作为参数传递,因为计算属性接收组件实例作为它们的第一个参数。 :
dummyText : ctx => console.log(ctx.address)
我正在尝试使用 Vue、Nuxt、Axios 和 Buefy 进行异步自动完成输入。它基本上可以工作,但是当用户刚开始输入时我需要有不同的字符串,但还没有显示任何内容,并且当没有找到此类请求时。
如果输入值不为空,我将检查计算变量;如果找不到请求地址,我将检查 axios returns 空数组来处理。但它会导致错误
Cannot read property 'length' of undefined
奇怪的是 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>
这与 ssr 无关,我已经尝试在 mounted 钩子中初始化组件。我想我错过了一些明显的东西,但我已经花了几个小时试图解决这个问题但没有成功
不要为computed
使用箭头函数()=>{}
,这会导致错误的上下文(不是当前的Vue实例)。
更改为 function () {}
然后它应该可以正常工作。
对于 methods
、watch
,您应该遵循相同的规则。
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'
}
}
},
你也可以使用 es2015 shorthand 作为方法函数:
computed: {
dummyText() {
return this.address.length > 0 && this.nothingFound ? 'There is no such address' : 'Keep typing';
}
}
Vue Documentation 声明不要在 属性 或回调中使用箭头函数。
您遇到此错误是因为箭头函数不会将 this 绑定到您为其定义计算 属性 的 vue 实例,因为箭头函数绑定到父上下文并且 this.address未定义。如果您对方法使用箭头函数,也会发生同样的情况。
使用正则函数:
dummyText: function () {
console.log(this.address)
}
或使用 ES5 shorthand:
dummyText() {
console.log(this.address)
}
或者如果您想继续使用箭头函数,您可以将组件实例 (this) 作为参数传递,因为计算属性接收组件实例作为它们的第一个参数。 :
dummyText : ctx => console.log(ctx.address)