Vue.js CLI 中的多个页面

IT技术 javascript html vue.js vue-cli multi-page-application
2021-03-06 11:38:47

我无法弄清楚如何在 Vue CLI 项目中拥有多个页面。现在我的主页有几个组件,我想创建另一个页面,但我不知道该怎么做。我是否应该在默认情况下创建多个 html 文件,其中 index.html 是?在使用 css js img 文件夹和 html 文件作为页面的简单文件结构中,我知道创建另一个 html 文件意味着创建另一个页面。但我不明白这如何与 Vue CLI 项目配合使用。

我在 Vue 文档中看到了诸如 vue-router 和“页面”之类的东西,但我不太了解它们。我的选择是什么?有没有详细解释的指南,因为我找不到任何指南,更不用说详细了。如果能帮到你会很开心!谢谢!

4个回答

第一:始终阅读官方文档。有了Vue就可以搭建SPA了,MPA也是没问题的。只需按照指南:

您应该使用 Vue CLI 3 创建一个新项目。创建项目后,将其设置为手动配置。确保您没有选择 SPA 选项。然后,Vue 将使用 MPA 方法创建一个不错的“开始”项目。之后,只需在 vue.config.js 上重复配置即可。


更新 #1

Vue Cli 的一些更新似乎改变了构建 MPA 应用程序的方式,因此:

  • 创建一个新的应用程序 vue create test
  • 选择手动配置

创建的样板将用于 SPA。因此进行以下更改:

  • src命名下创建一个文件夹pages(可选)

  • 在此文件夹中创建您自己的页面:主页、关于等。

  • 将 App.vue 和 main.js 从 src 复制并粘贴到您的新文件夹中 - Home 等。

  • App.vue根据您的喜好将其格式化到此文件夹中。

  • 创建一个 vue.config.js 并像这样设置:https ://cli.vuejs.org/config/#pages

下面,我用三张图片来证明这一点:

  • 第一:一个全新的应用程序
  • 第二:同一个应用程序,加上我在上面所做的更改
  • 第三:来自这个应用程序的 vue.config.js

全新的应用程序 同一个应用程序,加上我在上面所做的更改 这个应用程序中的 vue.config.js

不需要创建pages文件夹,这只是为了获得想法。

GitHub 链接:构建 MPA 应用程序

最好的解决方案,虽然我找不到更详细的多页教程
2021-05-01 11:38:47
set to manually configure it. Then, don't choose the SPA option. Vue will create a nice "start" project using a MPA approach.这是不正确的,我尝试使用 Vue CLI 3.4.0,我选择了手动,没有选择/不选择 SPA 的选项。Vue CLI 将使用 SPA 方法生成标准样板项目。
2021-05-03 11:38:47
它们仍然是同一个应用程序。node_modules 和您构建的任何组件都可以在它们之间共享,只需通过导入即可 - 与使用 SPA 的方式相同。我不明白你所说的“不上传到 npm”是什么意思。
2021-05-10 11:38:47
这应该是公认的答案..到目前为止,它工作正常上Vue CLI 3.4.0应注意的Vue CLI不看你的变化vue.config.js,所以如果你想了解新的设置,您已经改变了你必须npm run serve一次。
2021-05-16 11:38:47
似乎他们已经改变了它。无论如何,您需要按照此处的示例进行操作:cli.vuejs.org/config/#pages另外:选择手动配置时不要选择“路由”选项
2021-05-20 11:38:47

编辑:Vue 内置了这个。跳到底部了解更多。

原答案:

有两种方法可以解释您的问题,因此可以回答它。

第一种解释是:“我如何支持路由到同一个单页应用程序中的不同页面,例如 localhost:8080/about 和 localhost:8080/report 等?”。答案是使用路由器。它相当简单并且运行良好。

第二种解释是:“我的应用程序很复杂,我有多个单页应用程序,例如一个用于‘网站’部分的应用程序,一个用于消费者登录和工作的应用程序,一个用于管理员的应用程序等 - 怎么办? vue 在不创建三个完全独立的存储库的情况下执行此操作?”

后者的答案是具有多个单页应用程序的单个存储库。这个演示看起来正是你所追求的:

https://github.com/Plortinus/vue-multiple-pages/

