企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
先将所有代码给大家看一下,避免学习过程出错找不到问题。 admin/src/views/CategoryList.vue: ``` <template> <div> <h1>分类列表</h1> <el-table :data="items"> <el-table-column prop="_id" label="ID" width="220"> </el-table-column> <el-table-column prop="name" label="分类名称"> </el-table-column> <el-table-column fixed="right" label="操作" width="100"> <template slot-scope="scope"> <el-button type="text" size="small" @click="$router.push('/categories/edit/' + scope.row._id)">编辑</el-button> <el-button @click="remove(scope.row)" type="text" size="small">删除</el-button> </template> </el-table-column> </el-table> </div> </template> <script> export default { data() { return { items: [] } }, methods: { async fetch(){ const res = await this.$http.get('categories') this.items = res.data }, remove(row){ this.$confirm('是否确定要删除分类"' + row.name + '"?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(async () => { // 要想使用await,函数必须使用async // await异步执行,待调用接口获取数据完成后再将值传给res,进行下一步操作 const res = await this.$http.delete('categories/' + row._id) this.$message({ type: 'success', message: '删除成功!' }); if(res.status == 200){ // 接口调用成功后,刷新页面 this.fetch() } }).catch(() => { this.$message({ type: 'info', message: '已取消删除' }); }); } }, created() { this.fetch() } } </script> ``` server/routes/admin/index.js: ``` module.exports = app => { // 要想使用express,该文件就需要引入express const express = require('express') // 定义路由方法,将我们定义的路由挂载到express const router = express.Router() // 引入Category模型 const Category = require('../../models/Category') // router挂载post方法,因为表单传值时用的就是post传值 // 接口地址是categories,接收的是分类功能(创建分类、修改分类、查询分类列表)的操作 // 之后其他功能实现与此模板相同,与此功能平级 // 上传数据(增) router.post('/categories', async(req, res) => { // 在里边放该接口的具体操作,所有操作同级放置 // 数据来源是接受到的req中的body // 为避免阻塞,要用异步操作,故加入await const model = await Category.create(req.body) // 接收返回值 res.send(model) }) // 查询数据(查) router.get('/categories', async(req, res) => { const items = await Category.find().limit(10) res.send(items) }) // 根据id查询数据(查) router.get('/categories/:id', async(req, res) => { const model = await Category.findById(req.params.id) res.send(model) }) // 编辑数据(改) router.put('/categories/:id', async(req, res) => { const model = await Category.findByIdAndUpdate(req.params.id, req.body) res.send(model) }) // 删除数据(删) router.delete('/categories/:id', async(req, res) => { // 不需要返回值 await Category.findByIdAndDelete(req.params.id, req.body) // 只发送一个bool值,表明删除成功 res.send({ success: true }) }) // 定义“admin/api”路由方法,挂载存入到router app.use('/admin/api', router) } ``` 1.创建list页面组件。 vue.js不同于以往html\css的开发方式,全程以组件为主体进行视觉呈现,其中.vue文件就是vue的单文件组件,开发方式就是包装组件,然后将已开发的子组件引入父级组件中,从而进行进一步操作。现我们基本都会用前端框架进行视觉的呈现,很少用到css,其中css不可在vue组件中使用,后期我们需要的时候可能会用到.less文件,大家需要的话可以学习一下.less相关的引入方法。 进入正题: (1)创建CategoryList.vue组件 ![](https://img.kancloud.cn/85/44/8544bae7acd91d54442d30a6c55b5270_1159x798.png) ``` <template> <div> <h1>分类列表</h1> <el-table :data="items"> <el-table-column prop="_id" label="ID" width="220"> </el-table-column> <el-table-column prop="name" label="分类名称"> </el-table-column> </el-table> </div> </template> <script> export default { data(){ return { items: [ { name: "wogiao", _id: 1 },{ name: "yigiaowoligiao", _id: 2 } ] } } } </script> ``` (2)在路由中引入 ![](https://img.kancloud.cn/95/30/953084a4266150d855d9590bf5290e7b_1159x798.png) 此时就可以在页面中进入页面了。 ``` ![](https://img.kancloud.cn/83/21/83212e72ddc190d12c11752f60f91e6a_1268x802.png) ``` 2.创建接口-删改查 进入服务器端 ``` cd server ``` ``` npm run serve ``` 找到服务端admin路由主文件 ![](https://img.kancloud.cn/09/e4/09e4ae594b100d2a87c5f60cede32539_199x311.png) (1)查询数据 上篇文章的上传数据接口就是“增”,在下方并列写下“查”的方法接口: ![](https://img.kancloud.cn/fb/22/fb2268182c59ea46fa0afa9ab8b9413a_845x496.png) ``` // 查询数据(查) router.get('/categories', async(req, res) => { const items = await Category.find().limit(10) res.send(items) }) ``` (2)根据id查询数据(查) ``` // 根据id查询数据(查) router.get('/categories/:id', async(req, res) => { const model= await Category.findById(req.params.id) res.send(model) }) ``` (3)编辑数据-改 ``` // 编辑数据(改) router.put('/categories/:id', async(req, res) => { const model = await Category.findByIdAndUpdate(req.params.id, req.body) res.send(model) }) ``` (4)删除数据-删 ``` // 删除数据(删) router.delete('/categories/:id', async(req, res) => { // 不需要返回值 await Category.findByIdAndDelete(req.params.id, req.body) // 只发送一个bool值,表明删除成功 res.send({ success: true }) }) ``` 3.调用接口 (1)呈现数据到页面-使用查询接口 回到CategoryList.vue组件中,删除items原始数据的内容,添加方法fetch(),且使用初始化钩子函数created方法调用。 ![](https://img.kancloud.cn/b2/a4/b2a415d7611ab5758c62b022ddc7c6d5_1159x798.png) ``` export default { data() { return { items: [] } }, methods: { async fetch(){ const res = await this.$http.get('categories') this.items = res.data } }, created() { this.fetch() } } ``` 保存代码后,页面数据就改变了,打开网站开发面板检查调用数据,发现接口调用没问题。 ![](https://img.kancloud.cn/92/e4/92e43509f57512c7e3e48243e9c09c11_1268x728.png) 回到创建分类页面再次添加一个分类,测试: ![](https://img.kancloud.cn/2d/27/2d27ceb24b870b76942622dbcdca82ef_1268x353.png) ![](https://img.kancloud.cn/27/ee/27ee0d33dca09be1143e4ce8180ee23c_1268x353.png) 没问题,到此查询功能实现。 (2)显示编辑前数据-根据id查询接口(查) 在elementUI官网找到表格的按钮代码: ![](https://img.kancloud.cn/3f/0a/3f0a07863c31d52e79b1321dc7c14853_1268x730.png) ``` <el-table-column fixed="right" label="操作" width="100"> <template slot-scope="scope"> <el-button @click="handleClick(scope.row)" type="text" size="small">查看</el-button> <el-button type="text" size="small">编辑</el-button> </template> </el-table-column> ``` ![](https://img.kancloud.cn/e6/ad/e6ad4b20b0d7b354e3f5f54b8f58442a_1159x798.png) 修改编辑按钮,添加@click方法,传入这个按钮所在行的id: ``` <el-button type="text" size="small" @click="$router.push('/categories/edit/' + scope.row._id)">编辑</el-button> ``` 在服务器端路由admin添加接口的路径信息,由于修改分类的页面与添加分类页面相同,所以让edit修改页面地址指向同一个.vue组件CategorySet.vue。 同时最后要加一个props,指将链接传入的url参数值传入页面内,可以在页面内使用我们传入的id。 ![](https://img.kancloud.cn/84/d2/84d2cb33d7e5760d2f0b05c6058d1eee_1159x798.png) 同时,页面内要接收传来的id,在CategorySet.vue作改动: ![](https://img.kancloud.cn/53/95/5395b63106a2f84530ddcd14518ea33d_1159x936.png) 点击按钮跳转: ![](https://img.kancloud.cn/fa/5c/fa5c63cd3ff52b6974345f338333f048_1268x425.png) 进入编辑页面后,根据id查询修改前的分类名,所以我们要调用根据id查询的查询接口,改动CategorySet.vue: ![](https://img.kancloud.cn/82/12/82127699d43ec019e5e36f4173651ddc_1159x936.png) 这样,页面原值就出现了: ![](https://img.kancloud.cn/7e/5f/7e5f325253c339c4b5c73c0ccc1d9f47_1268x353.png) (3)使用编辑接口(改) 改动原save()方法,如果页面有id(编辑分类)则修改数据,若没有id(新建分类)则创建数据。 ![](https://img.kancloud.cn/2c/f0/2cf045bfb2f33e710571a4568dd51f09_1159x936.png) 改动后save()方法: ``` async save(){ const res if(this.id){ // 传id值,表明修改哪一条数据 res = await this.$http.put('categories/' + this.id, this.model) }else{ // 这里放axios方法,用来提交数据 res = await this.$http.post('categories', this.model) } // 操作完成后跳转到categories地址 this.$router.push('/categories/list') // 提示信息 this.$message({ type: 'success', message: '保存成功' }) }, ``` 测试一下,没问题: ![](https://img.kancloud.cn/02/c1/02c19b574800e070a52f48cf56492d46_1268x353.png) ![](https://img.kancloud.cn/c7/5d/c75df47dc62bd13e287e9488d330073a_1268x688.png) (4)使用删除接口(删) 首先,将“查看”按钮改成“删除”按钮,由于我们多数制作删除按钮是要注意避免误删,所以在点击删除应该多一步是否确认删除该条分类。因此与编辑保存后直接跳转接口不同,在这里要点击后跳转remove()方法,将整行信息传到方法中。 ``` <el-button @click="remove(scope.row)" type="text" size="small">删除</el-button> ``` 然后,在methods中编写remove()方法,在elementUI中找到messageBox弹框,使用其中的确认消息。 ![](https://img.kancloud.cn/b2/a6/b2a6886fdafa9a8da8ca6d3ddba38fea_1268x730.png) ``` remove(row){ this.$confirm('是否确定要删除分类"' + row.name + '"?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(async () => { // 要想使用await,函数必须使用async // await异步执行,待调用接口获取数据完成后再将值传给res,进行下一步操作 const res = await this.$http.delete('categories/' + row._id) this.$message({ type: 'success', message: '删除成功!' }); if(res.status == 200){ // 接口调用成功后,刷新页面 this.fetch() } }).catch(() => { this.$message({ type: 'info', message: '已取消删除' }); }); } ``` 测试该功能: ![](https://img.kancloud.cn/51/e6/51e6cced96d71ecc6b7977b6e55a200a_1268x353.png) ![](https://img.kancloud.cn/4a/cb/4acb947c5e3d25c5922ce4d27c2b0e1f_1268x353.png) 没问题。 4.路由页面的跳转 ![](https://img.kancloud.cn/33/44/3344284326c55223ed62cfacb1fdc09a_1152x1084.png) 如果我们编辑某一个分类,进入页面后进入新建分类页面,页面中的数据依然是之前编辑的页面: ![](https://img.kancloud.cn/5f/eb/5feb0ed3d7caa282f72629efa187345d_1144x396.png) 这是因为页面的路由是以组件来区分的: ![](https://img.kancloud.cn/58/4f/584faee8c6886f2f2cdba6e8054d9022_1004x855.png) 由于修改和新建分类使用的是同一个页面,所以我们不可以使用组件来区分,应该用路由地址区分: ![](https://img.kancloud.cn/2e/d2/2ed23541cd133fee6897a48fd2f9a9f5_1004x855.png) 此时问题得以解决。 5.总结 到此,mongodb的增删改查都学习完了。所有功能都可以照此相关接口完成,可以一步步制作我们的动态网站了。但是分类是一个网站内容的起始、根源,一切内容都以分类为进一步扩展。下篇文章我们学习mongodb的强大功能之一子分类,即分类的关联(绑定)。