首页 📚生活杂谈

用hello world案例开发与部署流程

一,egg.js后端

1,创建数据库

image-20211013172259378

2,创建Egg项目和Vue项目

npm init egg --type=simple
npm install
egg插件
npm install --save egg-view-nunjucks
npm install --save egg-cors
npm install --save egg-sequelize msyql2
npm install --save egg-jwt
vue安装
vue create 项目名
npm install
npm i element-ui -S
npm i axios -S

Egg目录

image-20211013173722185

3,编写配置文件

image-20211013174933783

serveconfigconfig.default.js

/* eslint valid-jsdoc: "off" */
const fs = require('fs');
const path = require('path');

('use strict');

/**
 * @param {Egg.EggAppInfo} appInfo app info
 */
module.exports = (appInfo) => {
  /**
   * built-in config
   * @type {Egg.EggAppConfig}
   **/
  const config = (exports = {});

  // use for cookie sign key, should change to your own and keep security
  config.keys = appInfo.name + '_1569042874002_5024';

  // add your middleware config here
  config.middleware = [];

  // add your user config here
  const userConfig = {
    // myAppName: 'egg',
  };

  config.jwt = {
    secret: 'lavine',
  };
  config.sequelize = {
    dialect: 'mysql',
    database: 'helloworld',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: 'admin',
    timezone: '+08:00',
  };

  //设置上传文件
  config.multipart = {
    fileSize: 300 * 1000 * 1000, //设置上传限制为300M
  };

  config.security = {
    csrf: {
      enable: false, // 前后端分离,post请求不方便携带_csrf
    },
    domainWhiteList: ['*'], //配置白名单
  };

  config.cors = {
    origin: '*', //允许所有跨域访问,注释掉则允许上面 白名单 访问
    credentials: true, // 允许跨域请求携带cookies
    allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH',
  };

  config.view = {
    defaultViewEngine: 'nunjucks',
  };
  //设置静态文件目录
  config.static = {
    prefix: '/', //访问路径
    dir: path.join(appInfo.baseDir, 'app/public'), //设置静态文件目录
  };

  return {
    ...config,
    ...userConfig,
  };
};

serveconfigplugin.js

'use strict';

/** @type Egg.EggPlugin */
module.exports = {
  // had enabled by egg
  // static: {
  //   enable: true,
  // }
  sequelize: {
    enable: true,
    package: 'egg-sequelize',
  },
  cors: {
    enable: true,
    package: 'egg-cors',
  },
  jwt: {
    enable: true,
    package: 'egg-jwt',
  },
  nunjucks: {
    enable: true,
    package: 'egg-view-nunjucks',
  },
};

3,编写数据模型

MySQL数据类型与sequelize数据类型对应如下

1. STRING => varchar(255)

2. INTEGER => int

3. DOUBLE => double

4. DATE => datetime

5. TEXT => text

4, 在app/model目录中创建hello.js文件,对应数据库中的hello表

module.exports = (app) => {
  const { STRING } = app.Sequelize;
  const Hello = app.model.define('Hello', {
    msg: STRING,
  });
  return Hello;
};

5, 在项目根目录中创建app.js文件,初始化数据库

module.exports = app => {
    app.beforeStart(async function() {
        // await app.model.sync({ force: true }); // 开发环境使用,会删除数据表
        await app.model.sync({});
    });
};

6, 在app/service目录中创建hello.js文件,获取hello表数据

const Service = require('egg').Service;
class HelloService extends Service {
  async getMessage() {
    try {
      return await this.app.model.Hello.findAll();
    } catch (error) {
      return null;
    }
  }
}
module.exports = HelloService;

7, 在app/controller目录中创建hello.js文件,渲染hello表数据

const Controller = require('egg').Controller;

class HelloController extends Controller {
  async index() {
    let result = await this.ctx.service.hello.getMessage();
    if (result) {
      this.ctx.body = {
        code: 200,
        data: result,
      };
    } else {
      this.ctx.body = {
        code: 500,
        data: '请联系管理员',
      };
    }
  }
}

module.exports = HelloController;

8,在app/middleware目录checktoken.js验证token(创建中间件,每次登录判断是否携带token)