特别查看:https : //github.com/Plortinus/vue-multiple-pages/blob/master/vue.config.js

更新的答案:

原来vuejs有内置多个顶级页面的想法。我的意思是,这是有道理的 - 这将非常普遍,尽管许多不正确的答案都在说“不,它适用于单页应用程序”!

您需要文件中pages选项vue.config.js

https://cli.vuejs.org/config/#pages

如果您的项目在根目录中没有该文件,请创建它,vuejs 会发现它。

定义每个页面的方法有长有短。我在这里使用了简短的形式:

module.exports = {
  pages: {
    index: 'src/pages/index/main.ts',
    experiment: 'src/pages/experiment/main.ts'
  }
}

你不必把你的工作放在“页面”下。它可以是“/src/apps/index/index.ts”或其他什么。

在移动代码并更改一些导入后:

import HelloWorld from './components/HelloWorld'

import HelloWorld from '@/components/HelloWorld'

该应用程序有效 - 但我的回购中的“实验”应用程序必须像这样加载:

http://localhost:8080/experiment.html

非常丑陋,甚至更糟,因为它使用了导致 URL 如下的路由器:

http://localhost:8080/experiment.html/about

啊。

幸运的是,这个 stackoverflow 答案解决了它。更新vue.config.js文件以包含devServer选项(确保它位于导出对象的顶层:

devServer: {
  historyApiFallback: {
    rewrites: [
      { from: /\/index/, to: '/index.html' },
      { from: /\/experiment/, to: '/experiment.html' }
    ]
  }
}

然后还修改router.ts文件以附加额外的路径(在我的情况下为“experiment/”:

export default new Router({
  mode: 'history',
  base: process.env.BASE_URL + 'experiment/',
  ...

然后 URL 解析得很好,例如:http://localhost:8080/experiment/about

在我看来,不,它是一个开发服务器,旨在使开发变得容易,而不是用于生产用途。Webpack 产生了很好的精益输出,可以在生产中作为一组静态文件提供,例如云前端、nginx 等。这并没有回答如何提供 api,但这完全是另一个问题。
2021-04-28 11:38:47
是的,这是正确的,IMO 应该如何。听起来您对那里的某些事情感到担忧。如果是这样,我建议提出一个新的完整问题,并且可以正确解决该问题。
2021-05-06 11:38:47
你的意思是,当你建立它督促,CLI会创建dist/index.htmldist/experiment/index.html等,每个index.html是它自己的SPA?但它在 DEV 中不是这样工作的。
2021-05-07 11:38:47
devServer重写 URL 以使其看起来更好的选项是否意味着在生产中使用?
2021-05-17 11:38:47
是否有可能利用pagesvue.config.js的也产生不同的版本css/img/以及js/目录的每一页?
2021-05-21 11:38:47

这可能与问题无关,但请耐心等待,也许我的回答可以帮助某人。 我用的是webpack+vue,我已经弄清楚了如何构建多页面应用程序这是我的 webpack.config.js:

const path = require('path');
const fs = require('fs')
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");

module.exports = {
    entry: {
        app: './src/app.js',
        mgmt: ['./src/modules/mgmt/mgmt.js'],
        login: './src/modules/login/login.js'
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        // publicPath: '/ahezime/',
        filename: (chunkData) => {
            console.log('chuckData.chunk.name => ', chunkData.chunk.name)
            return chunkData.chunk.name === 'app' ? './[name].bundle.js' : './[name]/[name].bundle.js';
        }
    },
    optimization: {
        minimizer: [
            new TerserPlugin(),
            new OptimizeCSSAssetsPlugin({})
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "[name].css",
            chunkFilename: "[id].css"
        }),
        new CleanWebpackPlugin(['dist']),
        new VueLoaderPlugin(),
        new HtmlWebpackPlugin({
            title: 'app',
            template: './src/app.html',
            // inject: false,
            chunks: ['app'],
            filename: './index.html'
        }),
        new HtmlWebpackPlugin({
            title: 'mgmt',
            template: './src/modules/mgmt/mgmt.html',
            // inject: false,
            chunks: ['mgmt'],
            filename: './mgmt/index.html'
        }),
        new HtmlWebpackPlugin({
            title: 'login',
            template: './src/modules/login/login.html',
            // inject: false,
            chunks: ['login'],
            filename: './login/index.html'
        })
    ],
    module: {
        rules: [
            {
                test: /\.m?js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env'],
                        plugins: ['@babel/plugin-proposal-object-rest-spread']
                    }
                }
            }
        ],
        rules: [
            {
                test: /\.vue$/,
                exclude: /node_modules/,
                loader: 'vue-loader'
            },
            {
                test: /\.css$/,
                use: [
                    'vue-style-loader',
                    'style-loader',
                    'css-loader',
                    'sass-loader'
                ]
            },
            {
                test: /\.scss?$/,
                use: ['style-loader', 'css-loader', 'sass-loader']
            },
            {
                test: /\.(png|svg|jpg|gif)$/,
                use: [
                    'file-loader'
                ]
            },
            {
                test: /\.(woff|woff2|eot|ttf|otf)$/,
                use: [
                    'file-loader'
                ]
            }
        ]
    }
};

这是我的目录结构:

https://i.stack.imgur.com/uFvKx.png

你可以跳转页面:

<template>
    <div>
        <h1>App</h1>
        <div>
            <a href="./login">Please click me, and let take you into the login page!!!</a>
        </div>
        <span>Before computed: {{ message }} </span>
        <br>
        <span>Afer computed: {{ computedMessage() }} </span>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                message: 'Hello World!'
            }
        },
        computed: {
            reversedMessage: function() {
                return this.message.split('').reverse().join('')
            }
        },
        methods: {
            computedMessage: function() {
                return this.message.split('').reverse().join('')
            }
        }
    }
