Koa2 + Vue 初始化

koa-generator 初始化(npm i yarn -g)

npm i koa-generator -g

koa2 -e demo

cd demo

yarn

yarn run dev

 .html 渲染页面

/app.js

app.use(views(__dirname + '/views', { map: { html: 'ejs' } }))

公共头部、页底

新建 /views/header.html ( 并引入 vue, vue-router, axios, elementUi )
<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/style/style.css' />
    <link rel="stylesheet" href="/style/element.css">

    <script src="/js/vue.js"></script>
    <script src="/js/vue-router.js"></script>
    <script src="/js/axios.min.js"></script>
    <script src="/js/element.js"></script>
  </head>
  <body>
新建 /views/footer.html
</body>
</html>

/views/index.html 复用页头、页尾

<% include header.html %>

<div id="app">
  <router-view></router-view>
</div>

<script>
  // 配置单页路由
  const router = new VueRouter({
    mode: 'hash',
    routes: [
      { path: '/course', component: <% include ./layout/course.html %> },
      { path: '/detail', component: <% include ./layout/detail.html %> }
    ]
  })

  const app = new Vue({
    name: 'app',
    router,
    data() {
      return {
        title: '<%- title %>'
      }
    },
    created() {
      this.$router.push({ path: '/course' })
    },
    methods: {
      list() {
        axios.post('/list', { page: 1, limit: 10 })
          .then(res => res.data)
          .catch(err => console.log(err))
      },
      detail() {
        axios.get('/detail', { params: { id: 1 } })
          .then(res => res.data)
          .catch(err => console.log(err))
      },
    }
  }).$mount('#app')
</script>
    
<% include footer.html %>

新建 /views/layout/course.html

Vue.component('course', {
  components: {
    divider: <% include ../component/divider.html %> // 自定义组件
  },
  data() {
    return {
      list: []
    }
  },
  created() {
    this.getList()
  },
  methods: {
    getList() {
      axios.post('/list', { page: 1, limit: 10 })
        .then(res => {
          this.list = res.data
        })
        .catch(err => console.log(err))
    },
    detail({ id }) {
      this.$router.push({ path: '/detail', query: { id } })
    },
  },
  template: `
    <div class="course">
      <divider title="人员信息"></divider>
      <el-table border stripe :data="list" style="width: 100%">
        <el-table-column prop="name" label="姓名"></el-table-column>
        <el-table-column prop="course" label="学科"></el-table-column>
        <el-table-column fixed="right" label="操作">
          <template slot-scope="scope">
            <el-button @click="detail(scope.row)" type="text" size="small">查看</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
  `
})

新建 /views/layout/detail.html

Vue.component('detail', {
  data() {
    return {
      id: this.$route.query.id,
      list: []
    }
  },
  created() {
    this.detail()
  },
  methods: {
    detail() {
      axios.get('/detail', { params: { id: this.id } })
        .then(res => {
          this.list = res.data
        })
        .catch(err => console.log(err))
    },
  },
  template: `
    <div class="detail">
      <el-table border stripe :data="list" style="width: 100%">
        <el-table-column prop="course" label="课程名称"></el-table-column>
      </el-table>
    </div>
  `
})

新建 /views/component/divider.html

Vue.component('divider', {
  props: ['title'],
  data() {
    return {

    }
  },
  template: `
    <div>
      <el-divider content-position="left">{{title}}(自定义组件)</el-divider>
    </div>
  `
})

mysql

yarn add mysql
新建 /utils/mysql.js
const mysql = require('mysql');

const pool = mysql.createPool({
  host: 'localhost',
  user: 'root',
  password: 'root',
  database: 'test',
  supportBigNumbers: true,
  bigNumberStrings: true
});

const exec = sql => {
  return new Promise((resolve, reject) => {
    pool.getConnection((error, connection) => {
        if (error) {
            reject('DB-获取数据库连接异常!')
        }
        connection.query(sql, (error, result) => {
            if (error) {
                reject('DB-执行查询语句异常!')
            }
            resolve(result)
        })
        connection.release(error => {
            if (error) {
                reject('DB-关闭数据库连接异常!')
            }
        })
    })
  })
}

module.exports = exec;

数据库交互

/routes/index.js
 
const router = require('koa-router')()
const exec = require('../utils/mysql');

router.get('/', async (ctx, next) => {
 // 页面渲染
  await ctx.render('index', {
    title: 'vueDemo'
  })
})

router.get('/detail', async (ctx, next) => {
  const { id } = ctx.query
  const sql = `select * from course where userId = ${id};`
  const list = await exec(sql)
  ctx.body = list
})

router.post('/list', async (ctx, next) => {
  const { page, limit } = ctx.request.body // POST 参数
  const sql = `select u.*, group_concat(c.course) as course from user u left join course c on c.userId = u.id group by u.id limit ${(page - 1) * limit}, ${limit};`
  const list = await exec(sql)
  ctx.body = list
})

module.exports = router

pm2

yarn global add pm2
新建 /pm2.conf.json
{
  "apps": {
    "name": "pm2-prd-server",
    "script": "./bin/www",
    "watch": true,
    "ignore_watch": [
      "node_modules",
      "logs"
    ],
    "instances": 2,
    "error_file": "logs/err.log",
    "out_file": "logs/out.log",
    "log_date_format": "YYYY-MM-DD HH:mm:ss",
    "autorestart": true
  }
}

pm2 运行配置

/package.json

{
  "scripts": {
    "prd": "pm2 start pm2.conf.json"
  }
}
npm run prd

 

目录

demo
├─ app.js
├─ bin
│  └─ www
├─ logs
│  ├─ err-1.log
│  └─ out-1.log
├─ package.json
├─ pm2.conf.json
├─ public
│  ├─ img
│  ├─ js
│  │  ├─ axios.min.js
│  │  ├─ element.js
│  │  └─ vue.js
│  └─ style
│     ├─ element.css
│     ├─ fonts
│     │  ├─ element-icons.eot
│     │  ├─ element-icons.svg
│     │  ├─ element-icons.ttf
│     │  ├─ element-icons.ttf.sfd
│     │  └─ element-icons.woff
│     └─ style.css
├─ routes
│  ├─ index.js
│  └─ users.js
├─ utils
│  └─ mysql.js
├─ views
│  ├─ components
│  │  └─ divider.html
│  ├─ layout
│  │  ├─ course.html
│  │  └─ detail.html
│  ├─ footer.html
│  ├─ header.html
│  └─ index.html
└─ yarn.lock

仓库

https://gitee.com/senjer/koa2-demo.git

常见问题

问题1:修改 pm2.conf.json 直接运行配置不生效? -- 需先 pm2 delete appName 再 npm run prd

posted @ 2021-03-03 15:15  _senjer  阅读(208)  评论(0)    收藏  举报