【问题标题】:Vue-router: Using component method within the routerVue-router:在路由器中使用组件方法
【发布时间】:2019-12-23 12:55:39
【问题描述】:

我的第一个 Vue 项目,我想在每个路由器调用上运行加载效果。 我做了一个Loading 组件:

<template>
    <b-loading :is-full-page="isFullPage" :active.sync="isLoading" :can-cancel="true"></b-loading>
</template>

<script>
    export default {
        data() {
            return {
                isLoading: false,
                isFullPage: true
            }
        },
        methods: {
            openLoading() {
                this.isLoading = true
                setTimeout(() => {
                    this.isLoading = false
                }, 10 * 1000)
            }
        }
    }
</script>

我想像这样放置在路由器内部:

router.beforeEach((to, from, next) => {
    if (to.name) {
        Loading.openLoading()
    }
    next()
}

但是我收到了这个错误:

TypeError:“_components_includes_Loading__WEBPACK_IMPORTED_MODULE_9__.default.openLoading 不是函数”

我该怎么办?

【问题讨论】:

    标签: vue.js vue-component vue-router


    【解决方案1】:

    Vuex 是个好点。但为简单起见,您可以在组件中查看$route,并在$route 更改时显示您的加载器,如下所示:

    ...
    watch: {
      '$route'() {
         this.openLoading()
       },
    },
    ...
    

    我认为这是快速而简短的解决方案。

    【讨论】:

    • 我在组件里放了手表,但是什么也没发生
    • 这个 watch 方法会调用吗?你能把console.log()放进去吗?
    • 你的组件应该总是在 DOM 中渲染(不要应用v-if)。
    • 我将组件替换为主要组件,现在它可以工作到无穷大。如果在后台加载了所有内容,我如何查看?
    • 所有内容都已加载是什么意思?这个事件什么时候发生?
    【解决方案2】:

    我认为你不能访问导航守卫 (beforeEach) 中的组件方法,我建议使用 Vuex 这是一个用于数据管理的 vue 插件,然后将 isLoading 设为全局变量,因此在每个之前路线导航你会做同样的事情......这是你可以做到的:

    当然你需要先安装Vuexnpm i vuex ...然后:

    在您初始化 Vue 实例的主文件中

    import Vue from 'vue'
    import Vuex from 'vue'
    
    Vue.use(Vuex)
    
    const store = new Vuex.Store({
      state: {
        isLoading: false,
      },
      mutations: {
        openLoading(state) {
          state.isLoading = true
          setTimeout(() => {
            state.isLoading = false
          }, 10000)
        },
      },
    })
    // if your router is on a separated file just export the store and import it there
    const router = new VueRouter({
      routes: [
        {
          // ...
        },
      ],
    })
    
    router.beforeEach((to, from, next) => {
      if (to.name) {
        store.commit('openLoading')
      }
      next()
    })
    
    new Vue({
       /// ....
       router,
       store,
    })
    

    在您的组件中:

    <b-loading :is-full-page="isFullPage" :active.sync="$store.state.isLoading" :can-cancel="true"></b-loading>
    

    【讨论】:

    • 使用 Vuex 是个好点。但是你的回答在:active.sync="$store.state.isLoading"这一行有错误。你会收到 Vuex 警告,因为你不能直接修改 store,建议你使用 gettersetter 重写它。
    • 嗨,谢谢,但我没有改变它刚刚出价的值(不是'v-model'),是的,使用吸气剂更好……你的解决方案要好得多我猜你只需要包括他正在实现的条件
    • 可能是直接在组件中修改,因为他添加了.sync修饰符,可以改变props。
    猜你喜欢
    • 2021-10-06
    • 2021-03-17
    • 2018-10-22
    • 2021-12-29
    • 1970-01-01
    • 2022-11-30
    • 2018-02-26
    • 2021-04-27
    • 2017-06-20
    相关资源
    最近更新 更多