成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

用這招監聽 Vue 的插槽變化

開發 前端
最近,每當組件的內容(插槽、子組件等)發生變化時,我需要更新它的狀態。對于上下文,它是一個表單組件,用于跟蹤其輸入的有效性狀態。

[[421396]]

 最近,每當組件的內容(插槽、子組件等)發生變化時,我需要更新它的狀態。對于上下文,它是一個表單組件,用于跟蹤其輸入的有效性狀態。

下面的代碼片段是以Options API格式編寫的,但除了指定的地方外可以在Vue2 和 Vue2中使用。

開始

先從控制表單狀態開始,根據狀態修改一個類,孩子內容使用填充:

  1. <template> 
  2.   <form :class="{ '--invalid': isInvalid }"
  3.     <slot /> 
  4.   </form> 
  5. </template> 
  6.  
  7. <script> 
  8. export default { 
  9.   data: () => ({ 
  10.     isInvalid: false
  11.   }), 
  12. }; 
  13. </script> 

為了更新isInvalid屬性,我們需要添加一個觸發的事件,可以使用 sumit 事件 ,但我更喜用 input 事件。

  • 表單事件7個: focus, blur, input, select, change, reset, submit 等,具體詳解看這篇文章:
  • https://blog.csdn.net/qq_43797996/article/details/103066452

表單不會觸發 input 事件,但我們可以使用 "事件委托"。我們將監聽器附加到父元素(<form>)上,當事件發生在它的子元素(<input>、<select>、<textarea>等)上時就會被觸發。

任何時候在這個組件的<slot>中觸發input事件,表單將捕獲該事件。

  1. <template> 
  2.   <form :class="{ '--invalid': isInvalid }" @input="validate"
  3.     <slot /> 
  4.   </form> 
  5. </template> 
  6.  
  7. <script> 
  8. export default { 
  9.   data: () => ({ 
  10.     isInvalid: false
  11.   }), 
  12.   methods: { 
  13.     validate() { 
  14.       // 驗證邏輯 
  15.     } 
  16.   } 
  17. }; 
  18. </script> 

驗證邏輯可以是簡單或復雜的。本文為了演示,用簡單的方法,使用form.checkValidity() API 來查看表單是否基于HTML驗證屬性而有效。

為了訪問<form>元素。可以用refs或$el屬性。為了簡單起見,本文使用$el。

  1. <template> 
  2.   <form :class="{ '--invalid': isInvalid }" @input="validate"
  3.     <slot /> 
  4.   </form> 
  5. </template> 
  6.  
  7. <script> 
  8. export default { 
  9.   data: () => ({ 
  10.     isInvalid: false
  11.   }), 
  12.   methods: { 
  13.     validate() { 
  14.       this.isInvalid = !this.$el.checkValidity() 
  15.     } 
  16.   } 
  17. }; 
  18. </script> 

問題

這里有一點問題。如果表單的內容改變了,會發生什么?如果一個<input>在表單加載被添加到DOM中,會發生什么?

舉個例子,我們把這個表單組件稱為 "MyForm",在 App 中,內容如下:

  1. // App.vue 
  2. <template> 
  3.   <MyForm> 
  4.     <input 
  5.       v-model="showInput" 
  6.       id="toggle-name" 
  7.       name="toggle-name" 
  8.       type="checkbox" 
  9.     /> 
  10.     <label for="toggle-name">顯示其它 input</label>  
  11.  
  12.     <template v-if="showInput"
  13.       <label for="name">Name:</label> 
  14.       <input id="name" name="name" required /> 
  15.     </template> 
  16.  
  17.     <button type="submit">提交</button> 
  18.   </MyForm> 
  19. </template> 
  20.  
  21. <script> 
  22. import Form from "./components/form.vue"
  23. export default { 
  24.   name"App"
  25.   components: { 
  26.     MyForm: Form, 
  27.   }, 
  28.   data: () => ({ 
  29.     showInput: false
  30.   }), 
  31. }; 
  32. </script> 

當App.vue通過條件來隱藏顯示某些 input,我們的表單需要知道。在這種情況下,我們會想到在表單內容發生變化時跟蹤其有效性,而不僅僅是在 input 事件或mounted生命周期鉤子上。否則,可能會顯示不正確的信息。

熟悉 Vue的生命周期鉤子小伙伴,這里可能會想到使用 update 來跟蹤變化。理論上,這聽起來不錯。在實踐中,它會創造一個無限的循環,然后瀏覽器掛了。

解決方法

經過一番研究和測試,最佳解決方案是使用MutationObserver API。它是瀏覽器內置的方法,提供了監視對DOM樹所做更改的能力,如果節點的增減、屬性的變動、文本內容的變動,這個 API 都可以得到通知。

它是原生的方法,所以不受限于框架。

