project
│ index.html
│ index.js
└─model
│ conf.js
└─db.js
数据库配置参数 conf.js
module.exports = {
// 数据库地址
url: 'mongodb://localhost:27017',
// 数据库名称
dbName: 'test'
}
数据库配置 db.js
const conf = require('./conf')
const EventEmitter = require('events').EventEmitter
// 客户端
const MongoClient = require('mongodb').MongoClient
class Mongodb {
constructor(conf) {
// 保存
this.conf = conf
this.emitter = new EventEmitter
// 连接
this.client = new MongoClient(conf.url, {
useNewUrlParser: true
})
this.client.connect(err => {
if (err) throw err
console.log('连接成功')
this.emitter.emit('connect')
})
}
// 数据库对象
col(colName, dbName = conf.dbName) {
return this.client.db(dbName).collection(colName)
}
// 执行一次
once(event, cb) {
this.emitter.once(event, cb)
}
}
module.exports = new Mongodb(conf)
实现数据接口
const express = require('express')
const app = express()
const path = require('path')
const mongo = require('./model/db')
app.get('/', (req, res) => {
res.sendFile(path.resolve(__dirname, './index.html'))
})
// 搜索
app.get('/api/category', async (req, res) => {
const col = mongo.col('fruits')
const data = await col.distinct('category')
res.json({
ok: 1,
data
})
})
// 列表
app.get('/api/list', async (req, res) => {
// 分页查询
const { page = 1, category, keyword } = req.query || {}
// 构造条件
const condition = {}
if (category) {
condition.category = category
}
if (keyword) {
condition.name = {
$regex: new RegExp(keyword)
}
}
try {
const col = mongo.col('fruits')
const total = await col.find(condition).count()
const fruits = await col.find(condition).skip((page - 1) * 5).limit(5).toArray()
res.json({
ok: 1,
data: {
fruits,
pagination: {
total: total
}
}
})
} catch (error) {
console.log(error)
}
})
app.listen(3000, () => {
console.log('listening at 3000')
})
前端页面 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" />
<title>购物车实战</title>
</head>
<body>
<div id="app">
<el-input placeholder="请输入内容" v-model="search" class="input-with-select" @change="changeHandler">
<el-button slot="append" icon="el-icon-search"></el-button>
</el-input>
<el-radio-group v-model="category" @change="getData">
<el-radio-button v-for="v in categorys" :label="v" :key="v">{{v}}</el-radio-button>
</el-radio-group>
<el-table :data="fruits" style="width: 100%">
<el-table-column prop="name" label="名称" width="180">
</el-table-column>
<el-table-column prop="price" label="价格" width="180">
</el-table-column>
<el-table-column prop="category" label="种类">
</el-table-column>
</el-table>
<el-pagination layout="prev, pager, next" @current-change="currentChange" :total="total">
</el-pagination>
</div>
<script>
const app = new Vue({
el: '#app',
data() {
return {
page: 1,
total: 0,
fruits: [],
categorys: [],
category: [],
search:''
}
},
created() {
this.getData()
this.getCategory()
},
methods: {
// 分页
async currentChange(page) {
this.page = page
await this.getData()
},
// 搜索
async changeHandler(val) {
this.search = val
await this.getData()
},
// 获取数据
async getData() {
const res = await axios.get(`/api/list?page=${this.page}&category=${this.category}&keyword=${this.search}`)
const data = res.data.data
this.fruits = data.fruits
this.total = data.pagination.total
},
// 获取类型
async getCategory() {
const res = await axios.get(`/api/category`)
this.categorys = res.data.data
}
}
})
</script>
</body>
</html>
执行结果