尚硅谷的后台管理系统学习笔记【尚硅谷】【Vue】
day1
1.什么是后台管理系统项目?
注意:前端领域当中,开发后台管理系统项目,并非是java、php等后台语言项目。
在前面课程当中,我们已经开发了一个项目【尚品汇电商平台项目】,这个项目主要针对的是用户(游客),可以让用户在平台当中购买产品。
但是你需要想明白一件事情,用户购买产品信息从何而来呀?
比如:前台项目当中的数据来源于卖家(公司),但是需要注意的时候,卖家它不会数据库操作。对于卖家而言,需要把产品的信息上传于服务器,写入数据库。
卖家并非程序员,不会数据库操作(增删改查)。导致卖家,找了一个程序员,开发一个产品,可以让我进行可视化操作数据库(增伤改查)
卖家(公司):组成,老板、员工。
老板:开发这个项目,对于老板而言,什么都可以操作。【产品的上架、产品的下架、查看员工的个人业绩、其他等等】
员工:可能就是查看个人业绩
后台管理系统:可以让用户通过一个可视化工具,可以实现对于数据库进行增删改查的操作。
而且需要注意,根据不同的角色(老板、员工),看到的、操作内容是不同的。
对于后台管理系统项目,一般而言,是不需要注册的。
2.模板介绍
简洁版: https://github.com/PanJiaChen/vue-admin-template 我们用这个
加强版: https://github.com/PanJiaChen/vue-element-admin
3.文件夹介绍
build
------ index.js webpack配置文件【很少修改这个文件】
mock
------ mock数据文件夹 【模拟一些假数据mockjs实现】,本案例使用真实数据
node_modules
------ 项目依赖
public
------ 静态资源,打包时不会编译这个文件夹
src------ 程序员源代码
api------ 接口请求相关
assets------ 静态资源,打包时不会编译
components ------ 一般放置非路由组件或者全局组件
icons ------ 放置了一些svg矢量图
layout ------ 放置一些组件与混入,后续组件都是在layout组件中
router ------ 路由相关
store------ vuex
style------ 样式相关
utils ------ 封装一些需要的方法比如request.js axios二次封装,以及token的存储和移出操作
views------ 放置路由组件
App.vue:根组件
main.js:入口文件
permission.js:与导航守卫先关、
settings:项目配置项文件
.env.development
.env.producation
4.登录功能
1.接口
因为我们使用的是真实接口需要替换原模板的接口
接口地址:http://39.98.123.211:8170/swagger-ui.html#/
这里将其他接口一起进行了替换
//引入axios(axios进行了二次封装)
import request from '@/utils/request'//对外暴露的登录接口函数
export function login(data) {return request({url: '/admin/acl/index/login',method: 'post',data})
}
//对外暴露的用户信息接口函数
export function getInfo(token) {return request({url: '/admin/acl/index/info',method: 'get',params: { token }})
}
//对外暴露的退出登录接口函数
export function logout() {return request({url: '/admin/acl/index/logout',method: 'post'})
}
修改axios的二次封装,真实接口成功的code=200,我们真实接口需要携带token字段,而不是提供的X-Token
service.interceptors.request.use(config => {// do something before request is sentif (store.getters.token) {// let each request carry token// ['X-Token'] is a custom headers key// please modify it according to the actual situation// config.headers['X-Token'] = getToken()config.headers['token'] = getToken()//修改后}return config},error => {// do something with request errorconsole.log(error) // for debugreturn Promise.reject(error)}
)
if (res.code !== 20000 && res.code != 200) {Message({message: res.message || 'Error',type: 'error',duration: 5 * 1000})
因为使用了真实接口所以需要在vue.config.js配置代理跨域
devServer: {port: port,open: true,overlay: {warnings: false,errors: true},//配置代理跨域proxy: {'/dev-api': {target: 'http://39.98.123.211:8170',pathRewrite: { '^/dev-api': '' },},},},
2.源码分析
组件内
handleLogin() {//验证表单元素是否符合规则this.$refs.loginForm.validate((valid) => {if (valid) {//按钮的loading效果this.loading = true//派发一个action:user/login,带着用户名和密码this.$store.dispatch('user/login', this.loginForm)//登录成功.then(() => {//路由跳转this.$router.push({ path: this.redirect || '/' })//loading结束this.loading = false}).catch(() => {this.loading = false})} else {console.log('error submit!!')return false}})},
vuex仓库中
actions,由于之前没有async和await,模板使用的.then与.catch
login({ commit }, userInfo) {//解构用户名与密码const { username, password } = userInforeturn new Promise((resolve, reject) => {//向服务器请求数据login({ username: username.trim(), password: password })//请求成功.then(response => {// console.log(response);//将response解构赋值给dataconst { data } = response//派发mutations业务commit('SET_TOKEN', data.token)//本地保存tokensetToken(data.token)resolve()}).catch(error => {reject(error)})})},
修改为async和await
async login({ commit }, userInfo) {//解构用户名与密码const { username, password } = userInfolet result = await login({ username: username.trim(), password: password })if (result.code == 20000) {commit('SET_TOKEN', result.data.token)setToken(result.data.token)return 'ok'} else {return Promise.reject(new Error('faile'))}},
剩余工作就是将英文文本替换成中文,较为简单不做演示,表单验证放在后面做
登录页最终结果
退出登录
由于api在上面已经做了修改,所以这里只是修改文本不做演示,退出登录组件名为Navbar
5.创建路由
1.路由目录
首页(一级路由)
权限管理(一级)
商品管理(一级)
---------品牌管理(二级)
---------平台属性管理(二级)
---------Spu管理(二级)
---------Sku管理(二级)
2.创建路由
我们的一级路由都是在Layout这个骨架下搭建的,所以一级路由的component都写Layout
{path: '/',component: Layout,//重定向至dashboard组件,即首页redirect: '/dashboard',children: [{path: 'dashboard',name: 'Dashboard',component: () => import('@/views/dashboard/index'),meta: { title: '首页', icon: 'dashboard' }}]},{path: '/product',component: Layout,name: 'Product',meta: { title: '商品管理', icon: 'el-icon-goods' },children: [{path: '/tradeMark',name: 'TradeMark',component: () => import('@/views/product/tradeMark'),meta: { title: '品牌管理' }},{path: '/attr',name: 'Attr',component: () => import('@/views/product/Attr'),meta: { title: '平台属性管理' }},{path: '/spu',name: 'Spu',component: () => import('@/views/product/Spu'),meta: { title: 'Spu管理' }},{path: '/sku',name: 'Sku',component: () => import('@/views/product/Sku'),meta: { title: 'Sku管理' }},]},
meta中的title为菜单栏以及面包屑显示的名字
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jKbvRwv9-1663551760268)(C:\Users\15363\AppData\Roaming\Typora\typora-user-images\image-20220916091415769.png)]
6.商品管理
这里主要是利用element-UI制作静态页面,模板的element-UI默认英文版
// set ElementUI lang to EN
// Vue.use(ElementUI, { locale })
// 如果想要中文版 element-ui,按如下方式声明
Vue.use(ElementUI)
1.品牌管理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-piNMFlod-1663551760269)(D:\桌面\屏幕截图 2022-09-16 092103.png)]
1.添加按钮
<el-button type="primary" icon="el-icon-plus" style="margin-bottom: 10px">添加</el-button>
2.添加table表格—显示的标题要居中—且序号的占比要小
el-table属性:
data:表格组件将来需要展示的数据【数组类型】
border:是给表格带上边框
el-table-column属性:
label:显示的标题
width:对应列的宽度
align:对齐方式
<el-table :data="data" style="width: 100%" border="true"><el-table-column prop="prop" label="序号" width="80px" align="center"></el-table-column><el-table-column prop="prop" label="品牌名称" width="width"></el-table-column><el-table-column prop="prop" label="品牌logo" width="width"></el-table-column><el-table-column prop="prop" label="操作" width="width"></el-table-column></el-table>
3.分页器----要居中
<!-- current-page:当前页数page-sizes:每页显示个数选择器page-size:每页显示条目个数total:总条目数pager-count:页码按钮的数量,当总页数超过该值时会折叠layout:实现分页器布局--><el-paginationclass="pagination":current-page="6":total="100":page-size="3":pager-count="7":page-sizes="[3, 5, 10]"@size-change="handleSizeChange"@current-change="handleCurrentChange"layout="prev, pager, next, jumper, ->, sizes, total"></el-pagination>
.pagination {margin-top: 20px;text-align: center;
}
day2
1.品牌管理动态数据展示
1.修改接口地址
原地址端口更改,代理跨域发生改变
proxy: {'/dev-api': {target: 'http://gmall-h5-api.atguigu.cn',pathRewrite: { '^/dev-api': '' },},},
后续就是写接口,写仓库
2.获取品牌列表接口
在api文件夹创建product文件夹统一管理商品管理的接口
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ShFN3MJJ-1663551760269)(C:\Users\15363\AppData\Roaming\Typora\typora-user-images\image-20220916165311726.png)]
在index中统一暴露
//统一暴露
import *as tradeMark from './product/tradeMark'
import *as attr from './product/attr'
import *as sku from './product/sku'
import *as spu from './product/spu'export default {tradeMark,attr,sku,spu,
}
//获取品牌信息
export const reqTradeMarkList = (page, limit) =>request({ url: `/admin/product/baseTrademark/${page}/${limit}`, method: 'get' })
这里不需要共享数据所以没有使用vuex仓库,而是将api添加到Vue原型上,其他组件可以直接调用
import API from '@/api'
Vue.prototype.$API = API
获取数据
mounted() {this.getPageList()},methods: {//获取商品列表async getPageList() {const { page, limit } = thislet result = await this.$API.tradeMark.reqTradeMarkList(page, limit)if (result.code == 200) {this.total = result.data.totalthis.list = result.data.records}},//点击分页器跳转页码handleCurrentChange(pager) {this.page = pagerthis.getPageList()},//展示数据条数切换handleSizeChange(sizes) {this.limit = sizesthis.getPageList()},
展示数据
elementUI当中的table组件,展示的数据是以一列一列进行展示数据的
如果需要显示索引,可以增加一列el-table-column,设置type属性为index即可显示从 1 开始的索引号。
prop:对应列内容的字段名,也可以使用 property 属性【字符串类型】
el-tabel :data="list"
表示这个表格展示的是哪里面的数据
第一列 我们要展示的是序列号,可以用 type="index"
表示从1 开始展示索引号
第二列 我们展示的是品牌类型,在list 里面的tmName,我们可以用prop
:对应列内容的字段名
<el-table border :data="list"><el-table-columnlabel="序号"width="80"align="center"type="index"></el-table-column><el-table-column label="品牌类型" prop="tmName"></el-table-column><el-table-column label="品牌LOGO"><!-- { row, $index }是固定的名字,不能瞎写 --><template slot-scope="{ row, $index }"><!-- row代表的是数组回传的数据 --><img :src="row.logoUrl" alt="" style="width: 100px; height: 100px" /></template></el-table-column><el-table-column label="操作"><template slot-scope="{ row, $index }"><el-button type="warning" icon="el-icon-edit>" size="mini">修改</el-button><el-button type="danger" icon="el-icon-delete>" size="mini">删除</el-button></template></el-table-column></el-table>
第三列 展示的是品牌logo,是个图片,我们有地址,我们可以用【作用域插槽】来展示图片
slot-scope="{ row, $index }"
代表的是子组件回传过来的数据,也就是list
然后我们进行动态展示图片:src
分页器动态数据
<el-pagination:current-page="page":page-sizes="[3, 5, 10]":page-size="limit"layout=" prev, pager, next, jumper,->,sizes, total":total="total"style="margin-top: 20px; text-align: center":page-count="7"></el-pagination>
完成相关点击事件
当点击页数的时候,修改data里面的page,然后再次发请求
@current-change="handleCurrentChange"
当你点击其他页数时触发
<el-pagination:current-page="page":page-sizes="[3, 5, 10]":page-size="limit"layout=" prev, pager, next, jumper,->,sizes, total":total="total"style="margin-top: 20px; text-align: center":page-count="7"@current-change="handleCurrentChange"@size-change="handleSizeChange"></el-pagination>
// 点击页码进行切换handleCurrentChange(pager) {// pager你点击的页数// 修改参数,然后再发请求this.page = pager ;this.getPageList();},// 点击页码进行切换handleCurrentChange(pager) {// pager你点击的页数// 修改参数,然后再发请求this.page = pager ;this.getPageList();},
@size-change="handleSizeChange"
当pageSize【展示数据条数】改变时触发
// 当分页器某一页需要展示数据的条数发生变化时触发handleSizeChange(limit){// 修改数据,再次发请求this.limit = limit ;this.getPageList();},
添加和修改品牌信息(静态)
当你点击品牌管理页面 左上角【添加】的时候,会弹出一个类似遮罩层的页面
当你点击【修改】,也会弹出一个类似遮罩层的页面-----------显示对话框
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pdAQvCLP-1663551760270)(C:\Users\15363\AppData\Roaming\Typora\typora-user-images\image-20220916172746949.png)]
我们这里用elementui的 dialog 对话框
<el-dialogtitle="添加品牌":visible.sync="dialogFormVisible"><!-- :model属性将表单数据收集到一个指定对象上 --><el-form style="width: 80%" :model="tmForm" :rules="rules" ref="ruleForm"><el-form-item label="品牌名称" label-width="100px" prop="tmName"><el-input autocomplete="off" v-model="tmForm.tmName"></el-input></el-form-item><el-form-item label="品牌logo" label-width="100px" prop="logoUrl"></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button @click="dialogFormVisible = false">取 消</el-button><el-button type="primary" @click="addOrUpdateTradeMark">确 定</el-button></div></el-dialog>
上传图片用elementui的Upload上传
<el-uploadclass="avatar-uploader"action="/dev-api/admin/product/fileUpload":show-file-list="false":on-success="handleAvatarSuccess":before-upload="beforeAvatarUpload"><img v-if="tmForm.logoUrl" :src="tmForm.logoUrl" class="avatar" /><i v-else class="el-icon-plus avatar-uploader-icon"></i><div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过2M</div></el-upload>
粘贴elementui里面相关的数据和方法与样式
data(){return{dialogFormVisible: false, // 对话框显示与隐藏的控制属性imageUrl: "", // 上传图片使用的属性}
},
methods:{// 上传图片相关的回调handleAvatarSuccess(res, file) {this.imageUrl = URL.createObjectURL(file.raw);},beforeAvatarUpload(file) {const isJPG = file.type === "image/jpeg";const isLt2M = file.size / 1024 / 1024 < 2;if (!isJPG) {this.$message.error("上传头像图片只能是 JPG 格式!");}if (!isLt2M) {this.$message.error("上传头像图片大小不能超过 2MB!");}return isJPG && isLt2M;},}
3.完成 添加品牌、修改品牌和删除的功能
1.api接口
//添加或修改品牌
export const reqAddOrUpdateTradeMark = (tradeMark) => {//修改品牌信息时需要获得品牌的id,我们通过是否存在品牌id,判断需要发送什么请求if (tradeMark.id) {//修改return request({ url: '/admin/product/baseTrademark/update', method: 'put', data: tradeMark })} else {//添加return request({ url: '/admin/product/baseTrademark/save', method: 'post', data: tradeMark })}
}//删除品牌
export const reqDeleteTradeMark = (id) => request({url: `/admin/product/baseTrademark/remove/${id}`, method: 'delete'
})
2.收集数据并发请求
1收集数据
要收集到elementui里面的表单数据,就要在表单el-form上面添加 model
属性,在item上添加v-model将来表单验证也需要这个属性
<el-form style="width: 80%" :model="tmForm"><el-form-item label="品牌名称" label-width="100px" ><el-input autocomplete="off" v-model="tmForm.tmName"></el-input></el-form-item>
收集LOGO图片
这里收集数据不能使用v-model,因为不是表单元素,我们这里用了另一个el-upload
action:设置图片上传的地址
on-success 可以检测到图片上传成功,图片上传成功会执行一次
before-upload :可以在上传图片之前,会执行一次
<el-uploadclass="avatar-uploader"action="/dev-api/admin/product/fileUpload":show-file-list="false":on-success="handleAvatarSuccess":before-upload="beforeAvatarUpload"><img v-if="tmForm.logoUrl" :src="tmForm.logoUrl" class="avatar" /><i v-else class="el-icon-plus avatar-uploader-icon"></i><div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过2M</div></el-upload>
//图片上传成功handleAvatarSuccess(res, file) {//res:上传成功之后返回的前端数据//file:同上//收集品牌图片数据this.tmForm.logoUrl = res.data},//图片上传之前beforeAvatarUpload(file) {const isJPG = file.type === 'image/jpeg'const isLt2M = file.size / 1024 / 1024 < 2if (!isJPG) {this.$message.error('上传头像图片只能是 JPG 格式!')}if (!isLt2M) {this.$message.error('上传头像图片大小不能超过 2MB!')}return isJPG && isLt2M},
2发请求
当点击【添加品牌】里的【确定】按钮时
- 将弹出的对话框隐藏
- 发请求(添加品牌
- 如果成功,弹出一个message框:可能是添加成功,也有可能是修改成功,然后重新获取新的品牌列表
<el-button type="primary" @click="addOrUpdateTradeMark">确 定</el-button>
笔记是在中午和晚上总结的,所以步骤会有点混乱,老师是先发请求,完成功能后再完成的表单验证,这里我提前表单验证
Form 组件提供了表单验证的功能,只需要通过rules
属性传入约定的验证规则,并将 Form-Item 的 prop
属性设置为需校验的字段名即可。校验规则参见 async-validator(element-ui原话)
<el-form style="width: 80%" :model="tmForm" :rules="rules" ref="ruleForm"><el-form-item label="品牌名称" label-width="100px" prop="tmName"><el-input autocomplete="off" v-model="tmForm.tmName"></el-input></el-form-item><el-form-item label="品牌logo" label-width="100px" prop="logoUrl">
data(){return{//表单验证规则rules: {tmName: [//required:必须验证的字段,message:提示信息,trigger:用户行为,blur失焦,change发生改变{ required: true, message: '请输入品牌名称', trigger: 'blur' },{min: 2, //字符长度max: 10,message: '长度在 2 到 10 个字符',trigger: 'change',},],//图片格式、大小不在这里验证,因为他不是表单元素, 在beforeAvatarUpload方法中有校验规则logoUrl: [{ required: true, message: '请上传品牌logo' }],},
}
}
发请求
addOrUpdateTradeMark() {//当全部字段验证通过在执行操作this.$refs.ruleForm.validate(async (valid) => {if (valid) {this.dialogFormVisible = false//发请求let result = await this.$API.tradeMark.reqAddOrUpdateTradeMark(this.tmForm)if (result.code == 200) {//element-ui的消息提示this.$message({message: this.tmForm.id ? '修改品牌成功' : '添加品牌成功',type: 'success',})//判断是修改还是添加操作,修改则留在当前页,添加返回第一页this.handleCurrentChange(this.tmForm.id ? this.page : 1)this.getPageList()}} else {this.$message.error('信息未填写完整')return false}})},
完善效果,点击不同按钮显示不同
<el-dialog:title="tmForm.id ? '修改品牌' : '添加品牌'":visible.sync="dialogFormVisible">
3.删除
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vpQNW8Hi-1663551760271)(C:\Users\15363\AppData\Roaming\Typora\typora-user-images\image-20220919094028254.png)]
当点击【删除】按钮时,会弹出一个弹框【确定要删除吗】,然后有【确定】和【取消】两个按钮
点击【删除】按钮,给【删除】绑定点击事件deleteTradeMark
,要传参数(你点击该品牌的信息—row)
弹出一个弹框,里面是【确定删除】还是【取消】
确定后,发请求删除该品牌,然后再发请求获取品牌列表数据;
deleteTradeMark(row) {this.$confirm(`确定删除${row.tmName}, 是否继续?`, '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning',})//点击确定触发.then(async () => {let result = await this.$API.tradeMark.reqDeleteTradeMark(row.id)if (result.code == 200) {this.$message({type: 'success',message: '删除成功!',})this.handleCurrentChange(this.list.length > 1 ? this.page : this.page - 1)this.getPageList()}})//点击取消触发.catch(() => {this.$message({type: 'info',message: '已取消删除',})})},
】绑定点击事件deleteTradeMark
,要传参数(你点击该品牌的信息—row)
弹出一个弹框,里面是【确定删除】还是【取消】
确定后,发请求删除该品牌,然后再发请求获取品牌列表数据;
deleteTradeMark(row) {this.$confirm(`确定删除${row.tmName}, 是否继续?`, '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning',})//点击确定触发.then(async () => {let result = await this.$API.tradeMark.reqDeleteTradeMark(row.id)if (result.code == 200) {this.$message({type: 'success',message: '删除成功!',})this.handleCurrentChange(this.list.length > 1 ? this.page : this.page - 1)this.getPageList()}})//点击取消触发.catch(() => {this.$message({type: 'info',message: '已取消删除',})})},
后续不想写了,主要是没那么多时间整理,只能写在代码注释里,抱歉。
完成后的GitHub源码地址
码云地址
尚硅谷的后台管理系统学习笔记【尚硅谷】【Vue】相关推荐
- MySQL学习笔记——尚硅谷李玉婷经典版MySQL基础笔记(一)
MySQL学习笔记--尚硅谷李玉婷经典版MySQL基础笔记(一) MySQL学习笔记目录 MySQL学习笔记--尚硅谷李玉婷经典版MySQL基础笔记(一) 一.基础知识 1.MySQL的语法规范 2. ...
- maven学习笔记——尚硅谷
文章目录 maven学习笔记--尚硅谷 第一章 Maven概述 第一节 为什么要学习Maven 1.Maven 作为依赖管理工具 1.1 jar 包的规模 1.2 jar 包的来源 1.3 jar 包 ...
- 「Vue 学习笔记 1」Vue 项目快速搭建,初始项目各个文件夹作用介绍和启动代码执行流程分析
「Vue 学习笔记 1」Vue 项目快速搭建,初始项目各个文件夹作用介绍和启动代码执行流程分析 前言 一.我的开发环境 二.使用 Vue CLI (Vue 脚手架)快速搭建项目 三.初始项目的目录结构 ...
- Rabbitmq学习笔记(尚硅谷2021)
Rabbitmq学习笔记 (尚硅谷) 1.MQ 的概念 1.1 什么是 MQ? 1.2 为什么要用 MQ? 削峰 解耦 异步 1.3 MQ 的分类 ActiveMQ Kafka RocketMQ Ra ...
- 尚硅谷springboot 2核心技术学习笔记
开发前先查看系统Java和maven的版本 参考资料 1.尚硅谷/SpringBoot2核心技术与响应式编程 2.springboot官网 3.版本升级变化 maven环境配置 <mirrors ...
- 【HBase学习笔记-尚硅谷-Java API shell命令 谷粒微博案例】
HBase学习笔记 HBase 一.HBase简介 1.HBase介绍 2.HBase的逻辑结构和物理结构 3.数据模型 4.基本架构 二.快速入门 1.配置HBase 2.命令 三.API 1.获取 ...
- SpringBoot练手项目《尚硅谷智慧校园》学习笔记
一 项目展示 1 登录及角色控制 2首页展示 3 业务模块展示 二 智慧校园系统简介 2.1 项目简介 智慧校园管理系统:主要是以年级.班级为单位,进行老师和学生信息记录和统计功能.项目采用前 ...
- 【尚硅谷/周阳】JUC学习笔记
JUC学习笔记[尚硅谷/周阳] 本文章基于B站视频教程[juc 与 jvm 并发编程 Java 必学_阳哥- 尚硅谷]进行整理记录,仅用于个人学习,交流使用. 目录标题 JUC学习笔记[尚硅谷/周阳] ...
- 尚硅谷Spring注解开发学习笔记
文章目录 前言 1.课程安排 1.1.容器 1.2.扩展原理 1.3.Web 2.配置文件开发 2.1.导入Spring-context依赖包 2.2.编写Spring配置文件 2.3.编写Perso ...
最新文章
- 有了易生信,导师再也不用担心我的单细胞转录组整合分析啦
- 小小flash动画_flash宣传动画视频能给公司品牌传播带来什么
- Creational模式之Builder模式
- 春运背后默默守护高铁安全的“隐形人”
- 自定义变量 配置文件_「系统架构」Nginx调优之变量的使用(3)
- Mathemmatica 新函数
- 【Java 数据库】Connections.getTables() 方法 获取数据库的元数据
- java对类数组进行排序_Java比较器类对数组进行排序
- slitaz c语言开发环境,makefile和cmake的简单使用
- Maya中AO贴图的一些烘焙心得
- 计算机方面的英语学术期刊,近几年计算机专业英文参考文献 计算机专业英文核心期刊参考文献有哪些...
- 计算机职业适应性测试题库,职业适应性测试题库 一、性格职业适应度测试.doc...
- 六千档最强万金油?华硕无畏Pro15 2022锐龙版笔记本体验
- win10服务器cpu占用过高,解决win10服务主机内存和cpu高占用的解决方法
- Java中String类intern()详解
- 老说程序员如何看产品经理,今天说说产品经理讨厌哪些程序员
- 尚医通(九)数据字典模块前后端 | EasyExcel
- 51单片机 玩转按键加减切换+数码管+Proteus仿真
- 3、Mybatis-Plus异常之There is no getter for property named ‘ew‘ in ‘class解决方案
- SPDR年内增量尽数被抹 市场看空金市
热门文章
- 【Magicavoxel简易入门教程】(二) 第二章 · 自制一个NPC导出模型优化工具使用(附下载)
- JDK8之ConcurrentHashMap源码解读
- 详解办公室装修设计省钱妙计
- 办公室设计公司关于办公室装修全过程解剖
- python argparse 和opencv模块的组合使用_如何利用Python3和OpenCV对比两张图片的不同,提取差异性...
- JMeter基础系列(八) JMeter断言之JSON断言
- 送给大一新生的一些话
- 京东技术体系员工级别划分及薪资区间
- 联想拯救者R720重装Win10系统的正确姿势
- 【转】2018年EI收录中文期刊目录