【问题标题】:Vuejs2 Modal with route in vue-router在 vue-router 中带有路由的 Vuejs2 模态
【发布时间】:2017-06-16 21:17:44
【问题描述】:

我正在尝试使用模态创建路由,当您使用路由器链接访问此路由器路径时,当前页面上方会出现一个模态,或者如果我直接从 url 访问,则会出现上面带有模态的索引。

例如:我在http://localhost/profile/1,然后点击侧边栏的创建团队,网址更改为http://localhost/team/create,但模态后面的页面仍然是http://localhost/profile/1

这是我正在尝试的代码:

路由器:

Vue.component('modal', Modal);    
export default new Router({
      mode: 'history',
      routes: [
       {
        path: '/',
        name: 'Hello',
        component: require('@/components/Hello'),
        meta: { auth: false }
      },

      {
        path: '/team',
        name: 'team',
        component: require('@/components/team/Index'),
        meta: { auth: true },
      },
      {
        path: '/team/create',
        name: 'CreateTeam',
        components: {
          b: CreateTeam
        },
        meta: { auth: true }
      },  
      ]
    })

App.vue

<template>

  <router-view></router-view>
  <!-- This is the "MODAL" router-view -->
  <router-view name="b"></router-view>              

</template>

Modal.vue

<template>
    <div class="modal">

      <slot name="body"></slot>  
        <button type="button" @click="$emit('close')">×</button>
   </div>
</template>

创建团队.vue

<template>
    <modal @close="vm.$router.go(-1)">

        <div slot="body" class="col-md-12">
        <!-- Form here -->
        </div>

    </modal>
</template>

一切正常,而不是当我转到 /create/team 时,模态后面是空的

【问题讨论】:

  • 在这种情况下,您的模式不应该是一条路线,它应该是与您的router-view 相同的组件的一个元素。当您需要显示它时,使用事件或状态管理从该组件触发它,甚至通过router-view 将函数传递给需要触发它的组件。
  • 我明白,但在这种情况下,我想在任何组件中打开,如“全局模式”。如果我确实喜欢你说所有组件都必须具有模态组件的代码和不同的路径,例如:配置文件/模态,团队/模态“我想从任何地方打开团队/创建
  • 不,我不是这个意思。它应该存在于 App.vue 中,它不应该是路由,并且您的 路由的组件应该触发它。
  • 当然。所有组件都可以访问$router
  • 如果你想让后退按钮正常工作并关闭模式,那么最好使用路由器的解决方案,并且会更“干净”

标签: vue.js


【解决方案1】:

如果有人需要这个解决方案,我是这样解决的:

我创建了一个组件 create-team Vue.component('create-team',CreateTeam) 并将它放在 App.vue 中,如下所示:

<create-team v-if="CreateTeam"></create-team>  

在同一个 App.vue 中,我使用 vuex getter 创建了一个计算:

computed: {

    CreateTeam() {
         return store.getters.createTeam
    }
  },

在侧边栏我创建了一个这样的链接:

 <a @click="CreateTeam" class="user-panel-action-link" href="/create/team">
   <i class="fa fa-users" aria-hidden="true"></i> Crear Equipo
 </a>

还有一个方法 CreateTeam

CreateTeam(e) {
      e.preventDefault()
      store.commit('setTeamModal')
      history.pushState('', 'Title of page', '/create/team');

    }

store.js vuex 很简单:

const state = {

    createTeam: false,
}

const mutations = {

    setTeamModal (state) {
      state.createTeam= true
    },
    deleteTeamModal (state) {
      state.createTeam= false
    }
}

const actions = {
    setTeamModal: ({ commit }) => commit('setTeamModal')
   deleteTeamModal: ({ commit }) => commit('setTeamModal')
}

const getters = {

    createTeam: state => state.createTeam
}

export default new Vuex.Store({
    state,
    getters,
    actions,
    mutations
})

最后一件事是在 CreateTeam.vue 组件中,我制作的 Close 方法是这样的:

 Close() {
      this.$store.commit('deleteTeamModal')
      this.$router.go(-1)
    }

  }

也许有人可以让它变得更好,这是我的一点帮助

问候

【讨论】:

  • 不错的一个!也会尝试一下 - 很高兴知道 history.pushState(..) 就像那样与 vue-router 一起工作..
  • 我觉得用js来处理路由不是个好主意。一定有办法使用 vue-router 模式...
【解决方案2】:

如果其他人寻找类似问题的解决方案,则提供here。 在重定向到模态路由之前,以编程方式更改命名路由的组件。像登录/注册模式的魅力一样为我工作。
我的笔记:
1. 确保模态路由不是任何路由的子路由(默认路由组件有一些问题)。
2.考虑在模态关闭按钮上添加router.back()

router.js
    ...
    {
      path: '/',
      name: 'home',
      component: Home,
      meta: {
        twModalView: true
      }
    },
    {
      path: '/directAccess',
      name: 'directAccess',
      component: DirectAccess
    },
    ...
    {
      path: '/:userId/tweet/:id',
      name: 'userTweet',
      beforeEnter: (to, from, next) => {
        const twModalView = from.matched.some(view => view.meta && view.meta.twModalView)

        if (!twModalView) {
          //
          // For direct access
          //
          to.matched[0].components = {
            default: TweetSingle,
            modal: false
          }
        }

        if (twModalView) {
          //
          // For twModalView access
          //
          if (from.matched.length > 1) {
            const childrenView = from.matched.slice(1, from.matched.length)
            for (let view of childrenView) {
              to.matched.push(view)
            }
          }
          if (to.matched[0].components) {
            to.matched[0].components.default = from.matched[0].components.default
            to.matched[0].components.modal = TweetModal
          }
        }

        next()
      }
    },
    ...

【讨论】:

    猜你喜欢
    • 2020-12-03
    • 1970-01-01
    • 2020-09-16
    • 2017-12-30
    • 2020-09-15
    • 2021-11-09
    • 2020-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多