kudy
kudy

Reputation: 51

When express and vue js are connected, the default address is accessed

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

enter image description here

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

Answers (1)

Jack Yu
Jack Yu

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.

Express Router Flow

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.

Vue.js Router Flow

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.

Sum Up

When request is coming ...

  1. express decide the content by your rule.
    • Not Matched: express give you not found page.
    • Matched: express give you content by your rule
  2. When request matched, it give you html (at above example).
    • bowser render the html
    • html include the build.js
    • build.js render the content of vue
  3. When you click vue-router link go to other page
    There is no real request sent by browser.
    It's controlled by your build.js.
  4. When you type url in browser, then push enter bottom.
    It goes to step1.

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.

Example

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

Related Questions