vue.js 2.0怎样实现父组件方法先于子组件方法之前执行

使用vue-cli创建的项目,父组件App.vue里加载了子组件index.vue,父组件与子组件的methods里各自有个方法。预设的想法是想在父组件App.vue的方法里把ajax请求到的数据设置成缓存,然后子组件index.vue的方法去使用缓存的数据。但调试结果发现,无论父组件App.vue里的方法放在函数生命周期里的哪个钩子里,执行的顺序总是慢于子组件index.vue的方法,导致子组件里调用的缓存数据是undefined,结果报错。详情如下图
图片描述

图片描述

父组件代码如下:

<template>
    <div id="app">
        <router-view/>
    </div>
</template>

<script>
import bus from '../static/js/bus.js'
export default {
    name: 'app',
    data () {
        return {
        
        }
    },
    methods: {
        checkLoingStatus () {
            //首次进入页面初始化默认未登录并跳转到登录页面
            if (!this.currentLoginStatus && !this.loginStatus) {
                App.setStorage('loginStatus', {'loginStatus': false}, 'localStorage')
                window.location.href = "#/signIn"
            }
        },
        getData () {
            $.ajax({
                url: '../../static/data/data.json',
                type: 'get',
                success: (response) => {
                    console.log('=== ' + response.message + ' ===')
                    console.log('=== 缓存基础配置数据成功 ===');
                    //此处设置基础数据缓存response.data
                    App.setStorage('response', {'data': response.data}, 'localStorage')
                },
                error: (response) => {
                    //...
                }
            })
        }
    },
    beforeCreate:function(){//组件实例化之前
        console.log('1===beforeCreate===')
    },
    created:function(){//组件实例化了
        console.log('2===created===')
    },
    beforeMount:function(){//组件写入dom结构之前
        console.log('3===beforeMount===')
    },
    mounted:function(){//组件写入dom结构了
        console.log('4===mounted===')
        //基础配置数据
        this.getData()
    },
    beforeUpdate:function(){//组件更新前
        console.log('5===beforeUpdate===')
    },
    updated:function(){//组件更新比如修改了文案
        console.log('6===updated===')
    },
    beforeDestroy:function(){//组件销毁之前
        console.log('7===beforeDestroy===')
    },
    destroyed:function(){//组件已经销毁
        console.log('8===destroyed===')
    }
}
</script>

子组件代码如下:

<template>
    <div class="page">
        <!-- 省略 -->
    </div>
</template>

<script>
export default {
    name: 'index',
    data() {
        return {
        }
    },
    components: {
    },
    methods: {
        getStorageResponseData () {
            //获取缓存的基础配置数据
            console.log('=== 开始使用缓存里的基础配置数据 ===')
            this.responseData = App.getStorage('response').data
        }
    },
    mounted () {
        this.$nextTick(() => {
            //由于getStorageResponseData比父组件的设置缓存方法先执行
            //结果获取不到缓存数据,报undefined
            this.getStorageResponseData()
        })
    }
}
</script>
阅读 15.3k
10 个回答

我今天也遇到了类似的问题,在父组件created时异步请求数据并存入vuex,子组件created时使用vuex里的数据初始化,结果子组件初始化时vuex里的数据是空的。后来发现可以在子组件里通过watch监听vuex里的属性试试,结果成功啦~
不过话说回来如果像楼主一样在不用vuex的情况下,直接在父组件钩子函数this.getData()之后再通过this.$refs.child.getStorageResponseData()调用子组件的方法应该可以解决问题。

你把父组件拿到的数据当做props传给子组件啊,不需要缓存

思路好像有点问题,因为ajax异步请求,导致你这个缓存其实不是最优的传递方式,子父类组件推荐用
1、prop传递prop文档

2、传递进去后,可以在子组件内调用updated 钩子函数进行渲染,可以解决异步的问题

抛开大家说的你的思路啥的有没有问题,单纯的你想要父组件执行之后子组件才执行,那么你等父组件将数据取到之后再父组件中调用子组件的函数就行了。

父子组件钩子汉族加载顺序:
father created
father before mounted
son created
son before mount
son mounted
father mounted
所以,你在父组件 beforeMounted 中已初始化的值一定可以通过props下发到子组件

路过:是不是可以考虑用vuex。。。。。。。。。。。。。

父组件往子组件传递数据应该使用props,如果组件较多,通信频繁,推荐使用vuex。

你确定在异步响应完成之前子组件还没有走完一遍生命周期?

解决了吗? 我也是想 减少ajax请求次数

新手上路,请多包涵

本题的初衷是把父组件App.vue与子组件index.vue的配置数据全部都写在一个data.json文件,然后在父组件App.vue通过一次ajax请求到数据,在App.vue使用数据的同时,把数据缓存起来,给子组件index.vue去使用,以到达减少ajax请求次数,但发现这样无法实现。所以,还是回归原始解决方法,把data的配置数据分开成两个json文件,分别在父组件与子组件去调用ajax获取并分别使用。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题