但愿这个图能显示
情况如图所示,这个计算属性会在 sctext 变动时触发,实际上也的确会这样,但是我在 HTML 中使用{{ suggestion }}发现是空的,但是 console 日志会刷新值,所以很奇怪,为甚返回不到值?
如果图挂了,看源码:
<template>
<div>
... 方便查看所以省略其他
<p>{{ suggestion }}</p>
</div>
</template>
<script>
export default {
data() {
return {
// 从 store 里面读取数据并使用
sctype: "",
scdata: {},
sctypelist: [],
sctext: "",
};
},
created() {
// 设置默认值
var default_type = this.$store.getters.searchTypes[0];
this.sctype = default_type;
this.sctypelist = this.$store.getters.searchTypes;
this.scdata = this.$store.state.searchList[default_type];
},
computed: {
suggestion: function() {
var a = ''
this.$axios
.get("/baidu/su", { params: { wd: this.sctext } })
.then(ret => {
var json_str = ret.data.match(/s:(\[.*\])}\);/);
if (json_str) {
var json_str = json_str[1];
}
console.log(json_str);
a = json_str
});
return a
}
},
methods: {
// 选择表单变化的时候同步数据
changedata: function(command) {
this.sctype = command;
this.scdata = this.$store.state.searchList[command];
}
}
};
</script>
<style scoped>
img {
width: 1.2rem;
margin: 0rem 0.2rem -0.2rem 0rem;
}
</style>
1
murmur 2019-09-02 23:24:26 +08:00
promise 是异步请求啊,你这个问题不懂的话建议先搞一下 promise 是个什么东西
既然是异步 ajax 那返回也应该是一个 promise 才对 |
2
murmur 2019-09-02 23:26:39 +08:00
老老实实用 method 绑事件不好么 看你是搜索提示 这个建议直接用定时器检测改动 你不知道中文输入法有什么坑
然后 a 做成 data 里的变量 检测到有文字输入就搜 搜了在 then 里赋值给 a suggestion 那里就是 a 了 |
3
xxx749 2019-09-02 23:28:37 +08:00 via Android
亲亲,这边建议您用 Watch 呢,您这边另起一个属性把 GET 拿到的数据赋值给这个属性就行了呢
|
4
krisfive 2019-09-02 23:28:54 +08:00
emmm 楼上 +1
|
5
hahasong 2019-09-02 23:30:19 +08:00
计算属性里套 ajax,令人窒息的操作。ajax 还没结束。空的 a 就被返回了
|
6
Allianzcortex 2019-09-02 23:33:32 +08:00
像是 async 和 await 的问题,因为 axios 返回的数据没有被用到,所以会 先 return 再 console.log(). 这里提一个 fix 的方法,把 return a 放到 resolvoe 函数里,楼主可以试下:
var a = ' ' a = this.$axios.get(...).then(... return json_str) |
7
ochatokori 2019-09-02 23:33:47 +08:00 via Android 1
建议先学习 js 异步的概念…
这样说吧,你这个代码的执行顺序是 var a='' //赋值,没问题 axios //哦?这个是异步的,先发请求,结果丢一边等我有空再说 return a//a 还空着,就被 computed 出去了 //刚才有个异步还没处理,现在轮到你了 //得到结果,给 a 赋值,这个时候 a 当然有值,但是 computed 方法早就跑完了 //这里的流程实际上有问题,为了方便理解我省去了微任务和宏任务那些东西… promise 是微任务(面试要考) |
8
Hopetree OP |
9
CDL 2019-09-02 23:38:41 +08:00
computed 只会监听 data,prop 这类属性值
|
10
Allianzcortex 2019-09-02 23:38:45 +08:00
@Allianzcortex 最后还要再 return a,其实是[因为要用到返回的结果]所以能保证[等到 axios 请求结果出来后再返回 computed 的结果]
|
11
Hopetree OP @xxx749 非常感谢,我刚看了一下 watch,发现这个才是我需要的方法,已经实现了效果,下面是我改的
``` watch: { sctext(val) { this.$axios .get("/baidu/su", { params: { wd: this.sctext } }) .then(ret => { var json_str = ret.data.match(/s:(\[.*\])}\);/); if (json_str) { var json_str = json_str[1]; } console.log(json_str); this.suggestion = json_str }); } }, ``` |
12
Allianzcortex 2019-09-03 00:00:57 +08:00
@ochatokori 我理解的流程也是这样的,那么这个 fix 方法理论上应该可以?
|
13
karnaugh 2019-09-03 00:10:17 +08:00
天秀。。。。
|
14
lqzhgood 2019-09-03 00:16:08 +08:00 via Android
用 watch 要 debounce
不然你就是 ddos |
15
Allianzcortex 2019-09-03 00:32:37 +08:00
@ochatokori 算了,看了下,除了 await 外确实没有别的方法,就算是用变量也不行
|
16
SilentDepth 2019-09-03 08:31:44 +08:00
@Allianzcortex #15 如果你是说要让这个过程「同步地」完成,强制循环等待法可解。只是,考虑到 JS 整体是单线程的,你的页面会被冻结(
其实 computed 应对这种需求也不是没有用,只是直观上没那么方便。创建两个普通状态,loading 和 data,然后触发异步动作,首先 loading = true,异步返回后 loading = false 并把返回数据赋值给 data。计算属性同时访问这俩普通状态,当 loading === true 时返回占位内容,loading === false 时返回 data。因为 loading 的变化也会导致计算属性刷新,所以可以直接被模板使用。 这些过程直接写到组件里会比较乱,所以用 Vue.obserable( ) 或 @vue/composition-api 是更好的做法。(是的我就是来安利 Vue 3 的~) |
17
VancleefL 2019-09-03 09:01:23 +08:00
sctext 变动频繁吗?如果变动频繁记得加防抖..
|
18
Zink99 2019-09-03 09:02:09 +08:00
同步任务执行完成后才执行 .then() 中的代码,所以 a 是空
了解下异步? https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/7 |
19
meepo3927 2019-09-03 09:17:23 +08:00
Ajax 异步 ,
你 return a 的时候,a = json_str 还没有执行呢 |
20
no1xsyzy 2019-09-03 09:17:24 +08:00
@SilentDepth 阻塞式请求也是可以同步的,但也会冻结页面,不过 CPU 消耗比较少
|
21
tumobi 2019-09-03 09:21:39 +08:00
还是使用 async await 吧
|
22
no1xsyzy 2019-09-03 09:25:44 +08:00
基础概念问题…… 附一个 2014 年的演讲:
|
23
SilentDepth 2019-09-03 09:27:49 +08:00
@no1xsyzy #20 那个开关不是都被废弃了吗,没准哪天都不能用了(
|
24
hyy1995 2019-09-03 09:34:24 +08:00
你这个问题其实跟 vue 没啥关系,纯粹就是网络请求没请求完成前,你就 return 返回了,此时数据都还没取到,这就是个异步问题,太秀了吧。。。
|
25
liuguang 2019-09-03 09:38:04 +08:00
因为这个是异步的,请求还没完成,就 return 了
|
26
galikeoy 2019-09-03 09:45:40 +08:00
计算属性嵌套异步请求,龟龟,骚操作
|
27
jrtzxh020 2019-09-03 09:48:27 +08:00 via iPhone
有个 asyncComputed 的库 可以了解一下
|
28
lscho 2019-09-03 09:48:56 +08:00
亲亲,建议您学习一下 js 噢
|
29
mikoshu 2019-09-03 10:08:10 +08:00
只想说一句 666 好歹把 return 写到 promise 里面呀
|
30
Curtion 2019-09-03 10:12:08 +08:00
这是异步问题啊,和我初学 js 时犯的问题的一样,建议看看书巩固下基础
|
31
mikoshu 2019-09-03 10:15:58 +08:00
@mikoshu 就算 return 写到 promise 里 还得 return axios 然后返回一个 promise 估计也不好使 果然只能用 await 了 还有楼主改成 watch 的话 如果这个值变动很快 比如监听 input 的 input 事件 就得故意加延迟查询 不然请求太多
|
32
Biwood 2019-09-03 10:17:05 +08:00 via Android
1 楼和 7 楼都已经说到点子上了,去了解一下 JavaScript 同步和异步的原理和机制,比乱猜乱尝试有意义多了。后面还一堆扯到 async await 的,到底是有多菜啊各位,学习框架就真的不用学底层和基础知识了吗
|
33
tolking 2019-09-03 10:19:20 +08:00
建议你打开项目的 eslint 或者配置下。这种情况就会直接提示
``` Unexpected asynchronous action in "suggestion" computed property.eslint(vue/no-async-in-computed-properties) ``` |
34
shintendo 2019-09-03 10:36:55 +08:00
上面说用 await 可以解决的各位,麻烦上个代码好吗?
|
36
ljpCN 2019-09-03 10:55:05 +08:00 via Android
楼主已经解决了,而且也很耐心地去寻求解决方案并尝试。不过还是想说,学 vue 之前,先学 js
|
37
wunonglin 2019-09-03 11:06:26 +08:00
这边建议 lz 先重新学习 vue 呢亲,async 也要另外学一下
|
38
Sapp 2019-09-03 12:48:17 +08:00
我好久没用过 computed 了,但是我似乎记得,这个属性推荐的是做同步操作啊?你这个需求应该在坚挺某个输入的值变化,然后再调用请求,请求完成之后设置 this.a
|
39
mamahaha 2019-09-03 13:02:06 +08:00
你这个相当于是暗恋一个人,对方却不知道。
|
40
johnnyNg 2019-09-03 13:49:59 +08:00
建议重学 js
|
41
mikoshu 2019-09-03 17:02:58 +08:00
|
42
supuwoerc 2019-09-03 17:05:36 +08:00
终于见到我会的问题了(滑稽)
|