[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-public-aOkpnT10":3,"public-project-articles-aOkpnT10":17},{"id":4,"uuid":5,"project_id":6,"title":7,"content":8,"type":9,"status":10,"public_enabled":10,"views":11,"sort":12,"created_at":13,"updated_at":14,"project_title":15,"project_slug":16},917,"aOkpnT10",50,"03. 一个视频学会Vue3+Element-Plus","\n## 使用依赖库\n\nVue.js、axios.js、element-plus.js、element-plus.css\n\n\n\n```html\n\u003Clink rel=\"stylesheet\" href=\"libs\u002Felement-plus.css\">\n```\n\n## Vue 官网\n\n[https:\u002F\u002Fcn.vuejs.org\u002Fguide\u002Fessentials\u002Fapplication.html](https:\u002F\u002Fcn.vuejs.org\u002Fguide\u002Fessentials\u002Fapplication.html)\n\n## Element-Plus\n\n[https:\u002F\u002Fdoc-archive.element-plus.org\u002F#\u002Fzh-CN\u002Fcomponent\u002Finstallation](https:\u002F\u002Fdoc-archive.element-plus.org\u002F#\u002Fzh-CN\u002Fcomponent\u002Finstallation)\n\n[https:\u002F\u002Fcn.element-plus.org\u002F](https:\u002F\u002Fcn.element-plus.org\u002F)\n\n## 网页版 Vue3 初始化\n\n```html\n\u003Cdiv id=\"app\">\u003C\u002Fdiv>\t\n\n\u003Cscript>\n  const { createApp, reactive } = Vue\n\n  const app = createApp({\n    setup() {\n      \u002F\u002F 存放数据\n      const data = reactive({\n\n      })\n      \u002F\u002F 数据和函数在外部使用 需要在此return出去\n      return {data}\n    }\n  }).mount('#app')\n\u003C\u002Fscript>\n```\n\n## 使用 Element.plus\n\n```vue\napp.use(ElementPlus)\n```\n\n## 前后端数据交互 Axios\n\naxios 是一个封装了 Ajax 的一个工具库\n\n## 设置网页自动更新\n\n![](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2025\u002Fpng\u002F751015\u002F1760688618047-b340b5b2-af53-4886-82e0-3d5f9ad2d115.png)\n\n![](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2025\u002Fpng\u002F751015\u002F1760688628318-cc42778b-4ba4-4d88-9acd-14260cee075f.png)\n\n![](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2025\u002Fpng\u002F751015\u002F1760688606051-c3de6a6e-9aca-48a4-a907-4ef6c50c2856.png)\n\n## 通过网络找到页面发起的请求，观察请求的数据\n\n![](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2025\u002Fpng\u002F751015\u002F1760688703845-41fa89da-84b3-4abe-a87a-0533d4046b0d.png)\n\n结果：\n\n![](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2025\u002Fpng\u002F751015\u002F1760688724812-bffeb1c3-ff27-4240-917e-acf9db6559de.png)\n\n## 本节课完整的 index.html 源码\n\n```html\n\u003C!DOCTYPE html>\n\u003Chtml lang=\"en\">\n\u003Chead>\n    \u003Cmeta charset=\"UTF-8\">\n    \u003Ctitle>B站搜：程序员青戈\u003C\u002Ftitle>\n    \u003Clink rel=\"stylesheet\" href=\"libs\u002Felement-plus.css\">\n    \u003Cstyle>\n        [v-clock] {\n            display: none;\n        }\n    \u003C\u002Fstyle>\n\u003C\u002Fhead>\n\u003Cbody>\n    \u003Cdiv id=\"app\" v-cloak>\n        \u003Ch2>B站关注程序员青戈，带你学SpringBoot+Vue实战项目\u003C\u002Fh2>\n        \u003Ch2>官网：\u003Ca target=\"_blank\" href=\"https:\u002F\u002Fjavaxm.cn\u002Ffree\u002F1spxh.html\">https:\u002F\u002Fjavaxm.cn\u003C\u002Fa>\u003C\u002Fh2>\n\n        \u003Cdiv>\n            \u003Cdiv style=\"width: 80%; margin-bottom: 20px; display: flex; align-items: center\">\n                \u003Cel-button type=\"primary\" @click=\"handleAdd\">新增\u003C\u002Fel-button>\n                \u003Cdiv style=\"flex: 1; text-align: right\">\n                    \u003Cel-input clearable @clear=\"load\" placeholder=\"请输入查询条件\" style=\"width: 300px\" v-model=\"data.name\">\u003C\u002Fel-input>\n                    \u003Cel-button type=\"success\" plain style=\"margin-left: 5px\" @click=\"load\">查 询\u003C\u002Fel-button>\n                \u003C\u002Fdiv>\n            \u003C\u002Fdiv>\n            \u003Cel-table border :data=\"data.tableData\" stripe style=\"width: 80%\">\n                \u003Cel-table-column prop=\"id\" label=\"ID\" width=\"100\">\u003C\u002Fel-table-column>\n                \u003Cel-table-column prop=\"username\" label=\"账号\"> \u003C\u002Fel-table-column>\n                \u003Cel-table-column prop=\"name\" label=\"姓名\"> \u003C\u002Fel-table-column>\n                \u003Cel-table-column prop=\"phone\" label=\"电话\" width=\"500\"> \u003C\u002Fel-table-column>\n                \u003Cel-table-column prop=\"email\" label=\"邮箱\"> \u003C\u002Fel-table-column>\n                \u003Cel-table-column label=\"操作\">\n                    \u003Ctemplate #default=\"scope\">\n                        \u003Cel-button type=\"text\" @click=\"handleUpdate(scope.row)\">编辑\u003C\u002Fel-button>\n                        \u003Cel-button style=\"color: #ff4141\" type=\"text\" @click=\"del(scope.row.id)\">删除\u003C\u002Fel-button>\n                    \u003C\u002Ftemplate>\n                \u003C\u002Fel-table-column>\n                \u003C\u002Fel-table-column>\n            \u003C\u002Fel-table>\n\n            \u003Cdiv style=\"margin-top: 20px\">\n                \u003Cel-pagination layout=\"total, sizes, prev, pager, next, jumper\"\n                               v-model:current-page=\"data.pageNum\"\n                               v-model:page-size=\"data.pageSize\"\n                               :page-sizes=\"[2, 5, 10, 15, 20]\"\n                               :total=\"data.total\"\n                               @current-change=\"load\"\n                               @size-change=\"load\"\n\n                >\n                \u003C\u002Fel-pagination>\n            \u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n\n        \u003Cel-dialog title=\"用户信息\" v-model=\"data.formVisible\" width=\"30%\">\n            \u003Cel-form style=\"padding-right: 30px\" :model=\"data.form\" label-width=\"80px\">\n                \u003Cel-form-item label=\"账户\">\n                    \u003Cel-input :disabled=\"data.form.id\" v-model=\"data.form.username\" autocomplete=\"off\" placeholder=\"请输入账号\">\u003C\u002Fel-input>\n                \u003C\u002Fel-form-item>\n                \u003Cel-form-item label=\"密码\">\n                    \u003Cel-input show-password v-model=\"data.form.password\" autocomplete=\"off\" placeholder=\"请输入密码\">\u003C\u002Fel-input>\n                \u003C\u002Fel-form-item>\n                \u003Cel-form-item label=\"名称\">\n                    \u003Cel-input v-model=\"data.form.name\" autocomplete=\"off\" placeholder=\"请输入名称\">\u003C\u002Fel-input>\n                \u003C\u002Fel-form-item>\n                \u003Cel-form-item label=\"电话\">\n                    \u003Cel-input v-model=\"data.form.phone\" autocomplete=\"off\" placeholder=\"请输入电话\">\u003C\u002Fel-input>\n                \u003C\u002Fel-form-item>\n                \u003Cel-form-item label=\"邮箱\">\n                    \u003Cel-input v-model=\"data.form.email\" autocomplete=\"off\" placeholder=\"请输入邮箱\">\u003C\u002Fel-input>\n                \u003C\u002Fel-form-item>\n            \u003C\u002Fel-form>\n            \u003Ctemplate #footer>\n                \u003Cspan class=\"dialog-footer\">\n                \u003Cel-button @click=\"data.formVisible = false\">取 消\u003C\u002Fel-button>\n                \u003Cel-button type=\"primary\" @click=\"save\">保 存\u003C\u002Fel-button>\n                \u003C\u002Fspan>\n            \u003C\u002Ftemplate>\n        \u003C\u002Fel-dialog>\n\n    \u003C\u002Fdiv>\n\n    \u003Cscript src=\"libs\u002Fvue.global.js\">\u003C\u002Fscript>\n    \u003Cscript src=\"libs\u002Felement-plus.js\">\u003C\u002Fscript>\n    \u003Cscript src=\"libs\u002Felement-plus_zh-cn.js\">\u003C\u002Fscript>\n    \u003Cscript src=\"libs\u002Faxios.min.js\">\u003C\u002Fscript>\n    \u003Cscript>\n        const { createApp, reactive } = Vue\n        const { ElMessage, ElMessageBox } = ElementPlus\n\n        \u002F\u002F 创建一个vue3 实例\n        const app = createApp({\n            setup() {\n                \u002F\u002F 存放数据\n                const data = reactive({\n                    tableData: [],  \u002F\u002F 用户的数据\n                    pageNum: 1,  \u002F\u002F当前页码\n                    pageSize: 5, \u002F\u002F 每页个数\n                    total: 0,  \u002F\u002F 总个数\n                    name: null,  \u002F\u002F 查询条件\n                    form: {},  \u002F\u002F 绑定表单的对象\n                    formVisible: false\n                })\n                const load = () => {\n                    console.log(data.pageNum)\n                    \u002F\u002F 通过  axios发送ajax请求获取数据\n                    axios.get('\u002Fuser\u002FselectPage', {\n                        params: {\n                            pageNum: data.pageNum,\n                            pageSize: data.pageSize,\n                            name: data.name\n                        }\n                    }).then(res => {\n                        console.log(res.data)\n                        data.tableData = res.data.list\n                        data.total = res.data.total\n                    }).catch(err => {\n                        console.error('错误信息：', err)\n                        ElMessage.error(err.message)\n                    })\n                }\n                load()\n\n                const handleAdd = () => {\n                    data.form = {}\n                    data.formVisible = true\n                }\n\n                const add = () => {\n                    axios.post('\u002Fuser\u002Fadd', data.form).then(res => {\n                        load()\n                        data.formVisible = false\n                        ElMessage.success('新增成功')\n                    }).catch(err => {\n                        ElMessage.error(err.response.data)\n                    })\n                }\n\n                const handleUpdate = (row) => {\n                    data.form = JSON.parse(JSON.stringify(row))  \u002F\u002F 深度拷贝行对象\n                    data.formVisible = true\n                }\n\n                const update = () => {\n                    axios.put('\u002Fuser\u002Fupdate', data.form).then(res => {\n                        load()\n                        data.formVisible = false\n                        ElMessage.success('更新成功')\n                    }).catch(err => {\n                        ElMessage.error(err.response.data)\n                    })\n                }\n\n                \u002F\u002F save是一个方法 调用2种接口  因为弹窗是共用的  form对象也是共用的\n                const save = () => {\n                    if (data.form.id) {  \u002F\u002F 更新\n                        update()\n                    } else {  \u002F\u002F 新增\n                        add()\n                    }\n                }\n\n                const del = (id) => {\n                    ElMessageBox.confirm('您确定删除id=' + id + '的数据吗？', '提示', { type: 'warning' }).then(res => {\n                        axios.delete('\u002Fuser\u002Fdelete\u002F' + id).then(res => {\n                            load()\n                            ElMessage.success('删除成功')\n                        }).catch(err => {\n                            ElMessage.error(err.response.data)\n                        })\n                    }).catch(err => {})\n                }\n\n                \u002F\u002F 数据和函数在外部使用 需要在此return出去\n                return {data, load, handleAdd, handleUpdate, save, del}\n            }\n        }).use(ElementPlus, { locale: ElementPlusLocaleZhCn }).mount('#app')\n    \u003C\u002Fscript>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>\n```\n\n\n\n\n\n## 本节课完成后的springboot_vue源码\n链接: [https:\u002F\u002Fpan.baidu.com\u002Fs\u002F16yU79P3qrNkOQd79XINTUQ?pwd=7x7q](https:\u002F\u002Fpan.baidu.com\u002Fs\u002F16yU79P3qrNkOQd79XINTUQ?pwd=7x7q) 提取码: 7x7q","coding",1,117,1828,"2025-10-17 17:17:50","2026-05-03 22:49:02","一个视频带你学会Springboot+Vue实战开发","springboot-vue-video",{"project":18,"items":19},{"id":6,"title":15,"slug":16},[20,27,34],{"id":21,"uuid":22,"project_id":6,"title":23,"type":9,"status":10,"public_enabled":10,"views":24,"sort":25,"created_at":26,"updated_at":14,"project_title":15,"project_slug":16},895,"hjKZQzTE","01. 一个视频学会SpringBoot",256,1793,"2025-10-17 17:19:16",{"id":28,"uuid":29,"project_id":6,"title":30,"type":9,"status":10,"public_enabled":10,"views":31,"sort":32,"created_at":33,"updated_at":14,"project_title":15,"project_slug":16},908,"uagE5iJR","02. 彻底搞会SpringBoot进阶开发模式",131,1815,"2025-10-15 18:08:39",{"id":4,"uuid":5,"project_id":6,"title":7,"type":9,"status":10,"public_enabled":10,"views":11,"sort":12,"created_at":13,"updated_at":14,"project_title":15,"project_slug":16}]