Vue.js CLI 中的多个页面
multiple pages in Vue.js CLI
我无法弄清楚如何在 Vue CLI 项目中拥有多个页面。现在我的主页有一些组件,我想创建另一个页面,但我不知道该怎么做。我是否应该在默认情况下 index.html 所在的位置创建多个 html 文件?在以 css js img 文件夹和 html 文件作为页面的简单文件结构中,我知道创建另一个 html 文件意味着制作另一个页面。但是我不明白这是如何与 Vue CLI 项目一起工作的。
我在 Vue 文档中看到了 vue-router 和 "pages" 之类的东西,但我不太了解它们。我有什么选择?有没有详细解释的指南,因为我找不到,更不用说详细了。如果您能提供帮助,将非常高兴!谢谢!
请注意将用户指向应该被接受的答案
在发布我的初始答案时,我并不知道在 VueJS 中实际构建 MPA 的可能性。我的回答没有解决所问的问题,因此我建议看看下面 PJ.Wanderson 提供的答案, 应该是公认的答案
初始答案
Vue.js 项目是 SPA(单页应用程序)。你整个工程只有一个.html
文件,就是你说的index.html
文件。您要创建的 "pages",在 vue.js 中称为组件。它们将被插入 index.html
文件并在浏览器中呈现。 vue.js 组件包含 3 个部分:
<template>
</template>
<script>
export default {
}
</script>
<style>
</style>
- 模板:它包含您的页面应显示的所有 html(这是放置页面 html 的位置)
- 脚本:它包含将在 page/component
上执行的所有 JavaScript 代码
- 样式:它包含 CSS 将设置特定 component/page
的样式
您可以查看本教程以快速入门Vue.js 2 Quickstart Tutorial 2017
它解释了 vue.js 项目结构以及各种文件如何相互关联
第一:始终阅读官方文档。使用 Vue 你可以构建一个 SPA,一个 MPA 也没有问题。只需按照指南操作即可:
- https://cli.vuejs.org/
- https://cli.vuejs.org/guide/html-and-static-assets.html#building-a-multi-page-app
- https://cli.vuejs.org/config/#pages
您应该使用 Vue CLI 3 创建一个新项目。创建项目后,将其设置为手动配置。确保您不选择 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/#pages
下面,我用三张图片展示了这一点:
- 第一:全新的应用程序
- 第二个:同一个应用程序,我在上面进行了更改
- 第三个:来自此应用的 vue.config.js
您不需要创建pages
文件夹,这只是为了理解。
Link 到 GitHub:Building a MPA App
编辑:Vue 内置了这个。跳到底部了解更多。
原回答:
有两种方法可以解释您的问题,从而回答您的问题。
第一种解读为:"how can I support routing to different pages within the same single-page app, e.g. localhost:8080/about and localhost:8080/report etc?"。答案是使用路由器。它相当简单并且运行良好。
第二种解释是:"my app is complex, and I have multiple single-page applications, e.g. one app for the 'website' part, one app for consumers to log in and do work, one app for admins, etc - how can vue do this, without making three entirely separate repositories?"
后者的答案是具有多个单页应用程序的单个存储库。这个演示看起来正是您所追求的:
https://github.com/Plortinus/vue-multiple-pages/
具体看:https://github.com/Plortinus/vue-multiple-pages/blob/master/vue.config.js
更新的答案:
原来vuejs内置了多个顶级页面的思想。我的意思是,这是有道理的 - 尽管关于 "no, it's for single page apps"!
有很多不正确的答案,但它会非常普遍
您想要 vue.config.js
文件中的 pages
选项:
https://cli.vuejs.org/config/#pages
如果您的项目在根目录中没有该文件,请创建它,vuejs 会发现它。
定义每个页面有长有短。我在这里使用了缩写形式:
module.exports = {
pages: {
index: 'src/pages/index/main.ts',
experiment: 'src/pages/experiment/main.ts'
}
}
您不必将您的工作放在 "pages" 下。它可以是“/src/apps/index/index.ts”或其他任何东西。
移动代码并更改一些导入后:
import HelloWorld from './components/HelloWorld'
至
import HelloWorld from '@/components/HelloWorld'
该应用程序可以运行 - 但我的存储库中的 "experiment" 应用程序必须像这样加载:
http://localhost:8080/experiment.html
非常丑陋,甚至更糟,因为它使用导致 URL 的路由器:
http://localhost:8080/experiment.html/about
呃
幸好解决了。更新 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+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>
我无法弄清楚如何在 Vue CLI 项目中拥有多个页面。现在我的主页有一些组件,我想创建另一个页面,但我不知道该怎么做。我是否应该在默认情况下 index.html 所在的位置创建多个 html 文件?在以 css js img 文件夹和 html 文件作为页面的简单文件结构中,我知道创建另一个 html 文件意味着制作另一个页面。但是我不明白这是如何与 Vue CLI 项目一起工作的。
我在 Vue 文档中看到了 vue-router 和 "pages" 之类的东西,但我不太了解它们。我有什么选择?有没有详细解释的指南,因为我找不到,更不用说详细了。如果您能提供帮助,将非常高兴!谢谢!
请注意将用户指向应该被接受的答案
在发布我的初始答案时,我并不知道在 VueJS 中实际构建 MPA 的可能性。我的回答没有解决所问的问题,因此我建议看看下面 PJ.Wanderson 提供的答案, 应该是公认的答案
初始答案
Vue.js 项目是 SPA(单页应用程序)。你整个工程只有一个.html
文件,就是你说的index.html
文件。您要创建的 "pages",在 vue.js 中称为组件。它们将被插入 index.html
文件并在浏览器中呈现。 vue.js 组件包含 3 个部分:
<template>
</template>
<script>
export default {
}
</script>
<style>
</style>
- 模板:它包含您的页面应显示的所有 html(这是放置页面 html 的位置)
- 脚本:它包含将在 page/component 上执行的所有 JavaScript 代码
- 样式:它包含 CSS 将设置特定 component/page 的样式
您可以查看本教程以快速入门Vue.js 2 Quickstart Tutorial 2017
它解释了 vue.js 项目结构以及各种文件如何相互关联
第一:始终阅读官方文档。使用 Vue 你可以构建一个 SPA,一个 MPA 也没有问题。只需按照指南操作即可:
- https://cli.vuejs.org/
- https://cli.vuejs.org/guide/html-and-static-assets.html#building-a-multi-page-app
- https://cli.vuejs.org/config/#pages
您应该使用 Vue CLI 3 创建一个新项目。创建项目后,将其设置为手动配置。确保您不选择 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/#pages
下面,我用三张图片展示了这一点:
- 第一:全新的应用程序
- 第二个:同一个应用程序,我在上面进行了更改
- 第三个:来自此应用的 vue.config.js
您不需要创建pages
文件夹,这只是为了理解。
Link 到 GitHub:Building a MPA App
编辑:Vue 内置了这个。跳到底部了解更多。
原回答:
有两种方法可以解释您的问题,从而回答您的问题。
第一种解读为:"how can I support routing to different pages within the same single-page app, e.g. localhost:8080/about and localhost:8080/report etc?"。答案是使用路由器。它相当简单并且运行良好。
第二种解释是:"my app is complex, and I have multiple single-page applications, e.g. one app for the 'website' part, one app for consumers to log in and do work, one app for admins, etc - how can vue do this, without making three entirely separate repositories?"
后者的答案是具有多个单页应用程序的单个存储库。这个演示看起来正是您所追求的:
https://github.com/Plortinus/vue-multiple-pages/
具体看:https://github.com/Plortinus/vue-multiple-pages/blob/master/vue.config.js
更新的答案:
原来vuejs内置了多个顶级页面的思想。我的意思是,这是有道理的 - 尽管关于 "no, it's for single page apps"!
有很多不正确的答案,但它会非常普遍您想要 vue.config.js
文件中的 pages
选项:
https://cli.vuejs.org/config/#pages
如果您的项目在根目录中没有该文件,请创建它,vuejs 会发现它。
定义每个页面有长有短。我在这里使用了缩写形式:
module.exports = {
pages: {
index: 'src/pages/index/main.ts',
experiment: 'src/pages/experiment/main.ts'
}
}
您不必将您的工作放在 "pages" 下。它可以是“/src/apps/index/index.ts”或其他任何东西。
移动代码并更改一些导入后:
import HelloWorld from './components/HelloWorld'
至
import HelloWorld from '@/components/HelloWorld'
该应用程序可以运行 - 但我的存储库中的 "experiment" 应用程序必须像这样加载:
http://localhost:8080/experiment.html
非常丑陋,甚至更糟,因为它使用导致 URL 的路由器:
http://localhost:8080/experiment.html/about
呃
幸好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+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>