Reputation: 51
Express and vue.js are linked. I have set up a route and when I run Express, it will go to an address different from the vue setting.
Vue index router
import Vue from 'vue';
import Router from 'vue-router';
import Editor from '@/components/Editor';
Vue.use(Router);
export default new Router({
mode: 'history',
routes:[
{
path : '/board',
name : 'Editor',
component : Editor
}
]
})
Vue main.js
import Vue from 'vue';
import App from './App.vue';
import {router} from './routes/index.js';
import axios from 'axios';
import ElementUI from 'element-ui';
import { ElementTiptapPlugin } from 'element-tiptap';
import 'element-tiptap/lib/index.css';
Vue.use(ElementUI);
Vue.use(ElementTiptapPlugin, {
// lang: "zh",
// spellcheck: false,
});
Vue.config.productionTip = false;
Vue.prototype.$http = axios;
new Vue({
render: h => h(App),
router
}).$mount('#app');
Express index router
const express = require('express');
const router = express.Router();
const mssql = require('mssql');
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
index.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p>Index</p>
<a href='/board'> Go to Vue Page </a>
</body>
</html>
app.js
const createError = require('http-errors');
const fs = require('fs');
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const ejs = require('ejs');
const indexRouter = require('./routes/index');
const usersRouter = require('./routes/users');
const apiRouter = require('./routes/api');
const port = 8000; //changed port
app.use(express.static('public'));
app.use(express.static(path.join('node_modules', 'devexpress-richedit', 'dist', 'custom')));
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
// view engine setup
app.set('views', path.join(__dirname, '/views'));
app.set('view engine', 'ejs');
app.use(cors());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
// app.use(express.static(path.join(__dirname, '/public')));
app.use(express.static(path.join(__dirname, '/')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/api', apiRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`));
my project tree
Express is 8000 port Connect to'localhost: 8000 /'and Vue's page will appear.
I want express's page to appear when connecting to'localhost:8000/' And 'localhost:8000/board' doesn't work
I have one more question. How to call express's html file in Vue?
Thanks for your answer
Upvotes: 0
Views: 417
Reputation: 2425
We first need to know how the request flow works in whole express and vue.js.
In your project, you're not running express and vue with same port at the same time.
More clearly, you're using express with 8080 port to host vue.js content.
In express, your request match the rule app.get("/", (req, res)= >{res.render("index")})
then express will render the index page for you when you visit the http://localhost:{port}/
And after you add "other" word in your rule app.get("/other", (req, res)= >{res.render("other")})
express will render other page for you when you visit the http://localhost:{port}/other
What if request doesn't match rule?
Express will give you a not found page.
When you host the vue output js (we call build.js here) in express server instead of webpack-server.
In your vue project, you setup the vue-router with /
and /other-path
.
In these paths, vue will render content of /
and /other-page
.
We assume you use express to host the build.js
And we need the html to include this build.js with following code.
<!-- put this html in project_root/public/{here}-->
<div id="app"></div>
<script src="/build.js"><script>
And we setup the following code to host this html.
app.use("/", express.static(path.resolve(__dirname, "public")))
When we type http://localhost:{port}/
, express will give the index.html to browser.
Then you could use website, click link which is <router-link>
go to "other-page" which is provide by vue.
BUT, what if you type http://localhost:{port}/other-page
in the browser, then push enter button?
Express will give you not found page.
Because express will give you content when you first visit the website.
That means when a request is coming to express, express will give you content by your rule.
If rule doesn't match, express give you not found page.
If rule match, express give you content which you setup.
In the above example, express give you index.html because you setup app.use("/", express.static(path.resolve(__dirname, "public")))
.
Then you see the content of index.html in browser.
And then there is a build.js to render the content of vue for you.
But, there is no rule about "other-page" so express give you not found page.
When request is coming ...
So if your vue.js router and express router have same router path
your express will not give you the vue content when you type url in browser.
We assume your vue output which is called build.js
is located in project_root/public/{here}
.
There are two routes path "/" and "/vue-content" in your vue-router.
In your express router, you setup like this.
app.use("/", express.static(path.resolve(__dirname, "public")))
app.use("/express-page", (req, res) => {res.render("express-page")})
Then in webpack.config.js
output.publicPath: "/"
output.path: path.resolve(__dirname, "public")
And don't forget the you must have a index.html
in project_root/public
.
index.html
must have script tag including the build.js
Then try to put <a href="/express-page">go to express<a>
into your vue content.
Finally, go to http://localhost:8080/
, you will see html page which in public.
The build.js render the content for you.
After you click "go to express", browser send the request to express.
Express will render "express-page" for you instead of index.html page.
But, you will find express give you not found page after you type http://localhost:{port}/vue-router
in browser and push enter button.
So, how to fix it?
Add the new rule in the end.
app.use("/", express.static(path.resolve(__dirname, "public")))
app.use("/express-page", (req, res) => {res.render("express-page")})
app.use(express.static(path.resolve(__dirname, "public"))) // here
According our sum up step flow, express doesn't have "vue-router" rule.
But, there is a rule which match any request.
app.use(express.static(path.resolve(__dirname, "public")))
So, express will give you index.html
Then build.js will render "vue-router" content for you because vue will get the url to render content by vue-router setting.
Upvotes: 1