</script>
观众请注意,我还没有尝试过您的解决方案,但请注意。这是针对3.x之前的Vue CLI ,Vue CLI 3 为您的 Vue 项目提供配置,更多信息可以从cli.vuejs.org/config/#pages上的官方文档中查看
2021-04-23 11:38:47

注意将用户指向什么应该是可接受的答案
在发布我的初始答案时,我不知道在 VueJS 中实际构建 MPA 的可能性。我的回答没有解决所提出的问题,因此我建议看一下 PJ.Wanderson 提供的答案,这应该是公认的答案

初始答案
Vue.js 项目是 SPA(单页应用程序)。.html在整个项目中只有一个文件,即index.html您提到文件。您要创建的“页面”,在 vue.js 中被称为组件。它们将插入index.html文件并在浏览器中呈现。一个 vue.js 组件包括 3 部分:

<template>

</template>

<script>
export default {

}
</script>

<style>

</style>
  • 模板:它包含您的页面应显示的所有 html(这是您放置页面 html 的位置)
  • 脚本:它包含将在页面/组件上执行的所有 JavaScript 代码
  • 样式:它包含将设置特定组件/页面样式的 CSS

您可以查看本教程以获取Vue.js 2 快速入门教程 2017 的快速入门

它解释了 vue.js 项目结构以及各种文件如何相互关联

只是在@avizzzy 所说的基础上添加更多内容,这实际上甚至不是一个有效的答案。 It's not entirely correct不是正确的词。这应该是一个错误的答案。 这个答案甚至不应该作为解决方案。如果您有兴趣使用 Vue 创建多页面应用程序 (MPA),您可以使用 Vue CLI 3 开始,它是 Vue 本身内置的。有关更多信息,请查看cli.vuejs.org/config/#pages 上的官方文档
2021-04-22 11:38:47
抱歉刚刚更新,当时@hippolyte 编辑了这个(8 月 8 日,18 日),Vue CLI 3 刚刚于 18 年 8 月 10 日发布,所以我猜这个答案并不完全错误。但由于我是新人,几乎没有接触过 3.x 之前的那个版本,所以我不能对之前的版本说太多。只是注意到其他人这个答案已经过时了..@Silverster 有我刚刚测试过的@PJ.Wanderson 的正确答案Vue CLI 3.4.0
2021-04-27 11:38:47
这并不完全正确。您可以使用 Vue Cli 创建 MPA。这就是你有页面的目的。
2021-05-02 11:38:47
我同意irfandyavizzzy他们虽不是如何做到这一点除了Vue公司3文档截至目前足够的文档。
2021-05-14 11:38:47