Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vue.js 具有不同布局(例如登录布局、页面布局、注册等)的vuejs应用程序_Vue.js_Vue Router - Fatal编程技术网

Vue.js 具有不同布局(例如登录布局、页面布局、注册等)的vuejs应用程序

Vue.js 具有不同布局(例如登录布局、页面布局、注册等)的vuejs应用程序,vue.js,vue-router,Vue.js,Vue Router,我使用vue cli生成了一个项目。我看到这个项目有一个App.vue,它是应用程序的主要布局——如果我没弄错的话。在这里,我放置了我的基本HTML布局和。现在的问题是,我需要完全不同的登录布局(不同的包装器,body有不同的类),但我不能更改它,因为App.vue有一个模板,作为一个布局有点“固定”。如何处理这个问题?有推荐的方法吗 我是否应该创建表示布局的新组件,以便在这种情况下,我的App.vue模板将只包含,然后LoginLayout.vue将包含在其中?我不知道任何“推荐方式”,但我的

我使用vue cli生成了一个项目。我看到这个项目有一个App.vue,它是应用程序的主要布局——如果我没弄错的话。在这里,我放置了我的基本HTML布局和
。现在的问题是,我需要完全不同的登录布局(不同的包装器,body有不同的类),但我不能更改它,因为App.vue有一个模板,作为一个布局有点“固定”。如何处理这个问题?有推荐的方法吗

我是否应该创建表示布局的新组件,以便在这种情况下,我的App.vue模板将只包含
,然后LoginLayout.vue将包含在其中?

我不知道任何“推荐方式”,但我的应用程序的结构如下所示:

App.vue
-仅顶部菜单栏(用户未经身份验证时不会呈现)和每个组件的
(第页)


所以每个页面都可以有完全不同的布局。

我想我找到了一个解决方案。该方法有
App.vue
只包含
,然后包含表示布局的不同组件(如果需要,包含
和子例程)。我发现一个项目就是这样使用它的


我认为这能让事情更干净、更有条理。恕我直言,隐藏所有定义布局结构的元素(所有div)将过于混乱-尤其是对于更大的应用程序。

我通过布局来路由我的应用程序。例如,登录不需要结构,只需要登录组件,但其他页面需要页眉页脚等,因此下面是我如何在路由中执行此操作的示例:

// application routes
'/secure': {
  name: 'secure',
  component: require('../components/layouts/default'),
  subRoutes: {
    '/home': {
      name: 'home',
      component: require('../components/home/index')
    }
  }
}

//- public routes
'/insecure': {
  name: 'insecure',
  component: require('../components/layouts/full-bleed'),
  subRoutes: {
    '/login': {
      name: 'login',
      component: require('../components/session/login')
    }
  }
}

这两个布局模板都有路由器视图标签,因此您可以根据需要为应用程序的不同部分构建布局

我在App.vue上全局动态检查路由,并使用它来确定需要显示的内容

App.vue

导出默认值{
挂载:函数(){
if(window.location.hash==“#/”| | window.location.hash.indexOf('route')){
vm.show.header=true
vm.show.footer=true
vm.show.slideNav=true
}
}
观察:{
$route:function(){
//当路线改变时控制导航
if(window.location.hash==“#/”| | window.location.hash.indexOf('route')){
vm.show.header=true
vm.show.footer=true
vm.show.slideNav=true
}
}
}
}
这样,我也可以通过道具控制顶部和底部导航中显示的内容


希望这有帮助

我通过使用找到了另一个解决方案。我只是有几个组件需要另一个布局

我在src/router/index.js中添加了一个plainLayout元键

然后使用src/App.vue中的playLayout有条件地渲染布局


导出默认值{
名称:“应用程序”,
};

查看演示项目。

一个很好的解决方案是使用

首先创建“布局组件”

src/components/layouts/basic.vue

<template>
  <div class="basic-layout">
    <header>[Company logo]</header>
    <hr>

    <slot/>

    <hr>
    <footer>
      Made with ❤ at Acme
    </footer>
  </div>
</template>

[公司标志]


用❤ 达到顶点
然后在另一个组件中使用它:

<template>
  <layout-basic>
    <p>Hello world!</p>
  </layout-basic>