使用時,首先使用MutationObserver構造函數,新建一個觀察器實例,同時指定這個實例的回調函數。在每次 DOM 變動后調用,這個回調都被調用。該回調函數接受兩個參數,第一個是變動數組,第二個是觀察器實例,將我們的 form 組件改寫成如下:

  1. <template> 
  2.   <form :class="{ '--invalid': isInvalid }" @input="validate"
  3.     <slot /> 
  4.   </form> 
  5. </template> 
  6.  
  7. <script> 
  8. export default { 
  9.   data: () => ({ 
  10.     isInvalid: false
  11.   }), 
  12.   mounted() { 
  13.     const observer = new MutationObserver(this.validate); 
  14.     observer.observe(this.$el, { 
  15.       childList: true
  16.       subtree: true
  17.     }); 
  18.     this.observer = observer; 
  19.   }, 
  20.   methods: { 
  21.     validate() { 
  22.       this.isInvalid = !this.$el.checkValidity(); 
  23.     }, 
  24.   }, 
  25.   beforeUnmount() { 
  26.     this.observer.disconnect(); 
  27.   }, 
  28. }; 
  29. </script> 
  30.  
  31.  
  32. <style scoped> 
  33. </style> 

這里還需要使用 beforeUnmount生命周期事件來斷開observer的連接,這會清除它所分配的任何內存。

最后,我們將isInvalid狀態傳遞給要訪問的內容的插件槽,這也稱作用域的槽,它非常有用。

  1. <template> 
  2.   <form :class="{ '--invalid': isInvalid }" @input="validate"
  3.     <slot v-bind="{ isInvalid }" /> 
  4.   </form> 
  5. </template> 
  6.  
  7. <script> 
  8. export default { 
  9.   data: () => ({ 
  10.     isInvalid: false
  11.   }), 
  12.   mounted() { 
  13.     const observer = new MutationObserver(this.validate); 
  14.     observer.observe(this.$el, { 
  15.       childList: true
  16.       subtree: true
  17.     }); 
  18.     this.observer = observer; 
  19.   }, 
  20.   methods: { 
  21.     validate() { 
  22.       this.isInvalid = !this.$el.checkValidity(); 
  23.     }, 
  24.   }, 
  25.   beforeUnmount() { 
  26.     this.observer.disconnect(); 
  27.   }, 
  28. }; 
  29. </script> 

通過這樣的設置,可以在我們的表單組件中添加任意數量的 input,并添加任何它需要的條件渲染邏輯。只要input使用HTML驗證屬性,表單就會跟蹤它是否處于有效狀態。

此外,由于使用的是作用域槽,我們將表單的狀態提供給父級,所以父級可以對有效性的變化做出反應。

例如,在 App.vue,我們想在表單無效時 "禁用" 提交按鈕,可以這么來寫

  1. <template> 
  2.   <MyForm> 
  3.     <template slot:default="form"
  4.       <label for="name">Name:</label> 
  5.       <input id="name" name="name" required> 
  6.  
  7.       <button 
  8.         type="submit" 
  9.         :class="{ disabled: form.isInvalid }" 
  10.       > 
  11.         Submit 
  12.       </button> 
  13.     </template> 
  14.   </MyForm> 
  15. </template> 

nice~.

希望本文能對你未來的開必有所幫助。

 

責任編輯:姜華 來源: 今日頭條
相關推薦

2023-06-02 07:32:34

localStorage?監聽

2020-05-25 17:03:47

Vue嵌套插槽開發

2021-05-08 07:37:32

Vue 命名插槽

2023-12-14 08:25:14

WatchVue.js監聽數據

2025-03-07 10:10:48

Vue插槽slot

2021-04-14 07:52:00

Vue 作用域插槽

2020-08-10 08:30:35

Vue 數據插槽

2021-12-29 07:51:21

Vue3 插件Vue應用

2025-05-29 01:00:00

文件監聽函數

2016-09-29 08:45:12

vueAPIWeb

2022-07-01 12:00:56

Kubernete網絡模型

2022-07-15 08:45:07

slotVue3

2024-06-03 10:00:51

Vue 3語法插槽

2024-04-10 10:15:16

監聽

2024-09-10 10:04:47

2019-10-15 09:05:07

域插槽組件前端

2021-04-26 07:53:06

DOM前端框架

2013-08-02 15:23:11

2013-08-02 10:39:59

AndroidAPPOS

2023-07-24 16:28:51

@State@Observed裝飾器監聽
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲一二三区不卡 | 日本在线中文 | 久草新在线 | 国产精品大片在线观看 | 精品一区二区三区在线观看国产 | 偷拍自拍在线观看 | 美女福利网站 | 国产精品美女 | 亚洲视频精品 | 视频一区二区三区中文字幕 | 男女视频在线观看 | 高清黄色毛片 | 亚洲不卡av在线 | 黄色三级免费网站 | 九色91视频 | 精品啪啪 | 久久久一二三 | 免费的av网站 | 天天拍天天插 | 99视频入口| 亚洲午夜在线 | www.狠狠操 | 国产视频久久 | 精品国产精品一区二区夜夜嗨 | 视频一区在线观看 | 精品伊人久久 | 一区二区三区四区在线视频 | 亚洲一二三区在线观看 | 成人在线精品视频 | 成人在线观看欧美 | 国产激情偷乱视频一区二区三区 | 国产精品一区在线观看你懂的 | 国产精品免费一区二区三区 | 久草新在线 | 免费黄色在线 | 一区二区三区精品视频 | 91资源在线 | 精品国产18久久久久久二百 | 国产精品一区二区三区久久 | 国产永久免费 | 国产在线观看一区二区 |