【问题标题】:Wrapping three specific routes with the same component in VueJS在 VueJS 中用相同的组件包装三个特定的路由
【发布时间】:2017-03-19 14:16:13
【问题描述】:

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

我的登陆页面有这样的事情发生

<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 中的条件逻辑包装容器(对我来说,这似乎不是好的做法)?

【问题讨论】:

    标签: javascript node.js vue.js


    【解决方案1】:

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

    import landingPage from './components/LandingPage';
    export const routes = [
        { path: '/signup', component: landingPage, props: { currentComponent: 'SignUp' } },
        { path: '/login', component: landingPage, props: { currentComponent: 'SignIn' } },
        { path: '', component: landingPage, props: { currentComponent: 'SignIn' } },
        { path: '/forgot', component: landingPage, props: { 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>
    

    【讨论】:

    【解决方案2】:

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

    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】:

      Nested Routes 应该可以很好地解决您的问题。这是文档中的一个示例:

      在下面的组件中,User 部分在两个路由中是相同的,这些路由的内部内容需要不同:

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

      &lt;router-view&gt; 是顶级插座。它呈现与顶级路由匹配的组件。同样,渲染的组件也可以包含它自己的嵌套&lt;router-view&gt;。例如,如果我们在 User 组件的模板中添加一个:

      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。

      【讨论】:

      • 我是这么想的,但对我来说主要问题是如何隐藏 url 中的路由?我认为有类似 mysite.com/landing/login 的东西有点不直观。
      • @MathieuBertin 找到更好的词:P mysite.com/registration/login。但是可能有更好的解决方案。
      • 是的,我正在寻找一种解决方案,使我能够做到这一点,同时将 url 保持为 mysite.com/login。
      • 另外,注册似乎对登录没有意义。
      • 我找到了一个适合我的解决方案。不确定这是否是最好的方法,但我会很感激一些反馈。让我知道你是否可以改进它。
      【解决方案4】:

      对于vue-router 4,这样更容易:

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

      【讨论】:

        【解决方案5】:

        其实答案一直在文档中:

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

        虽然有点难以理解,但这意味着你可以写这样的东西:

         {
            path: '/login',
            component: () => import ('@/pages/SignInSignUpWrapper.vue'),
            children: [
              {
                path: '',
                component: () => import ('@/pages/SignIn.vue')
              },
              {
                path: '/signup',
                component: () => import ('@/pages/SignUp.vue')
              }
            ]
          },
        

        这将只产生两条路线:/login/signup。 它们都将SignInSignUpWrapper 组件作为父组件,并且这些组件将呈现在SignInSignUpWrapper&lt;route-view&gt; 的槽中

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-12-24
          • 2022-01-18
          • 1970-01-01
          • 2018-11-15
          • 2018-10-20
          • 2017-08-26
          • 1970-01-01
          • 2021-03-06
          相关资源
          最近更新 更多