在VueJS中使用相同组件包装三个特定路由

时间:2017-03-19 14:16:14

标签: javascript node.js vue.js

我有三个路由,/ login,/ signup和/忘记及其相应的组件,它们只包含您期望的基本表单。我希望这些组件包含在登录页面组件中,而不必将我的登陆页面逻辑放在我的三个组件中,因为这会重新加载容器并且我的转换不会显示。

我的目标网页上有这样的内容

<h1>Welcome to my web app</h1>
<transition name="slide" mode="">
   <router-view></router-view>
<transition>

routes.js看起来像这样

import SignUp from './components/SignUp';
import SignIn from './components/SignIn';
import Forgot from './components/Forgot';
export const routes = [
    { path: '/signup', component: SignUp },
    { path: '/login', component: SignIn },
    { path: '', component: SignIn },
    { path: '/forgot', component: Forgot }
];

我需要一些中间隐藏的路线吗?或者我只能根据App.vue中的条件逻辑包装容器(对我来说,这似乎不是一个好习惯)?

4 个答案:

答案 0 :(得分:3)

在router.js中,您可以将currentComponent作为prop发送,

import landingPage from './components/LandingPage';
export const routes = [
    { path: '/signup', component: landingPage, prop: { currentComponent: 'SignUp' } },
    { path: '/login', component: landingPage, prop: { currentComponent: 'SignIn' } },
    { path: '', component: landingPage, prop: { currentComponent: 'SignIn' } },
    { path: '/forgot', component: landingPage, prop: { currentComponent: 'Forgot' } }
];

并将着陆页视为组件(LandingPage.vue)

<template>    
<h1>Welcome to my web app</h1>
    <transition name="slide" mode="">
       <component :is="currentComponent">
    <transition>
</template>

<script>
import SignUp from './components/SignUp';
import SignIn from './components/SignIn';
import Forgot from './components/Forgot';
export default {
  components: ['SignUp', 'SignIn', 'Forgot'],
  props: ['currentComponent']
}
</script>

答案 1 :(得分:1)

Nested Routes应该很好地处理你的问题。以下是文档中的示例:

在以下组件中,User部分在两条路线中都相同,内部内容在这些路线中需要不同:

/user/foo/profile                     /user/foo/posts
+------------------+                  +-----------------+
| User             |                  | User            |
| +--------------+ |                  | +-------------+ |
| | Profile      | |  +------------>  | | Posts       | |
| |              | |                  | |             | |
| +--------------+ |                  | +-------------+ |
+------------------+                  +-----------------+

<router-view>是一个顶级出口。它使组件与顶级路由匹配。同样,渲染组件也可以包含自己的嵌套<router-view>。例如,如果我们在用户组件的模板中添加一个:

const User = {
  template: `
    <div class="user">
      <h2>User {{ $route.params.id }}</h2>
      <router-view></router-view>
    </div>
  `
}

要将组件渲染到这个嵌套的插座中,我们需要在VueRouter构造函数配置中使用children选项:

const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User,
      children: [
        {
          // UserProfile will be rendered inside User's <router-view>
          // when /user/:id/profile is matched
          path: 'profile',
          component: UserProfile
        },
        {
          // UserPosts will be rendered inside User's <router-view>
          // when /user/:id/posts is matched
          path: 'posts',
          component: UserPosts
        }
      ]
    }
  ]
})
  

请注意,以/开头的嵌套路径将被视为根路径。这允许您利用组件嵌套而无需使用嵌套URL。

答案 2 :(得分:0)

我能够使用像这样的命名嵌套<router-view>元素来完成这项工作

routes.js

import SignUp from './components/SignUp';
import SignIn from './components/SignIn';
import Forgot from './components/Forgot';
import RegistrationWrapper from './components/RegistrationWrapper';

export const routes = [{
    path: '/signup',
    components: {
        default: SignUp,
        'wrapper': RegistrationWrapper
    }
}, {
    path: '/login',
    components: {
        default: SignIn,
        'wrapper': RegistrationWrapper
    }
}, {
    path: '/forgot',
    components: {
        default: Forgot,
        'wrapper': RegistrationWrapper
    }
}, {
    path: '/',
    components: {
        default: SignIn,
        'wrapper': RegistrationWrapper
    }
}];

RegistrationWrapper.vue

<template>
   <h1>Welcome to my web app</h1>
   <transition name="slide" mode="">
      <slot></slot>
   <transition>
<template>

我的App.vue看起来像这样

<template>
    <div>
       <router-view name="wrapper">
          <router-view></router-view>
       </router-view>
   </div>
</template>

我能看到的唯一缺点就是我现在必须为我的所有路线提供一个包装器,这可能会变得多余。如何在App.vue中检测是否提供了包装器?另外,我还没有看到另一个缺点吗?

答案 3 :(得分:0)

对于vue-router 4,这种方式更简单:

<router-view v-slot="{ Component }">
  <Wrapper>
    <component :is="Component" />
  </Wrapper>
</router-view>