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