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ā)現(xiàn)什么問題,但這段代碼實實在在的報錯了,我們來看一下錯誤
首先需要明確的是 這是一個警告, 并非一個error, 但他直接導(dǎo)致了我們的代碼執(zhí)行結(jié)果非預(yù)期,我們來分析一下這個錯誤
1.首先這個錯誤的第一句**Error in mounted hook**, 錯誤發(fā)生在mounted鉤子中
2.請安排一個有效的path給prop
首先第一個問題,我的代碼中并沒有mounted函數(shù),他怎么會報錯呢?
第二個問題,讓我們提供一個有效的prop, 但這里我們明明給的是有效的撒。
最后查了官網(wǎng)并查了百度 都沒有找到很好的解決方式,最后沒有辦法,只能去看一下element-ui的源碼, 下面是源碼環(huán)節(jié):
1.找到packages/form/src/form-item.vue這個文件
2. 我們根據(jù)他的報錯來分析, 首先他說`mounted hook`中報錯, 那我們就直接來看這個hook做了什么事情:
mounted() { if (this.prop) { this.dispatch('ElForm', 'el.form.addField', [this]); // 這一步不用管 let initialValue = this.fieldValue; // 取得fieldvalue // 判斷fieldvalue是不是數(shù)組, 如果是數(shù)組則合并 if (Array.isArray(initialValue)) { initialValue = [].concat(initialValue); } // 給this定義一個initialValue屬性 Object.defineProperty(this, 'initialValue', { value: initialValue }); this.addValidateEvents(); } }
我看這段代碼的第一反應(yīng)是, 這也沒干什么事兒啊, 就取了個值 賦了個值, 看了一會兒我發(fā)現(xiàn), 有一個盲點就是this.fieldValue
這里, 這是一個什么東西呢?不知道 去看一下。
computed: { fieldValue() { // 1.拿到當(dāng)前"form"的model屬性(這里很重要, 要記住這一步) const model = this.form.model; if (!model || !this.prop) { return; } // 2.拿到當(dāng)前"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ā)現(xiàn)這是一個computed
屬性(步驟見注釋), 發(fā)現(xiàn)最終返回getPropByPath
方法的返回結(jié)果, 我們接著去看一下這個方法.
我們發(fā)現(xiàn)這個方法是在utils/util
下的一個方法
第一眼看到這個方法, 是不是有一種眼熟的感覺?越看越像js的一個面試題
function getValue(obj, path) { ... } const obj = { a: { b: { c: '1' } } } getValue(obj, 'a.b.c'); // 1
有木有??! 有木有!不能說一模一樣,只能說分毫不差,既然知道它是面試題就簡單了,我們首先需要明確 這個方法的作用就是 通過嵌套字符串key 拿到key對應(yīng)的value, 那我們來看一下element是怎么做的。
首先先看第一句代碼let tempObj = obj
, 這里第一次的obj是誰呢?是不是上面?zhèn)鬟^來的this.form.model
啊? 我們來看一下 我們代碼中傳輸?shù)膍odel是什么
我們這里只需要記住, 我們傳的是一個對象{ name: '' }
好的 我們再來看下一步, path = 正則匹配
, 最后的結(jié)果是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
中即可, 然后我們再來看控制臺已經(jīng)不報錯了。
總結(jié)
我考慮了一下element為什么要這樣做,因為在這樣的前提下,只看文檔 應(yīng)該不會得到有用的信息, 后來想了一會兒想通了, 因為element要判斷prop
傳遞的值是否合法的話, 就只能用 一個obj
一個key
通過key in obj
這樣的方式來判斷, 而如果我們不把tableData
放到ruleForm
中, form-item
在mounted
的時候 是拿不到外面this
的data
的, 所以他無法判斷 當(dāng)前傳進來的tableData
到底是誰, 也就沒有辦法使用key in obj
.
到此這篇關(guān)于element中form組件prop嵌套屬性的問題解決的文章就介紹到這了,更多相關(guān)element form組件prop嵌套內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
仿ElementUI實現(xiàn)一個Form表單的實現(xiàn)代碼
這篇文章主要介紹了仿ElementUI實現(xiàn)一個Form表單的實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04vue el-table字段點擊出現(xiàn)el-input輸入框,失焦保存方式
這篇文章主要介紹了vue el-table字段點擊出現(xiàn)el-input輸入框,失焦保存方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02el-table?fixed固定列導(dǎo)致錯位的解決方法介紹
ElementUI中el-table設(shè)置指定列固定不動,不受滾動條影響,下面這篇文章主要給大家介紹了關(guān)于el-table?fixed固定列導(dǎo)致錯位的解決方法,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-11-11ElementUI日期選擇器時間選擇范圍限制的實現(xiàn)
在日常開發(fā)中,我們會遇到一些情況,限制日期的范圍的選擇,本文就詳細的介紹了ElementUI日期選擇器時間選擇范圍限制的實現(xiàn),文中通過示例代碼介紹的非常詳細,感興趣的可以了解一下2022-04-04vue項目打包解決靜態(tài)資源無法加載和路由加載無效(404)問題
這篇文章主要介紹了vue項目打包,解決靜態(tài)資源無法加載和路由加載無效(404)問題,靜態(tài)資源無法使用,那就說明項目打包后,圖片和其他靜態(tài)資源文件相對路徑不對,本文給大家介紹的非常詳細,需要的朋友跟隨小編一起看看吧2023-10-10Vue計算屬性與監(jiān)視屬性實現(xiàn)方法詳解
最近在學(xué)習(xí)vue,學(xué)習(xí)中遇到了一些感覺挺重要的知識點,感覺有必要整理下來,這篇文章主要給大家介紹了關(guān)于Vue.js中計算屬性、監(jiān)視屬性的相關(guān)資料,需要的朋友可以參考下2022-08-08