function checktoken() {
  return async function (ctx, next) {
    // 验证token
    try {
      let token = ctx.header.token;
      ctx.app.jwt.verify(token, ctx.app.config.secret);
      await next();
    } catch (error) {
      ctx.body = {
        code: 400,
        msg: 'token验证失败',
      };
    }
  };
}
module.exports = checktoken;

9,在app目录中编写router.js文件

'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = (app) => {
  const { router, controller } = app;
  router.get('/', controller.home.index);
  router.get('/hello', app.middleware.checktoken(), controller.hello.index);
  router.post('/login', controller.login.login);
};

二,vue.js前端

vue目录

image-20211013173748530

创建 .env.development和.env.production

VUE_APP_BASE_AP1="http://127.0.0.1:7001"
为了重复添加接口地址,将接口赋值到VUE_APP_BASE_AP1

封装aixos

这样就不用每次重复编写,减少代码量,有利于维护

hellosrcutilsrequest.js

// 封装一个axios
import axios from "axios";
const request = axios.create({
  baseURL: process.env.VUE_APP_BASE_AP1
});
// 拦截器
request.interceptors.request.use(req => {
  // 拿到token
  let token = localStorage.getItem("token");
  //如果拿到token,每次带着token,如果没有返回req
  if (token) {
    req.headers.token = token;
  }
  return req;
});
//抛出request
export default request;

1,编写登录页

hellosrcviewsHome.vue

每次登录,添加token

<template>
  <div>
    <h1>登录</h1>
    <form @submit.prevent="login">
      <input type="text" v-model="username" />
      <button>登录</button>
    </form>
  </div>
</template>

<script>
import request from "../utils/request";
export default {
  data() {
    return {
      username: ""
    };
  },
  methods: {
    // 跨域请求拿到表单输入的username
    login() {
      request
        .post(`/login`, {
          username: this.username
        })
        .then(res => {
          if (res.data.code === 200) {
            // 输出token
            console.log(res.data.token);
            // 把token存放到localStorage
            localStorage.setItem("token", res.data.token);
            // 跳转到首页
            this.$router.push("/");
          }
        });
    }
  }
};
</script>

<style></style>

image-20211013182310646

2,编写注销页

hellosrcviewsLogin.vue

每次注销,清除token

<template>
  <div>
    <h1>我的网站:{{ msg }}</h1>
    <button @click="logout">注销</button>
  </div>
</template>

<script>
import request from "../utils/request";
export default {
  data() {
    return {
      msg: ""
    };
  },
  methods: {
    logout() {
      localStorage.setItem("token", "");
      location.reload();
    },
    getMsg() {
      // 获取token
      // let token = localStorage.getItem("token");
      // 请求携带token
      request.get(`/hello`).then(({ data: res }) => {//解构赋值
        console.log(res.data);
        this.msg = res.data[0].msg;
      });
    }
  },
  created() {
    this.getMsg();
  }
};
</script>

<style></style>

image-20211013182522867

3,编写路由首位

hellosrcrouterindex.js

判断用户每次访问首页是否,携带token,防止直接访问到首页

import Vue from "vue";
import VueRouter from "vue-router";
import Home from "../views/Home.vue";

Vue.use(VueRouter);

const routes = [
  {
    path: "/",
    name: "Home",
    component: Home
  },
  {
    path: "/login",
    name: "Login",
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () =>
      import(/* webpackChunkName: "about" */ "../views/Login.vue")
  }
];

const router = new VueRouter({
  base: process.env.BASE_URL,
  routes
});
// 路由守卫
router.beforeEach((to, from, next) => {
  // 如果目标页面是登录页,直接跳转
  if (to.path === "/login") {
    next();
  } else {
    // 获取token
    let token = localStorage.getItem("token");
    if (token) {
      // 如果有正常跳转
      next();
    } else {
      // 如果没有重定向到登陆页面
      next("/login");
    }
  }
});
export default router;

三,打包发布

到前端目录下运行

npm run build

image-20211013183022617

生成dist文件 ,

image-20211013183212208

将dist里边的文件,添加到egg项目,中的public文件夹下

image-20211013183521996

访问egg服务器http://127.0.0.1:7001/index.html

可以看到访问7001,看到前端页面,这样就部署成功了

1GIF

真正项目开发中

将server上传到服务器,前端就是为了生成一个dist文件

image-20211013184319422

开发时用:npm run dev 启动egg服务器




文章评论

目录