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>
我第一眼看上去的時候并沒有發(fā)現什么問題,但這段代碼實實在在的報錯了,我們來看一下錯誤
首先需要明確的是 這是一個警告, 并非一個error, 但他直接導致了我們的代碼執(zhí)行結果非預期,我們來分析一下這個錯誤
1.首先這個錯誤的第一句**Error in mounted hook**, 錯誤發(fā)生在mounted鉤子中
2.請安排一個有效的path給prop
首先第一個問題,我的代碼中并沒有mounted函數,他怎么會報錯呢?
第二個問題,讓我們提供一個有效的prop, 但這里我們明明給的是有效的撒。
最后查了官網并查了百度 都沒有找到很好的解決方式,最后沒有辦法,只能去看一下element-ui的源碼, 下面是源碼環(huán)節(jié):
1.找到packages/form/src/form-item.vue這個文件
2. 我們根據他的報錯來分析, 首先他說`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(); } }
我看這段代碼的第一反應是, 這也沒干什么事兒啊, 就取了個值 賦了個值, 看了一會兒我發(fā)現, 有一個盲點就是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
這里, 發(fā)現這是一個computed
屬性(步驟見注釋), 發(fā)現最終返回getPropByPath
方法的返回結果, 我們接著去看一下這個方法.
我們發(fā)現這個方法是在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是誰呢?是不是上面?zhèn)鬟^來的this.form.model
啊? 我們來看一下 我們代碼中傳輸的model是什么
我們這里只需要記住, 我們傳的是一個對象{ name: '' }
好的 我們再來看下一步, path = 正則匹配
, 最后的結果是keyArr = ['tableData', 0, 'name']
下面的代碼就是走keyArr的循環(huán)了, 這里我們是3次循環(huán), 因為keyArr只有三個元素
我們還是來捋一下:
1. 第一次循環(huán), 此時的tempObj是 { name: '' }, key是tableData, key in tempObj?, 很顯然是false, 所以直接走了else, 觸發(fā)了throw new Error
其實看到這里我們就明白了, element在做prop
判斷的時候, 是通過判斷key
在不在model
中的方式 來判斷path
是否合法的, 那我們知道這個原理之后, 只需要將我們的代碼稍稍改動一下即可。
我們只需要將tableData
移到ruleForm
中即可, 然后我們再來看控制臺已經不報錯了。
總結
我考慮了一下element為什么要這樣做,因為在這樣的前提下,只看文檔 應該不會得到有用的信息, 后來想了一會兒想通了, 因為element要判斷prop
傳遞的值是否合法的話, 就只能用 一個obj
一個key
通過key in obj
這樣的方式來判斷, 而如果我們不把tableData
放到ruleForm
中, form-item
在mounted
的時候 是拿不到外面this
的data
的, 所以他無法判斷 當前傳進來的tableData
到底是誰, 也就沒有辦法使用key in obj
.
到此這篇關于element中form組件prop嵌套屬性的問題解決的文章就介紹到這了,更多相關element form組件prop嵌套內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue el-table字段點擊出現el-input輸入框,失焦保存方式
這篇文章主要介紹了vue el-table字段點擊出現el-input輸入框,失焦保存方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02vue項目打包解決靜態(tài)資源無法加載和路由加載無效(404)問題
這篇文章主要介紹了vue項目打包,解決靜態(tài)資源無法加載和路由加載無效(404)問題,靜態(tài)資源無法使用,那就說明項目打包后,圖片和其他靜態(tài)資源文件相對路徑不對,本文給大家介紹的非常詳細,需要的朋友跟隨小編一起看看吧2023-10-10