本篇内容介绍了“element中form组件prop嵌套属性问题怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
Introduction
分享今天同事问的一个问题, 下面这段代码会报错,先看代码:重点是el-form-item组件的prop属性
<template> <div id="app"> <el-form label-width="100px" :model="ruleForm" :rules="rules"> <el-form-item v-for="(item, index) in tableData" :key="item.id" :prop="'tableData.' + index + '.name'" :rules="rules.name" > <el-input v-model="item.name"></el-input> </el-form-item> </el-form> </div></template><script>export default { name: "App", data() { return { ruleForm: { name: '' }, tableData: [ { id: 1, name: "" }, { id: 2, name: "" }, ], rules: { name: [ { required: true, message: "请输入活动名称", trigger: "blur", validator(rule, value, callback) { console.log("rule: ", rule); console.log("value: ", value); }, }, ], }, }; },};</script>
我第一眼看上去的时候并没有发现什么问题,但这段代码实实在在的报错了,我们来看一下错误
首先需要明确的是 这是一个警告, 并非一个error, 但他直接导致了我们的代码执行结果非预期,我们来分析一下这个错误
首先这个错误的第一句**Error in mounted hook**, 错误发生在mounted钩子中
请安排一个有效的path给prop
首先第一个问题,我的代码中并没有mounted函数,他怎么会报错呢?
第二个问题,让我们提供一个有效的prop, 但这里我们明明给的是有效的撒。
最后查了官网并查了百度 都没有找到很好的解决方式,最后没有办法,只能去看一下element-ui的源码, 下面是源码环节:
找到packages/form/src/form-item.vue这个文件
我们根据他的报错来分析, 首先他说`mounted hook`中报错, 那我们就直接来看这个hook做了什么事情:
mounted() { if (this.prop) { this.dispatch('ElForm', 'el.form.addField', [this]); // 这一步不用管 let initialValue = this.fieldValue; // 取得fieldvalue // 判断fieldvalue是不是数组, 如果是数组则合并 if (Array.isArray(initialValue)) { initialValue = [].concat(initialValue); } // 给this定义一个initialValue属性 Object.defineProperty(this, 'initialValue', { value: initialValue }); this.addValidateEvents(); }}
我看这段代码的第一反应是, 这也没干什么事儿啊, 就取了个值 赋了个值, 看了一会儿我发现, 有一个盲点就是this.fieldValue
这里, 这是一个什么东西呢?不知道 去看一下。
computed: { fieldValue() { // 1.拿到当前"form"的model属性(这里很重要, 要记住这一步) const model = this.form.model; if (!model || !this.prop) { return; } // 2.拿到当前"form-item"的prop属性, // 也就是我们传的那个:prop="'tableData.' + index + '.name'" let path = this.prop; if (path.indexOf(':') !== -1) { path = path.replace(/:/, '.'); } // 3.将model和path传给了getPropByPath方法 return getPropByPath(model, path, true).v; } }
代码翻到fieldValue
这里, 发现这是一个computed
属性(步骤见注释), 发现最终返回getPropByPath
方法的返回结果, 我们接着去看一下这个方法.
我们发现这个方法是在utils/util
下的一个方法
第一眼看到这个方法, 是不是有一种眼熟的感觉?越看越像js的一个面试题
function getValue(obj, path) { ...}const obj = { a: { b: { c: '1' } } }getValue(obj, 'a.b.c'); // 1
有木有啊! 有木有!不能说一模一样,只能说分毫不差,既然知道它是面试题就简单了,我们首先需要明确 这个方法的作用就是 通过嵌套字符串key 拿到key对应的value, 那我们来看一下element是怎么做的。
首先先看第一句代码let tempObj = obj
, 这里第一次的obj是谁呢?是不是上面传过来的this.form.model
啊? 我们来看一下 我们代码中传输的model是什么
我们这里只需要记住, 我们传的是一个对象{ name: '' }
好的 我们再来看下一步, path = 正则匹配
, 最后的结果是keyArr = ['tableData', 0, 'name']
下面的代码就是走keyArr的循环了, 这里我们是3次循环, 因为keyArr只有三个元素
我们还是来捋一下:
第一次循环, 此时的tempObj是 { name: '' }, key是tableData, key in tempObj?, 很显然是false, 所以直接走了else, 触发了throw new Error
其实看到这里我们就明白了, element在做prop
判断的时候, 是通过判断key
在不在model
中的方式 来判断path
是否合法的, 那我们知道这个原理之后, 只需要将我们的代码稍稍改动一下即可。
我们只需要将tableData
移到ruleForm
中即可, 然后我们再来看控制台已经不报错了。
“element中form组件prop嵌套属性问题怎么解决”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!