vuejs parent 获取所有 child 数据后的事件
vuejs parent event once all child data is fetched
我是 vuejs 的新手,对于是否应该使用事件或 vuex 来了解何时从服务器获取所有 children 的数据仍然有些迷茫。
例如我有一个结构如下的路由:
<Parent>
<Child1 />
<Child2 />
<Child3 />
</Parent>
然后在每个 child 组件中,我有一个 fetchData() 方法,它从不同端点从服务器检索数据:
export default {
created() {
// fetch data
this.fetchData()
},
methods: {
fetchData() {
this.$http.get('/api/dataN', {})
.then(response => {
// do something
}).catch(error => {})
}
}
}
parent 如何知道一旦 所有 child 数据都已获取 因此 parent 可以执行操作?
我想让它成为一个通用函数,所以在另一条路线只有两个 children(或超过 3 个)的情况下,事件总是被触发。
我查看了 parent 挂钩,但似乎我在创建时获得了 child 数据(组件已加载),parent 挂钩对我没有用 - 因为据我所知。
我需要为 parent 修改 DOM 的示例:
你应该从每个子组件发出一个事件,父组件添加一个名为 nb_components
的数据 属性,它用组件的数量初始化,另一个 count
将递增每次子组件执行其任务时:
export default {
created() {
// fetch data
this.fetchData()
},
methods: {
fetchData() {
this.$http.get('/api/dataN', {})
.then(response => {
this.$emit('fetch-data')
}).catch(error => {})
}
}
}
和父组件:
<Parent>
<Child1 @fetch-data="increment" />
<Child2 @fetch-data="increment" />
<Child3 @fetch-data="increment" />
</Parent>
脚本
data(){
return{
count:0,
nb_components:3
....
}
},
methods:{
increment(){
this.count++;
if(this.count==this.nb_components){
//stop the spinner
}
}
...
}
下面是一个使用异步回调函数的示例。每个子组件 returns 它自己的一个异步函数(例如 api 调用),父组件解析并保留一个 运行 触发回调次数的计数器:
Vue.component('child', {
template: `<div>I take {{ timeout }} seconds to finish. <span>{{ message }}</span></div>`,
props: ['callback'],
data () {
return {
timeout: Math.ceil(Math.random() * 10),
complete: false
}
},
computed: {
message () {
return this.complete ? 'Done!' : 'Working...'
}
},
mounted() {
setTimeout(() => {
this.complete = !this.complete
const func = async () => {}
this.callback.call(this, func)
}, this.timeout * 1000)
}
})
new Vue({
el: '#app',
data() {
return {
max: 10,
counter: 0
}
},
computed: {
message () {
return this.counter < this.max ? `${this.max - this.counter} Jobs remaining` : `All jobs complete!`
}
},
methods: {
async callback(func) {
const data = await func()
this.counter += 1
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<p>{{ message }}</p>
<child v-for="i in max" :key="i" :callback="callback" style="margin: 1rem 0;"></child>
</div>
最后我做的略有不同:
- child 保持微调器的状态
- $emit 为 parent 提供回调 - 打开微调器
/ 关
这不是我的完整代码,但为您提供了我如何解决它的示例。
<div id="app">
<div id="spinner" v-show="spinner" key=1></div>
<child v-show="!spinner" @spinnerCallback="setSpinner" />
</div>
Vue.component('child', {
template: `<div>this is child data</div>`,
data() {
return {
tiles: '',
}
},
created() {
// start spinner
this.$emit('spinnerCallback', 1)
//fetch data
this.fetchData()
},
methods: {
fetchData() {
this.$http.get('/api/dashboard', {})
.then(response => {
this.tiles = response.data.tiles//,
this.$emit('spinnerCallback', 0)
}).catch(error => {})
}
}
})
var app = new Vue({
el: '#app',
data() {
return {
spinner: null,
}
},
methods: {
setSpinner: function(value) {
// toggle spinner
if (value == 1) {
this.spinner = true;
} else {
this.spinner = false;
}
}
},
})
我是 vuejs 的新手,对于是否应该使用事件或 vuex 来了解何时从服务器获取所有 children 的数据仍然有些迷茫。
例如我有一个结构如下的路由:
<Parent>
<Child1 />
<Child2 />
<Child3 />
</Parent>
然后在每个 child 组件中,我有一个 fetchData() 方法,它从不同端点从服务器检索数据:
export default {
created() {
// fetch data
this.fetchData()
},
methods: {
fetchData() {
this.$http.get('/api/dataN', {})
.then(response => {
// do something
}).catch(error => {})
}
}
}
parent 如何知道一旦 所有 child 数据都已获取 因此 parent 可以执行操作?
我想让它成为一个通用函数,所以在另一条路线只有两个 children(或超过 3 个)的情况下,事件总是被触发。
我查看了 parent 挂钩,但似乎我在创建时获得了 child 数据(组件已加载),parent 挂钩对我没有用 - 因为据我所知。
我需要为 parent 修改 DOM 的示例:
你应该从每个子组件发出一个事件,父组件添加一个名为 nb_components
的数据 属性,它用组件的数量初始化,另一个 count
将递增每次子组件执行其任务时:
export default {
created() {
// fetch data
this.fetchData()
},
methods: {
fetchData() {
this.$http.get('/api/dataN', {})
.then(response => {
this.$emit('fetch-data')
}).catch(error => {})
}
}
}
和父组件:
<Parent>
<Child1 @fetch-data="increment" />
<Child2 @fetch-data="increment" />
<Child3 @fetch-data="increment" />
</Parent>
脚本
data(){
return{
count:0,
nb_components:3
....
}
},
methods:{
increment(){
this.count++;
if(this.count==this.nb_components){
//stop the spinner
}
}
...
}
下面是一个使用异步回调函数的示例。每个子组件 returns 它自己的一个异步函数(例如 api 调用),父组件解析并保留一个 运行 触发回调次数的计数器:
Vue.component('child', {
template: `<div>I take {{ timeout }} seconds to finish. <span>{{ message }}</span></div>`,
props: ['callback'],
data () {
return {
timeout: Math.ceil(Math.random() * 10),
complete: false
}
},
computed: {
message () {
return this.complete ? 'Done!' : 'Working...'
}
},
mounted() {
setTimeout(() => {
this.complete = !this.complete
const func = async () => {}
this.callback.call(this, func)
}, this.timeout * 1000)
}
})
new Vue({
el: '#app',
data() {
return {
max: 10,
counter: 0
}
},
computed: {
message () {
return this.counter < this.max ? `${this.max - this.counter} Jobs remaining` : `All jobs complete!`
}
},
methods: {
async callback(func) {
const data = await func()
this.counter += 1
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<p>{{ message }}</p>
<child v-for="i in max" :key="i" :callback="callback" style="margin: 1rem 0;"></child>
</div>
最后我做的略有不同:
- child 保持微调器的状态
- $emit 为 parent 提供回调 - 打开微调器 / 关
这不是我的完整代码,但为您提供了我如何解决它的示例。
<div id="app">
<div id="spinner" v-show="spinner" key=1></div>
<child v-show="!spinner" @spinnerCallback="setSpinner" />
</div>
Vue.component('child', {
template: `<div>this is child data</div>`,
data() {
return {
tiles: '',
}
},
created() {
// start spinner
this.$emit('spinnerCallback', 1)
//fetch data
this.fetchData()
},
methods: {
fetchData() {
this.$http.get('/api/dashboard', {})
.then(response => {
this.tiles = response.data.tiles//,
this.$emit('spinnerCallback', 0)
}).catch(error => {})
}
}
})
var app = new Vue({
el: '#app',
data() {
return {
spinner: null,
}
},
methods: {
setSpinner: function(value) {
// toggle spinner
if (value == 1) {
this.spinner = true;
} else {
this.spinner = false;
}
}
},
})