翼度科技»论坛 编程开发 JavaScript 查看内容

vue elementui异步给dom赋值无效问题

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
vue elementui异步给dom赋值无效

最近在研究el-admin,角色管理里面有个功能是点击左侧的表格里面的一个角色,右侧的树就会自动初始化。
于是我在点击的方法里面,去后台异步调用了一下接口,然后返回数据并把数据赋值给menuIds,但是我发现这个异步请求获取到的数据压根就不能让树控件刷新。
代码如下:
我是在handleCurrentChange里面操作的,网上说通过push方法能够起作用,但是根本没用,最后我的解决方法如下,先将ids都存储起来,然后再在nextTick方法里面去给menuIds赋值。
  1. async initMenus(val) {
  2.       this.menuIds = []
  3.       const AV = window.AV
  4.       const role = AV.Object.createWithoutData('Role', val.objectId);
  5.       const roleMenuQuery = new AV.Query('RoleMenu');
  6.       roleMenuQuery.equalTo("role", role)
  7.       roleMenuQuery.include("menu")
  8.       var roleMenus = await roleMenuQuery.find()
  9.       var ids = [];
  10.       roleMenus.forEach(roleMenu => {
  11.         var roleMenuJson = roleMenu.toJSON()
  12.         ids.push(roleMenuJson.menu.menuId)
  13.       })
  14.       this.$nextTick(() => {
  15.         this.menuIds = ids;
  16.       })
  17.       // https://blog.csdn.net/xudalin/article/details/103158941
  18.       // 这个代码解决了树控件的半选问题。参考链接如上
  19.       /*ids.forEach((i, n) => {
  20.         var node = this.$refs.menu.getNode(i);
  21.         console.log(node.isLeaf)
  22.         if (node.isLeaf) {
  23.           this.$refs.menu.setChecked(node, true);
  24.         }
  25.       });*/
  26.     },
  27.     // 触发单选
  28.     handleCurrentChange(val) {
  29.       console.log("handleCurrentChange")
  30.       if (val) {
  31.         const _this = this
  32.         // 清空菜单的选中
  33.         this.$refs.menu.setCheckedKeys([])
  34.         // 保存当前的角色id
  35.         this.currentId = val.id
  36.         // this.showButton = this.level <= val.level
  37.         // 初始化
  38.         this.initMenus(val)
  39.         // 菜单数据需要特殊处理
  40.         /*val.menus.forEach(function (data, index) {
  41.           _this.menuIds.push(data.id)
  42.         })*/
  43.       }
  44.     },
复制代码
vue elementui前端异步方法转同步

elementui的表单验证功能

表单验证方法如果传入回调函数时是异步的
  1. // 子组件的方法
  2. validateForm(){
  3.       this.$refs.jsonEditor.getRef("form").validate((valid, hints) => {
  4.         return {valid: valid, hints: hints}
  5.       })
  6. }

  7. // 父组件调用,会发现校验结果,hints为undefine
  8. submitAll(){
  9.       this.$refs.resourceEditorRef.forEach((item, index) => {
  10.         console.log(item.validateForm())
  11.       })
  12. }
复制代码
修改成同步的
  1. // 子组件方法
  2. validateForm(){
  3.       // this.$refs.jsonEditor.getRef("form").validate((valid, hints) => {
  4.       //   return {valid: valid, hints: hints}
  5.       // })
  6.       // return new Promise((resolve, reject) => {
  7.       //   this.$refs.jsonEditor.getRef("form").validate((valid, hints) => {
  8.       //     resolve({valid, hints})
  9.       //   })
  10.       // })
  11.       //或者根据官网文档说明可以不传入回调函数,直接validate
  12.       return this.$refs.jsonEditor.getRef("form").validate
  13.     },

  14. // 父组件调用
  15. submitAll(){
  16.       // this.$refs.resourceEditorRef.forEach((item, index) => {
  17.       //   console.log("校验结果", item.validateForm())
  18.       // })
  19.       this.$refs.resourceEditorRef.forEach(async (item, index) => {
  20.         let {valid, hints} = await item.validateForm()
  21.         console.info(valid, hints)
  22.         console.log("校验结果", hints)
  23.       })
  24. }
复制代码
但是其实上面 submitAll 的 forEach 是有问题, 需要改成传统的for遍历, 因为 forEach 的入参是一个回调函数 , 简单的说就是执行 forEach 后会马上执行forEach后面的代码

所以修改成普通的for , 使用普通 for 循环的时候有需要多包一层
  1. // 子组件方法
  2. validateForm(){
  3.       //或者根据官网文档说明可以不传入回调函数,直接validate
  4.       return this.$refs.jsonEditor.getRef("form").validate
  5.     }

  6. //父组件调用
  7. submitAll(){
  8.       (async () => {
  9.         let submitAllForm = {};
  10.         for (let index = 0; index < this.$refs.resourceEditorRef.length; index++) {
  11.           const item = this.$refs.resourceEditorRef[index]
  12.           await item.validateForm().then(res => {
  13.             console.log("表单校验",res)
  14.           }).catch(res => {
  15.             console.log("表单校验catch",res)
  16.             if(res == false){
  17.               this.$message({ type: "error", message: "表单校验失败" });
  18.               // 有一个校验失败则直接返回
  19.               return;
  20.             }
  21.           })
  22.         }
  23.         //后续操作
  24.         
  25.       })()
  26. }
复制代码
或者
  1. // 子组件方法
  2. validateForm(){
  3.       return new Promise((resolve, reject) => {
  4.         this.$refs.jsonEditor.getRef("form").validate((valid, hints) => {
  5.           resolve({valid, hints})
  6.         })
  7.       })
  8. }

  9. // 父调用
  10. submitAll(){
  11.       (async () => {
  12.         let submitAllForm = {};
  13.         for (let index = 0; index < this.$refs.resourceEditorRef.length; index++) {
  14.           const item = this.$refs.resourceEditorRef[index]
  15.           let {valid, hints} = await item.validateForm();
  16.           console.log("表单校验valid",valid)
  17.           console.log("表单校验hints",hints)
  18.           debugger
  19.         }
  20.         //后续操作
  21.         debugger
  22.       })()
  23. }
复制代码
总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

来源:https://www.jb51.net/javascript/322372wvn.htm
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具