60

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

我在 Vue 文档中看到了诸如 vue-router 和“页面”之类的东西,但我不太了解它们。我的替代方案是什么?有没有详细解释的指南,因为我找不到任何东西,更不用说详细了。如果您能提供帮助将非常高兴!谢谢!

4

4 回答 4

118

第一:始终阅读官方文档。使用 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 应用程序

于 2018-09-27T11:56:02.333 回答
20

编辑: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

于 2018-12-19T11:02:33.007 回答
2

这可能与问题无关,但请耐心等待,也许我的回答可以帮助某人。 我使用 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>
于 2019-01-29T16:06:45.503 回答
-9

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

Inital Answer
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 项目结构以及各种文件如何相互关联

于 2018-08-05T08:56:16.973 回答