脚本宝典收集整理的这篇文章主要介绍了谷粒商城_04_商品CRUD,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
谷粒商城_01_环境搭建 谷粒商城_02_Nacos、网关 谷粒商城_03_前端基础
1、定义接口查询所有数据:gulimall-product的com.liu.gulimall.product.controller.CategoryController添加如下方法
/**
* 商品三级分类
*
* @author liujianyu
* @email 380404812@qq.com
* @date 2021-12-09 19:15:00
*/
@RestController
@RequestMapping("product/category")
public class CategoryController {
@Autowired
private CategoryService categoryService;
/**
* 查出所有分类以及子分类,以树形结构组装起来
*/
@RequestMapping("/list/tree")
public R list(){
List<CategoryEntity> entities = categoryService.listWithTree();
return R.ok().put("data", entities);
}
}
2、在service层中创建方法 listWithTree
/**
* 商品三级分类
*
* @author liujianyu
* @email 380404812@qq.com
* @date 2021-12-09 18:29:39
*/
public interface CategoryService extends IService<CategoryEntity> {
PageUtils queryPage(Map<String, Object> params);
/**
* 将数据以树形分类,分出三级
* @return
*/
List<CategoryEntity> listWithTree();
}
3、在service层的Impl中实现方法
@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {
// @Autowired
// private CategoryDao categoryDao;
// ServiceImpl<CategoryDao, CategoryEntity>已经帮我们注入了dao,就不用自己注入了
@Override
public List<CategoryEntity> listWithTree() {
// 1 查出所有分类
List<CategoryEntity> entities = baseMapper.selectList(null);
// 2 组装成父子的树形结构
List<CategoryEntity> level1Menus = entities.stream().filter((categoryEntity) ->{ // 过滤
// long类型的比较不要直接使用==,要用到longValue()来比较
return categoryEntity.getParentCid().longValue() == 0;} // 过滤只要父id等于0的数据,也就是一级分类
).map((categoryEntity)->{ // 为过滤后的一级分类的每一个数据设置他的子分类
categoryEntity.setChildren(getChildrens(categoryEntity,entities));
return categoryEntity;}
).sorted((categoryEntity1,categoryEntity2)->{ // 升序排序根据字段sort来让sort小的的排前面 由于categoryEntity1可能已经为空null了,所以先判断
return (categoryEntity1.getSort() == null? 0: categoryEntity1.getSort())
-
(categoryEntity2.getSort() == null?0:categoryEntity2.getSort());
}).collect(Collectors.toList()); // 将过滤的数据收集成数组
return level1Menus;
}
// 递归查找所有菜单的子菜单,把当前分类,和总分类传进来
private List<CategoryEntity> getChildrens(CategoryEntity root, List<CategoryEntity> all) {
List<CategoryEntity> children = all.stream().filter(categoryEntity -> {
// 过滤取出父id等于当前分类的数据
return categoryEntity.getParentCid().longValue() == root.getCatId().longValue();
}).map(categoryEntity -> { // 每一个子分类还有可能有子分类
// 1 找到子菜单
categoryEntity.setChildren(getChildrens(categoryEntity, all));
return categoryEntity;
}).sorted((menu1, menu2) -> {
// 2 菜单的排序 由于menu可能已经为空null了,所以先判断
return (menu1.getSort() == null?0:menu1.getSort()) - (menu2.getSort() == null?0:menu2.getSort());
}).collect(Collectors.toList());
return children;
}
}
1、创建商品系统的目录,以及内容转发的路由
数据库同步数据
2、根据人人开源策略,根据路由product/category
来请求product-category,比如sys-role具体的视图在renren-fast-vue/views/modules/sys/role.vue 所以要自定义我们的product/category视图的话,就是创建mudules/product/category.vue,根据策略创建product文件,在文件下创建category.vue组件,这样请求路由就会跳转到这个组件中,
3、编写category.vue组件
<template>
<el-tree
:data="data"
:props="defaultProps"
@node-click="handleNodeClick"
></el-tree>
</template>
<script>
export default {
data() {
return {
data: [],
defaultProps: {
children: "children",
label: "label",
},
};
},
methods: {
handleNodeClick(data) {
console.log(data);
},
getMenus(data) {
// 自定义方法
this.$http({
// htpp请求
url: this.$http.adornUrl("/product/category/list/tree"), // 请求后端的接口
method: "get",
}).then((data) => {
// 成功了之后的操作
console.log("请求数据," + data);
});
},
},
created() {
// 加载组件的时候就调用改方法
this.getMenus();
},
};
</script>
<style lang="scss" scoped>
</style>
4、我们的数据肯定是从后端取出来,所以要请求gulimall-product服务后端的接口,但是现在请求的是:人人开源的接口,所以修改前端配置:renren-fast-vuestaticconfigindex.js中修改,但是我们gulimall-product服务可能在很多服务器上,所以每次都要修改端口很麻烦,直接交给网关来做,让网关跟我们去请求服务器
由于我们想要访问的是:http://localhost:10000/product/category/list/tree这个请求,而且这里面的10000端口也存在多服务问题,所以采用网关来转发请求。http://localhost:88/product/category/list/tree
我们登录有验证码,这个是renrne-fast服务的数据,所以先注册renrne-fast服务
通过网关把请求转发给后端renren-fast服务,所以先让网关发现服务,也就是注册服务到注册中心去
1、在renren-fast中导入的依赖【如果依赖无法彻底删除,复制全文,删除原来的,重新创建pom文件】
2、在配置文件中配置,服务名称和注册中心地址
3、注册到注册中心中,加入注解:@EnableDiscoveryClient
4、启动nacos,发现服务
spring:
cloud:
gateway:
# 路由规则
routes:
- id: admin_route
uri: lb://renren-fast # 路由给renren-fast,lb代表负载均衡
predicates: # 什么情况下路由给它
- Path=/api/** # 默认前端项目都带上api前缀,但是这样还是请求的:http://localhost:88/api/..我们想要请求 http://localhost:8080/renren-fast/..,所以加上过滤器
# 所以在前端index.js中改为 window.SITE_CONFIG['baseUrl'] = 'http://localhost:88/api';
filters: # 过滤器,
- RewritePath=/api/(?<segment>.*),/renren-fast/${segment}
allowedOrigins("*")
改为 allowedOriginPatterns("*")
已拦截跨源请求:同源策略禁止读取位于 http://localhost:88/api/sys/login 的远程资源。(原因:CORS 头缺少 ‘Access-Control-Allow-Origin’)。
这是一种跨域问题。访问的域名和端口和原来的请求不同,请求就会被限制
跨域:指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对js施加的安全限制。(ajax可以)
同源策略:是指协议,域名,端囗都要相同,其中有一个不同都会产生跨域;
GulimallCorsConfiguration
类,该类用来做过滤,允许所有的请求跨域。【注意】需要把renren-fast的跨域注解掉,因为先走我们网关跨域再走renrne-fast就重复了,然后就成功解决跨域/**
* @author ljy
* @version 1.0.0
* @Description TODO
* @createTime 2021年12月12日 22:46:00
*/
@Configuration // gateway
public class GulimallCorsConfiguration {
@Bean // 添加过滤器
public CorsWebFilter corsWebFilter(){
// 基于url跨域,选择reactive包下的
UrlBasedCorsConfigurationSource source=new UrlBasedCorsConfigurationSource();
// 跨域配置信息
CorsConfiguration corsConfiguration = new CorsConfiguration();
// 允许跨域的头
corsConfiguration.addAllowedHeader("*");
// 允许跨域的请求方式
corsConfiguration.addAllowedMethod("*");
// 允许跨域的请求来源
// corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedOriginPattern("*");
// 是否允许携带cookie跨域
corsConfiguration.setAllowCredentials(true);
// 任意url都要进行跨域配置
source.registerCorsConfiguration("/**",corsConfiguration);
return new CorsWebFilter(source);
}
}
1、编写配置文件,加上配置中心地址和服务名称
2、添加注解@EnableDiscoveryClient
3、添加spring-cloud-starter-alibaba-nacos-discovery服务发现依赖
- id: product_route
uri: lb://gulimall-product
predicates:
- Path=/api/product/**
filters:
- RewritePath=/api/(?<segment>.*),/${segment}
再访问http://localhost:88/api/product/category/list/tree,数据正常出现,数据正常显示,就应该编写页面了
<template>
<!-- :dataA="data" 表示dataA跟我们组件中的data进行绑定-->
<el-tree
:data="menus"
:props="defaultProps"
>
</el-tree>
</template>
<script>
export default {
data() {
return {
menus: [], // 请求后端返回的数据
defaultProps: {
children: "children", // 表示children显示data的children属性
label: "name", // label指的是显示数据中的哪个属性这里就显示data中的name属性,这些label、children都可以在官方文档 中查看的
},
};
},
methods: {
getMenus(data) {
// 自定义方法
this.$http({
// htpp请求
url: this.$http.adornUrl("/product/category/list/tree"), // 请求后端的接口
method: "get",
// }).then((data) => { 由于我们的data是一个对象,我们只需要拿到其中的data属性的数据,所以要把data对象解构出来
}).then(({ data }) => {
// 成功了之后的操作
// console.log("请求数据," + data); +号不能显示出数据
// console.log("请求数据," , data); ,才可以显示出数据
console.log("请求数据,", data.data); // 解构data对象取出data属性
this.menus = data.data; // 将后端取出的数据给到组件中的menus属性
});
}
},
created() {
// 加载组件的时候就调用改方法
this.getMenus();
},
};
</script>
<style lang="scss" scoped>
</style>
/**
* 删除
* @RequestBody 获取到请求体里面的内容,必须发送Post请求
* springMVC会自动将请求体的数据(json),转为对应的对象(Long[])
*/
@RequestMapping("/delete")
public R delete(@RequestBody Long[] catIds){
// categoryService.removeByIds(Arrays.asList(catIds));
// 删除之前需要判断待删除的菜单那是否被别的地方所引用。
categoryService.removeMenuByIds(Arrays.asList(catIds));
return R.ok();
}
@Override
public void removeMenuByIds(List<Long> asList) {
// TODO 先检查当前的菜单是否被别的地方所引用
// TODO表示代办事项,以后可以直接在最下方查看代办
// 开发期间多用逻辑删除:使用字段来标识
baseMapper.deleteBatchIds(asList);
}
1、配置mybatis-plus
# MapperScan
# sql映射文件位置
mybatis-plus:
mapper-locations: classpath:/mapper/**/*.xml
global-config:
db-config:
id-type: auto
logic-delete-value: 1 # 表示逻辑已删除
logic-not-delete-value: 0
2、添加注解@TableLogic
/**
* 是否显示[0-不显示,1显示],由于我们数据库和mybatis-plus规则相反,所以我们自己定义逻辑删除,1表示未删除
*/
@TableLogic(value = "1",delval = "0")
private Integer showStatus;
http://localhost:88/api/product/category/delete
logging:
level:
com.liu.gulimall: debug
==> Preparing: UPDATE pms_category SET show_status=0 WHERE cat_id IN ( ? ) AND show_status=1
==> Parameters: 1000(Long)
<== Updates: 1
避免误操作,是否开启拖拽需要设置一个按钮switch标签来确定
可以直接拖动每一分类来改变每一分类的顺序,以及其父和子分类,并且需要判断是否可以拖拽到此分类
官网:拖拽完成触发方法,不同拖拽,会有不同的父id,确定拖拽的新顺序,将所有改动的分类都放到一个数组里面
由于不能反复请求后端,设置批量保存按钮,触发事件请求后端,将数组传给后端
弹出提示,刷新页面,展开所有的父分类,并将数组置空
<template>
<div>
<el-switch
v-model="draggable"
active-text="开启拖拽"
inactive-text="关闭拖拽"
>
</el-switch>
<el-button @click="batchSave()" v-if="draggable">批量保存</el-button>
<el-button type="danger" @click="batchDelete">批量删除</el-button>
<!-- :dataA="data" 表示dataA跟我们组件中的data进行绑定-->
<!-- :expand-on-click-node表示禁止网上冒泡,官网都有解释,直接在官网ctrl+f搜索即可 -->
<!--el-tree中的 @node-click="handleNodeClick" 删除没什么用-->
<!-- show-checkbox表示该标签是否可以被选中 -->
<!-- node-key表示每个节点的唯一标识,catId是我们各个data中唯一的属性,也就是数据库中的主键 -->
<!-- :default-expanded-keys表示动态绑定需要展开的节点id,因为当我们删除的时候,不想让父节点折叠起来,所以定义让删除节点的父节点都展开 -->
<!-- :draggable="draggable"是否可以拖动-->
<!-- :allow-drop="allowDrop"是否允许拖动比如层级关系等等。有三个情况,分别表示放置在目标节点前、插入至目标节点和放置在目标节点后, -->
<!-- @node-drop拖拽成功触发的方法-->
<!-- ref="menuTree" 方便指定是哪个组件,主要是批量删除的时候用到 -->
<el-tree
node-key="catId"
show-checkbox
:data="menus"
:props="defaultProps"
:expand-on-click-node="false"
:default-expanded-keys="expandedKey"
:draggable="draggable"
:allow-drop="allowDrop"
@node-drop="handleDrop()"
ref="menuTree"
>
<!-- 官网找的span slot-scope插槽机制,每一个元素后面都会格外加上是这个span-->
<!-- node代表当前的节点也即是对象,node.label就是当前节点的name,data就是此节点的数据 -->
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}</span>
<span>
<!-- @click点击就会跳转到我们的方法-->
<!-- 由于只要一级二级才有append操作,所以加上v-if="node.level<=2",node的level<=2表示为一二级-->
<el-button
v-if="node.level <= 2"
type="text"
size="mini"
@click="() => append(data)"
>
Append
</el-button>
<!-- 自己定义修改按钮,每一个菜单都要显示 -->
<el-button type="text" size="mini" @click="edit(data)">
Edit
</el-button>
<!--childNodes是node的子节点数组属性, v-if="node.childNodes==0"表示没有子节点才有delete按钮 -->
<el-button
v-if="node.childNodes == 0"
type="text"
size="mini"
@click="() => remove(node, data)"
>
Delete
</el-button>
</span>
</span>
</el-tree>
<!-- :visible.sync 为true显示该弹框 -->
<!-- close-on-click-modal 是否点击弹框外边就会让弹框消失 -->
<el-dialog
:title="title"
:visible.sync="dialogVisible"
width="30%"
:close-on-click-modal="false"
>
<!-- 弹框嵌套 官网 model表单绑定对象 category我们自己的分类对象-->
<el-form :model="category">
<el-form-item label="分类名">
<el-input v-model="category.name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="图标">
<el-input v-model="category.icon" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="计量单位">
<el-input
v-model="category.productUnit"
autocomplete="off"
></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<!-- 取消就把他设为false即可 -->
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="submitData()">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
data() {
return {
pCid: [],
// 是否可以拖动
draggable: false,
updateNodes: [],
// 最大的层级
maxLevel: 0,
// 弹框的标题
title: "",
// 弹框的类型,因为修改和添加复用一个弹框
dialogType: "",
// 添加的分类对象
category: {
// 里面的属性都是根据后端数据库中来定义的
name: "",
parentCid: 0,
catLevel: 0,
showStatus: 1,
sort: 0,
catId: null,
icon: "",
productUnit: "",
}, // 表单对象
// 是否弹框,默认为false
dialogVisible: false,
// 需要展开的id
expandedKey: [],
// 分类对象
menus: [],
defaultProps: {
children: "children", // 表示children显示data的children属性
label: "name", // label指的是显示数据中的哪个属性这里就显示data中的name属性,这些label、children都可以在官方文档中查看的
},
};
},
methods: {
// 批量删除
batchDelete() {
let catIds = [];
// 拿到组件menuTree
let checkedNodes = this.$refs.menuTree.getCheckedNodes();
console.log("被选中的元素", checkedNodes);
for (let i = 0; i < checkedNodes.length; i++) {
catIds.push(checkedNodes[i].catId);
}
this.$confirm(`是否批量删除【${catIds}】菜单?`, "提示", {
confirmButtonText: "确定", // 点击确定就调用then
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
this.$http({
url: this.$http.adornUrl("/product/category/delete"),
method: "post",
data: this.$http.adornData(catIds, false),
})
.then(({ data }) => {
this.$message({
type: "success",
message: "菜单批量删除成功!",
});
// 刷新出新的菜单
this.getMenus();
})
.catch(() => {});
})
.catch(() => {});
},
// 批量修改
batchSave() {
this.$http({
url: this.$http.adornUrl("/product/category/update/sort"),
method: "post",
data: this.$http.adornData(this.updateNodes, false),
})
.then(({ data }) => {
this.$message({
type: "success",
message: "菜单顺序修改成功!",
});
// 刷新出新的菜单
this.getMenus();
// 设置需要默认展开的菜单
this.expandedKey = this.pCid;
this.updateNodes = [];
this.maxLevel = 0;
// this.pCid = 0;
})
.catch(() => {});
},
// 拖拽完成触发方法,draggingNode当前拖拽的节点,拖拽到哪个节点dropNode,dropType类型:前面,后面,里面
handleDrop(draggingNode, dropNode, dropType, ev) {
console.log("handleDrop: ", draggingNode, dropNode, dropType);
//1 当前节点最新的父节点
let pCid = 0;
let siblings = null;
// 不同拖拽,会有不同的父id
if (dropType == "before" || dropType == "after") {
pCid =
dropNode.parent.data.catId == undefined
? 0
: dropNode.parent.data.catId;
siblings = dropNode.parent.childNodes;
} else {
pCid = dropNode.data.catId;
siblings = dropNode.childNodes;
}
this.pCid.push(pCid);
//2 当前拖拽节点的最新顺序
for (let i = 0; i < siblings.length; i++) {
if (siblings[i].data.catId == draggingNode.data.catId) {
// 如果遍历的是当前正在拖拽的节点
let catLevel = draggingNode.level;
if (siblings[i].level != draggingNode.level) {
// 当前节点的层级发生变化
catLevel = siblings[i].level;
// 修改他子节点的层级
this.updateChildNodeLevlel(siblings[i]);
}
this.updateNodes.push({
catId: siblings[i].data.catId,
sort: i,
parentCid: pCid,
catLevel: catLevel,
});
} else {
this.updateNodes.push({ catId: siblings[i].data.catId, sort: i });
}
}
//3 当前拖拽节点的最新层级
console.log("updateNodes", this.updateNodes);
},
updateChildNodeLevlel(node) {
if (node.childNodes.length > 0) {
for (let i = 0; i < node.childNodes.length; i++) {
var cNode = node.childNodes[i].data;
this.updateNodes.push({
catId: cNode.catId,
catLevel: node.childNodes[i].level,
});
this.updateChildNodeLevlel(node.childNodes[i]);
}
}
},
// 判断是否可以拖动
allowDrop(draggingNode, dropNode, type) {
//1 被拖动的当前节点以及所在的父节点总层数不能大于3
//1 被拖动的当前节点总层数
// draggingNode当前正在拖动的节点
// dropNode 拖到哪个节点,也就是draggingNode和dropNode同级
console.log("allowDrop:", draggingNode, dropNode, type);
// 返回总层数
var level = this.countNodeLevel(draggingNode);
// 当前正在拖动的节点+父节点所在的深度不大于3即可
// draggingNode.level表示层级一级标题为1,三级标题为3
// 当前深度
let deep = Math.abs(this.maxLevel - draggingNode.level) + 1;
console.log("this.maxLevel", this.maxLevel);
console.log("深度:", deep);
// this.maxLevel
// innner表示拖到里面
if (type == "innner") {
// console.log(
// `this.maxLevel: ${this.maxLevel}; draggingNode.data.catLevel:${draggingNode.data.catLevel};dropNode.level: ${dropNode.level}`
// );
return deep + dropNode.level <= 3;
} else {
return deep + dropNode.parent.level <= 3;
}
},
countNodeLevel(node) {
// 找到所有子节点,求出最大深度
// 如果当前节点不为null,并且有子节点
if (node.childNodes != null && node.childNodes.length > 0) {
for (let i = 0; i < node.childNodes.length; i++) {
// 找到最大的深度
if (node.childNodes[i].level > this.maxLevel) {
this.maxLevel = node.childNodes[i].level;
}
this.countNodeLevel(node.childNodes);
}
}
},
// 获取所有的菜单
getMenus(data) {
// 自定义方法
this.$http({
// htpp请求
url: this.$http.adornUrl("/product/category/list/tree"), // 请求后端的接口
method: "get",
// }).then((data) => { 由于我们的data是一个对象,我们只需要拿到其中的data属性的数据,所以要把data对象解构出来
}).then(({ data }) => {
// 成功了之后的操作
// console.log("请求数据," + data); +号不能显示出数据
// console.log("请求数据," , data); ,才可以显示出数据
console.log("请求数据,", data.data); // 解构data对象取出data属性
this.menus = data.data; // 将后端取出的数据给到组件中的menus属性
});
},
// 添加分类方法
addCategory() {
console.log("提交的三级分类数据", this.category);
// 提交对象到后端,给后端发请求
this.$http({
url: this.$http.adornUrl("/product/category/save"),
method: "post",
data: this.$http.adornData(this.category, false),
}).then(({ data }) => {
// 提交成功
this.$message({
message: "保存成功",
type: "success",
});
// 保存完后,关闭弹框
this.dialogVisible = false;
// 刷新出新的菜单
this.getMenus();
// 展开添加菜单的父菜单
this.expandedKey = [this.category.parentCid];
});
},
// 修改分类数据
editCategory() {
// 只往后端发需要更新的数据,没有发送的数据为null后端则不会更新
// 从category取出数据,解构对象!
var { catId, name, icon, productUnit } = this.category;
this.$http({
url: this.$http.adornUrl("/product/category/update"),
method: "post",
// 这些数据都是对应的后端实体字段
data: this.$http.adornData({ catId, name, icon, productUnit }, false),
})
.then(({ data }) => {
this.$message({
type: "success",
message: "菜单修改成功!",
});
// 关闭对话框
this.dialogVisible = false;
// 刷新出新的菜单
this.getMenus();
// 设置需要默认展开的菜单
this.expandedKey = [this.category.parentCid];
})
.catch(() => {});
},
submitData() {
if (this.dialogType == "add") {
this.addCategory();
}
if (this.dialogType == "edit") {
this.editCategory();
}
},
append(data) {
console.log("append----", data);
// 打开弹框
this.dialogVisible = true;
this.dialogType = "add"; // 将弹框类型变为添加
this.title = "添加分类";
// 取出当前节点的一些属性赋给要填加的节点
this.category.parentCid = data.catId; // 父id
this.category.catLevel = data.catLevel * 1 + 1; // 层级
// 由于我们修改过后的category回显时设置了属性,所以我们添加的时候要清空这些属性,让他等于默认值
this.category.catId = null; // 为null,表示后端添加的时候不加上id,自增
this.category.name = null;
this.category.icon = "";
this.category.productUnit = "";
this.category.sort = 0;
this.category.showStatus = 1;
//
this.dialogVisible = true;
},
edit(data) {
console.log("要修改的数据", data);
// 将弹框类型变为修改
this.dialogType = "edit";
this.title = "修改分类";
// 打开弹框
this.dialogVisible = true;
// 修改框内显示要修改的name
this.category.name = data.name;
// 发送请求获取节点最新的数据,因为有并发
this.$http({
url: this.$http.adornUrl(`/product/category/info/${data.catId}`),
method: "get",
}).then(({ data }) => {
// 请求成功 这个data是从服务器拿过来的data
console.log("要回显得数据", data);
// 因为服务器返回的data是数据对象,里面还有一个data才是分类对象,所以data.data.name
this.category.name = data.data.name;
this.category.catId = data.data.catId;
this.category.icon = data.data.icon;
this.category.productUnit = data.data.productUnit;
//由于修改完后要展开父菜单,所以把父id也回显
this.category.parentCid = data.data.parentCid;
//
this.dialogVisible = true;
});
},
remove(node, data) {
// 定义我们要删除的id数组,data.catId数据的id,也就是数据库中的id
var ids = [data.catId];
// 在删除之前显示一个弹框,官网
this.$confirm(`此操作将永久删除【${data.name}】文件, 是否继续?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
// 确定删除才会真正请求删除业务
// 模仿renrne-vue的Post请求写法即可
this.$http({
// adornUrl是renrne-vue定义的工具类:renren-fast-vuesrcutilshttpRequest.js
url: this.$http.adornUrl("/product/category/delete"), // 请求的地址
method: "post", // 发送Post请求
data: this.$http.adornData(ids, false),
}).then((data) => {
// 删除成功,发送一个消息提示
this.$message({
message: "恭喜你,删除成功",
type: "success",
});
// 删除成功后,要刷新页面
this.getMenus(); // 重新请求方法,就会获取到最新的menus,然而el-tree又和menus是双向绑定的,所以会实时切换
// 刷新后我们想要展开刚才被删除的节点的父结点
// node当前节点,中有个parent属性里面放的是父节点的内容,父节点中的data就是父节点的数据对象,然后再拿到父节点的id即可
this.expandedKey = [node.parent.data.catId];
});
})
.catch(() => {
console.log("取消删除");
});
console.log(node, data); // 打印当前结点和当前数据
},
},
created() {
// 加载组件的时候就调用改方法
this.getMenus();
},
};
</script>
<style lang="scss" scoped>
</style>
"http-get请求": {
"prefix": "httpget",
"body": [
"this.\$http({",
"url: this.\$http.adornUrl(''),",
"method: 'get',",
"params: this.\$http.adornParams({})",
"}).then(({ data }) => {",
"})"
],
"description": "httpGet请求"
},
"http-post请求": {
"prefix": "httppost",
"body": [
"this.\$http({",
"url: this.\$http.adornUrl(''),",
"method: 'post',",
"data: this.\$http.adornData(data, false)",
"}).then(({ data }) => { });"
],
"description": "httpPOST请求"
}
以上是脚本宝典为你收集整理的谷粒商城_04_商品CRUD全部内容,希望文章能够帮你解决谷粒商城_04_商品CRUD所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。