</template>

<script>
  import LayoutBasic from '@/components/layouts/basic'
  export default {
    components: {
      LayoutBasic
    }
  }
</script>

你好,世界

从“@/components/layouts/basic”导入LayoutBasic 导出默认值{ 组成部分:{ 布局基本 } }
“Hello world”将出现在
标记所在的位置


您还可以有多个具有名称的插槽,请参见。

利用路由,尤其是子路由是在Vue中使用通用布局的一种很好的方法

所有这些代码都使用Vue 2.x

首先要有一个名为App的非常简单的vue组件,它没有布局

app.vue

<template>
    <router-view></router-view>
</template>
<template>
<div>
    <cc-header></cc-header>

    <div class="container">
        <main>
            <router-view></router-view>
        </main>
        <aside>
        </aside>
    </div>

    <cc-footer></cc-footer>    
</div>
</template>

<script lang="ts">

import ccHeader from "../common/cc-header.vue"
import ccFooter from "../common/cc-footer.vue"

export default {
    components: {
        ccHeader,
        ccFooter
    }
}

</script>

<style lang="scss" scoped>

.container {
    display: flex;
}

main {
    flex: 3;
    order: 2;
}

aside {
    flex: 1;
    order: 1;
}
</style>
<template>
<div>
<cc-header></cc-header>

<div class="catalog-container">
    <main class="catalog">
        <router-view></router-view>
    </main>
    <cc-categories></cc-categories>
</div>

<cc-footer></cc-footer>    
</div>

</template>

<script lang="ts">
import ccHeader from "../common/cc-header.vue"
import ccFooter from "../common/cc-footer.vue"

import ccCategories from "./cc-categories.vue"

export default {
    components: {
        ccCategories,
        ccHeader,
        ccFooter
    },
    data : function() : any {
    return {
        search: ''
    }        
},
}
</script>

<style lang="scss" scoped>
.catalog-container {
        display: flex;
    }

    .category-nav {
        flex: 1;
        order: 1;
    }

    .catalog {
        flex: 3;
        order: 2;
    }
</style>
<template>
<div>
    <hr />
    <footer>
        <div class="footer-copyright">
            <div>© Copyright {{year}} GlobalCove Technologies, LLC</div>
            <div>All rights reserved. Powered by CoveCommerce.</div>
        </div>
    </footer>
</div>
</template>

<script lang="ts">
    import Vue from "vue";
    export default Vue.component('cc-footer', {

        data : function() : any {
        return {
            year: new Date().getFullYear()
        }        
    },
    })

</script>

<style lang="scss">
</style>
代码正在使用延迟加载(与网页包一起),因此不要让
()=>导入(…)
将您抛出。如果您想要快速加载,它可以是
import(…)

重要的一点是孩子们的路线。因此,我们将
/account
的主路径设置为使用
/components/account/layout.vue
,但最前面的两个子项指定了主要内容vue(登录)。我选择这样做是因为如果有人只是浏览到/account,我想用登录屏幕问候他们。您的应用程序/帐户可能适合作为登录页,他们可以在其中检查订单历史记录、更改密码等

我对目录做了同样的事情
/
/catalog
都使用
/catalog/catalog
文件加载
目录/布局

另外请注意,如果您不喜欢使用“子文件夹”(即account/login而不是just/login),那么您可以使用我在登录中显示的别名

通过添加
,别名:'/login'
意味着用户可以浏览到
/login
,即使实际路径是
/account/login

这是整件事的关键,但只是试着让这个例子完整

这是我的引导文件,用于连接我的app.vue和路由:

开机。(ts|js)

我为应用程序的每个主要部分(帐户、目录等)创建了layout.vue文件

帐户/布局.vue

<template>
    <router-view></router-view>
</template>
<template>
<div>
    <cc-header></cc-header>

    <div class="container">
        <main>
            <router-view></router-view>
        </main>
        <aside>
        </aside>
    </div>

    <cc-footer></cc-footer>    
</div>
</template>

<script lang="ts">

import ccHeader from "../common/cc-header.vue"
import ccFooter from "../common/cc-footer.vue"

export default {
    components: {
        ccHeader,
        ccFooter
    }
}

