代码之家  ›  专栏  ›  技术社区  ›  Martin Zahariev

Vue.js CLI中的多个页面

  •  8
  • Martin Zahariev  · 技术社区  · 6 年前

    我很难弄清楚如何在一个Vue CLI项目中拥有多个页面。现在我的主页有一些组件,我想创建另一个页面,但我不知道如何做到这一点。我应该在index.html默认为的地方创建多个html文件吗?在一个简单的文件结构中,css js img文件夹和html文件作为页面,我知道创建另一个html文件意味着创建另一个页面。但我不明白这是如何与Vue CLI项目一起工作的。

    我在vue文档中看到了诸如vue router和“pages”之类的东西,但我不太了解它们。我的选择是什么?有没有一本指南详细解释了这一点,因为我找不到,更不用说详细了。如果你能帮忙,我会很高兴的!谢谢您!

    4 回复  |  直到 6 年前
        1
  •  -7
  •   Hippolyte Fayol    5 年前

    提示用户应该接受的答案
    在发布我最初的答案时,我并不知道在VueJS中实际构建MPA的可能性。我的回答并没有回答你提出的问题,因此我建议你看看PJ.Wanderson bellow提供的答案 应该是公认的答案

    初始答案
    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 Quickstart Tutorial 2017

    它解释了vue.js项目结构以及各种文件之间的关系

        2
  •  42
  •   PJ.Wanderson    5 年前

    第一:务必阅读官方文件。有了Vue,你也可以建一个SPA:一个MPA没问题。只需遵循指南:

    使用Vue CLI 3,可以使用Vue create you project创建新项目,并将其设置为手动配置。那么,不要选择SPA选项。Vue将使用MPA方法创建一个很好的“开始”项目。之后,只需在vue.config.js上重复配置。


    更新#1

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

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

    创建的样板,将是一个SPA之一。但是,做些改变:

    • 在下面创建文件夹 src 命名的 pages (可选)

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

    • 从src复制App.vue和main.js并粘贴到新文件夹-Home等。
    • 格式化 App.vue 在这个文件夹里
    • 创建一个vue.config.js并按如下方式设置: https://cli.vuejs.org/config/#页面

    下面,我有三张图片展示了这一点:

    • 第一个:一个新的应用程序
    • 第二个:这个应用程序,上面我做了一些修改
    • 第三个:这个应用程序中的vue.config.js

    fresh new app this same app, with the changes I made above the vue.config.js from this app

    你不需要创建 文件夹,你就知道了。

    链接到GitHub: Building a MPA App

        3
  •  9
  •   Andrew E    5 年前

    编辑 :Vue具有此内置功能。跳到底部查看更多信息。

    原始答案:

    有两种方法来解释你的问题,并因此来回答它。

    第一种解释是:“如何支持在同一个单页应用程序中路由到不同页面,例如localhost:8080/about和localhost:8080/report etc?”。答案是使用路由器。它相当简单,而且效果很好。

    第二种解释是:“我的应用程序很复杂,我有 多个单页应用程序 ,例如,一个应用程序用于“网站”部分,一个应用程序用于消费者登录和工作,一个应用程序用于管理员,等等—在不创建三个完全独立的存储库的情况下,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'
    

    应用程序可以工作-但是我的repo中的“实验”应用程序必须这样加载:

    http://localhost:8080/experiment.html
    

    相当难看,甚至更糟,因为它使用路由器,导致如下网址:

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

    呃。

    幸运的是, this stackoverflow answer 解决了。更新 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

        4
  •  0
  •   Ray's Life Thinking    5 年前

    这可能与问题无关,但请容忍我,也许我的回答可以帮助某人。 我使用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>
    
        5
  •  0
  •   user3873617    5 年前

    一个简单的解决方案

    1. 更新后端服务器以获取和/或发布
    2. AXIOS .GET/POST(TothTeHyURL)
    3. 返回html(如烧瓶中的呈现模板)
    4. 您可以从response.request.responseURL中提取url
    5. 现在设置window.location.ref=response.request.responseURL
    推荐文章