問題の説明
テーブル内でフォームを使用する場合、フォーム コントロールがテーブルの各行の高さの範囲内にある場合、そのエラー メッセージは表示されなくなります。(私のUIライブラリはiviewを使用しています)
常に存在する問題と以前の回避策は次のとおりです。
- フォーム コントロールのエラー プロンプト距離をそのままにして、フォームの各行を支えます。このようにすると、テーブルの 2 行ごとに大きな隙間ができ、行の内容がずれる問題が発生する可能性があります。
- エラー プロンプトをフォーム コントロールに配置すると、表示コンテンツに影響を与える場合があります。
もともとうちはどうせミドルエンドのシステムだと思っていて、今回も最初の方法でゴロゴロ進めていくつもりだったのですが、まさか今回の請求書が色付きだとは予想外でしたし、最初の解決策の色は明白すぎるため、製品が 2 番目の解決策を受け入れないため、変更する必要があります。
分析する
1. Zインデックス
このような遮蔽されたコンテンツの場合、最初に Z インデックスを設定してレベルを上げることを考えますが、どのように設定しても Z インデックスは 9999 に等しいため、効果がありません。禿げている。
いろいろ検索した結果、「テーブルの z-index がどのように設定されていても、<td>
テーブルのレベルは<td>
コンテンツ要素のレベルよりも高いです。」と言っている人を見かけました。
それでは、z-index を設定するという私の計画は完全に失敗です。
2. 位置
しかしこれで、日付ピッカーのドロップダウン部分が正常に表示される理由がわかりました。
<body>
日付ピッカーの選択部分は内部で生成されており、相対的な位置関係は当然相対的なものな<body>
ので、テーブル上に浮くのが正常であることがわかります。(実は日付セレクターを前に参考にしようと思っていたのですが、思い出せなくて今思い出しました)
要素を再生成することは不可能でしたが、位置決めを使用することで別のアイデアが得られました。
エラープロンプトの位置参照を親要素から に変更した場合、日付ピッカーの選択部分と同様に計算された位置を介して表示する<body>
こともできますか?<body>
OK!次に、まずブラウザで変更してみます。
まず、エラー メッセージ ( ) の.ivu-form-item-error-tip
親要素 ( ).ivu-form-item-content
の絶対位置を解除し、.ivu-form-item-error-tip
検索しやすいように、top 属性と left 属性を 0 に変更します。この時点で絶対位置決めが設定されており、位置が変更されたこと.ivu-form-item-error-tip
が分かります。.ivu-table-wrapper
top 属性を再度変更する.ivu-form-item-error-tip
と、テーブルの 2 行の間に正常に表示できることがわかります。これは、この解決策に問題がないことが証明されており、次のように実行できます。
コードを変更して効果をテストする
複数の要素を操作する場合、メソッドが同じ場合は、vue のカスタム命令を使用するのが最も便利です。(Vue カスタム ディレクティブについては詳しく説明しません。公式 Web サイトを参照してください: https://cn.vuejs.org/v2/guide/custom-directive.html )
エラーメッセージが表示された場合に、対応する複数の要素のスタイルを変更する命令を定義しv-tableformerrorposition
、vueに登録する
...省略...
Vue.directive('tableformerrorposition', {
update: function(el) {
const classList = el.getAttribute('class').split(' ')
// 判断是否出现错误提示
if (classList.includes('ivu-form-item-error')) {
// 这是ivu-form-item-content
let contentEl = el.children[0]
// 这是ivu-form-item-error-tip
let errTipEl = contentEl.children[1]
// 在浏览器测试时找到`<table>`去设置定位还是太麻烦,可以尝试找到父级表格`<td>`去修改定位,这里就直接找到<td>元素
let parentTdEl = el.parentNode.parentNode.parentNode
// ivu-form-item-content取消绝对定位
contentEl.setAttribute('style', 'position:static;')
// <td>加上绝对定位
parentTdEl.setAttribute('style', 'position:relative;')
// ivu-form-item-error-tip调整相对定位距离
errTipEl.setAttribute('style', 'top:44px;')
}
},
})
...省略...
ページ上でディレクティブを使用する
...省略...
<Form ref="chargForm" :model="chargForm" :label-width="120">
<Table class="table-list" :columns="chargColumns" max-height="600" :data="chargForm.list">
<template slot-scope="{ index }" slot="firstMonths">
<FormItem
label=""
:label-width="0"
:prop="'list.' + index + '.firstMonths'"
v-tableformerrorposition
>
<Input v-model="xxx" />
</FormItem>
</template>
</Table>
</Form>
..省略...
最適化
上記のコードは引き続き最適化できます。
-
エラーメッセージの表示・非表示は変わりますが、その位置は変わりませんし、一度スタイルを設定すれば、以前のスタイルに戻す必要はありません。したがって、更新時に変更する必要はなく、挿入時にバインディング変更を実行するだけで済みます (挿入を使用する場合は、親要素が存在することを確認してください)。
-
ここでは、変更する 3 つの要素を見つける必要がありますが、実際には、クラスを作成し、親要素を見つけて
<td>
、このクラスをそれに追加することができます。 -
一部のフォームレベルが同じであることが心配な場合は、パラメータを渡し、そのパラメータに従って変更される親要素を再帰的に見つけることもできます(この点は最適化していません)。
...省略...
Vue.directive('tableformerrorposition', {
inserted(el) {
// 找到<td>元素
let parentTdEl = el.parentNode.parentNode.parentNode
parentTdEl.className += ' update-form-item-error-position'
},
})
...省略...
最終的な効果を見てみましょう。