用node建立web服务(九)连通前后端数据

作者: 自然框架 | 来源:发表于2021-07-19 14:35 被阅读0次

    技术栈

    • Vue3
    • axios
    • Node.js 14.0
    • MySQL 8.0

    前端

    前端做一个简单的页面即可,主要是实现基础的数据访问的功能。

    <template>
      <div>
        测试后端API
        <el-input-number v-model="id" placeholder="" @input="sendGetOne"></el-input-number>
        <el-input v-model="aa.name" placeholder="姓名"></el-input>
        <el-input v-model="aa.age" placeholder="年龄"></el-input>
        <el-button type="" @click="sendAdd">添加数据</el-button>
        <el-button type="" @click="sendUpdate">修改数据</el-button>
        <el-button type="" @click="sendDelete">删除数据</el-button>
        <el-button type="" @click="sendGetOne">获取数据</el-button>
        <el-button type="" @click="sendGetAll">获取全部数据</el-button>
        <br>
        启用查询:<el-switch v-model="useQuery"></el-switch><br>
        <el-pagination
          background
          layout="prev, pager, next"
          v-model:currentPage="pager.pagerIndex"
          :page-size="pager.pagerSize"
          :total="pager.pagerTotal">
        </el-pagination>
        <div v-for="(item, index) in dataList" :key="index">
          {{item}}
        </div>
        <el-button type="" @click="find(100)">查找</el-button>
        {{array}}
      </div>
    </template>
    

    只是简单的测试,就不用做复杂的UI了。

    import { reactive, ref, watch } from 'vue'
    import axios from 'axios'
    
    // 记录ID
    const id = ref(98)
    
    const array = ref([])
    const find = (n) => {
      array.value = find1(parseInt(id.value))
    }
    
    // 是否使用查询条件
    const useQuery = ref(false)
    
    // 分页信息
    const pager = reactive({
      pagerIndex: 1,
      pagerSize: 20,
      pagerTotal: 100
    })
    
    // model
    const aa = reactive({
      name: 'jyk',
      age: 18
    })
    
    // 数据列表
    const dataList = reactive([])
    
    // 添加
    const sendAdd = () => {
      axios.post('/api/100/10', aa).then((re) => {
        console.log('添加完成,新ID:', re)
      })
    }
    
    // 修改
    const sendUpdate = () => {
      axios.post(`/api/100/20/${id.value}`, aa).then((re) => {
        console.log('修改完成,影响行数:', re)
      })
    }
    // 删除
    const sendDelete = () => {
      axios.get(`/api/100/30/${id.value}`).then((re) => {
        console.log('删除完成,影响行数:', re)
      })
    }
    // 获取一条记录
    const sendGetOne = () => {
      axios.get(`/api/100/40/${id.value}`).then((re) => {
        console.log('获取记录:', re)
        Object.assign(aa, re.data.model[0])
      })
    }
    // 获取全部数据
    const sendGetAll = () => {
      const query = {}
      if (useQuery.value) {
        if (aa.name.length > 0) query.name = [403, aa.name]
        if (aa.age.length > 0) query.age = [415, aa.age]
      }
      axios.post(`/api/100/60/${id.value}`, query).then((re) => {
        console.log('获取记录:', re)
        dataList.length = 0
        dataList.push(...re.data.list)
      })
    }
    
    // 分页
    watch(() => pager.pagerIndex, (v) => {
      console.log(v)
      const info = {
        pager: pager,
        query: {},
        useCount: false
      }
      if (v === 1) info.useCount = true
    
      if (useQuery.value) {
        if (aa.name.length > 0) info.query.name = [403, aa.name]
        if (aa.age.length > 0) info.query.age = [415, aa.age]
      }
      axios.post('/api/100/50', info).then((re) => {
        console.log('获取记录:', re)
        // 设置总记录数
        pager.pagerTotal = re.data.pager.pagerTotal
        pager.pagerSize = re.data.pager.pagerSize
        dataList.length = 0
        dataList.push(...re.data.list)
      })
    })
    
    

    主要还是axios的使用,这里只用了get和post,没有使用其他的动作,感觉用不上。

    简单的页面

    话说,好像还可以封装一下。

    后端

    建立服务,提供API接口。

    // 引入服务
    const http = require('http')
    
    // 获取上传的body
    const getBody = (req) => {
      return new Promise((resolve, reject) => {
        let body = ''
        req.on('data', chunk => {
          body += chunk
        })
        req.on('end', () => {
          // 输出body,转换成对象
          try {
            if (body === '') {
              resolve({})
            } else {
              const obj = JSON.parse(body)
              resolve(obj)
            }
          } catch {
            reject({
              msg: 'json格式不正确!',
              body
            })
          }
        })
      })
    }
    
    http.createServer((req, res) => {
      // 设置响应头
      res.writeHeader(200, {
        "Content-Type" : "application/json"
      })
      // 输出开头
      // res.write('{"code":"200" ')
      
      // 解构获取 URL、请求方法和头部对象
      const { url, method, headers } = req
      console.log('\n有访问者', url, method)
      
      // 请求体
      getBody(req).then(body => {
        // 需要转换成对象。
        console.log('\n获取body', body)
        const userInfo = {
          userId: 1,
          name: 'jyk',
          roles: []
        } // 先占个坑
    
        // 判断url,加载对应的服务
        const arr = url.split('/')
        if (arr.length >= 4) {
          // 符合 /api/moduleId/actionId/dataid 的形式
          const moduleId = arr[2]
          const actionId = arr[3]
          const dataId = arr.length > 2 ? arr[4]: ''
          switch (arr[1]) {
            case 'api': // 加载服务
              const servers = require('./src/services/index.js')
              servers(userInfo, moduleId, actionId, dataId, body).then((data) => {
                const re = {
                  code: 200
                }
                Object.assign(re, data)
                res.write(JSON.stringify(re, null, 2))
                res.end()
              })
            break
          }
        }
      }).catch(err => {
        console.log(err.msg, err.body)
        const re = {
          code: 600 // 出错了用啥编号
        }
        res.write(JSON.stringify(re, null, 2))
        res.end()
      })
    })
    // 设置监听端口为 6000
    .listen(6000, () => {
      console.log('服务已经开启:http://localhost:6000')
    })
    
    

    然后要调用对应的js进行解析,具体的就不写了,前面的好像介绍了。

    文件结构

    设计一个简单的表

    测试嘛,做一个简单的表就好,比如这样:

    测试表

    这样前后端,带上数据库,就完全贯通起来了。

    测试数据

    源码

    https://gitee.com/naturefw/node-services

    相关文章

      网友评论

        本文标题:用node建立web服务(九)连通前后端数据

        本文链接:https://www.haomeiwen.com/subject/kgzcmltx.html