</script>

<style lang="scss" scoped>

.container {
    display: flex;
}

main {
    flex: 3;
    order: 2;
}

aside {
    flex: 1;
    order: 1;
}
</style>
<template>
<div>
<cc-header></cc-header>

<div class="catalog-container">
    <main class="catalog">
        <router-view></router-view>
    </main>
    <cc-categories></cc-categories>
</div>

<cc-footer></cc-footer>    
</div>

</template>

<script lang="ts">
import ccHeader from "../common/cc-header.vue"
import ccFooter from "../common/cc-footer.vue"

import ccCategories from "./cc-categories.vue"

export default {
    components: {
        ccCategories,
        ccHeader,
        ccFooter
    },
    data : function() : any {
    return {
        search: ''
    }        
},
}
</script>

<style lang="scss" scoped>
.catalog-container {
        display: flex;
    }

    .category-nav {
        flex: 1;
        order: 1;
    }

    .catalog {
        flex: 3;
        order: 2;
    }
</style>
<template>
<div>
    <hr />
    <footer>
        <div class="footer-copyright">
            <div>© Copyright {{year}} GlobalCove Technologies, LLC</div>
            <div>All rights reserved. Powered by CoveCommerce.</div>
        </div>
    </footer>
</div>
</template>

<script lang="ts">
    import Vue from "vue";
    export default Vue.component('cc-footer', {

        data : function() : any {
        return {
            year: new Date().getFullYear()
        }        
    },
    })

</script>

<style lang="scss">
</style>

路由、普通app.vue和特定布局文件以及通用组件的组合应该可以让您到达您想要的位置。

对接受的答案发表评论

我有点不同意这一点。同样的问题,这个答案让我困惑。基本上,如果您有一个组件,您希望在应用程序中的任何地方(例如页脚、页眉)都可以重用,那么您可以将其保存在
App.vue
中。这是我的情况,我想在每一页上都有页脚和页眉,找到这个答案让我觉得很内敛
<template>
<div>
    <hr />
    <footer>
        <div class="footer-copyright">
            <div>© Copyright {{year}} GlobalCove Technologies, LLC</div>
            <div>All rights reserved. Powered by CoveCommerce.</div>
        </div>
    </footer>
</div>
</template>

<script lang="ts">
    import Vue from "vue";
    export default Vue.component('cc-footer', {

        data : function() : any {
        return {
            year: new Date().getFullYear()
        }        
    },
    })

</script>

<style lang="scss">
</style>
src/
    boot.ts
    routes.ts

    components/
        app.vue

        catalog/
            layout.vue
            catalog.vue
            category.vue
            product.vue
            search.vue
            basket.vue

        account/
            layout.vue
            login.vue
            register.vue

        global/
            notfound.vue

        common/
            cc-header.vue
            cc-footer.vue               
<template>
  <div id="app">
    <app-header />
    <router-view />
    <app-footer />
  </div>
</template>

<script lang="ts">
// Imports related to Vue.js core.
import { Component, Vue } from "vue-property-decorator";

// Imports related with custom logic.
import FooterComponent from "@/components/Footer.vue";
import HeaderComponent from "@/components/Header.vue";

@Component({
  components: {
    "app-footer": FooterComponent,
    "app-header": HeaderComponent
  }
})
export default class App extends Vue {}
</script>

<style lang="scss" scoped>
</style>
<template>
  <div>
    <footer>
      <div>&copy; {{ year }} MyCompany</div>
    </footer>
  </div>
</template>

<script lang="ts">
// Imports related to Vue.js core.
import { Component, Vue } from "vue-property-decorator";

@Component({})
export default class FooterComponent extends Vue {
  public year = new Date().getFullYear();
}
</script>

<style lang="scss" scoped>
</style>
<template>
  <div>
    <header>
      <router-link to="/">Home</router-link>
      <router-link to="/about">About</router-link>
      <router-link to="/contact">Contact</router-link>
    </header>
  </div>
</template>

<script lang="ts">
// Imports related to Vue.js core.
import { Component, Vue } from "vue-property-decorator";

@Component({})
export default class HeaderComponent extends Vue {}
</script>

<style lang="scss" scoped>
</style>