vue カスタム命令を使用して、table td コンテンツ要素の z-index 設定が有効にならない問題を解決します

問題の説明

テーブル内でフォームを使用する場合、フォーム コントロールがテーブルの各行の高さの範囲内にある場合、そのエラー メッセージは表示されなくなります。(私のUIライブラリはiviewを使用しています)
フォームプロンプトの内容を表示できません

常に存在する問題と以前の回避策は次のとおりです。

  1. フォーム コントロールのエラー プロンプト距離をそのままにして、フォームの各行を支えます。このようにすると、テーブルの 2 行ごとに大きな隙間ができ、行の内容がずれる問題が発生する可能性があります。
  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>
..省略...

最適化

上記のコードは引き続き最適化できます。

  1. エラーメッセージの表示・非表示は変わりますが、その位置は変わりませんし、一度スタイルを設定すれば、以前のスタイルに戻す必要はありません。したがって、更新時に変更する必要はなく、挿入時にバインディング変更を実行するだけで済みます (挿入を使用する場合は、親要素が存在することを確認してください)。

  2. ここでは、変更する 3 つの要素を見つける必要がありますが、実際には、クラスを作成し、親要素を見つけて<td>、このクラスをそれに追加することができます。

  3. 一部のフォームレベルが同じであることが心配な場合は、パラメータを渡し、そのパラメータに従って変更される親要素を再帰的に見つけることもできます(この点は最適化していません)。

...省略...
Vue.directive('tableformerrorposition', {
    
    
  inserted(el) {
    
    
    // 找到<td>元素
    let parentTdEl = el.parentNode.parentNode.parentNode
    parentTdEl.className += ' update-form-item-error-position'
  },
})
...省略...

最終的な効果を見てみましょう。
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/BAtodl/article/details/114991562