亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

vue2之響應(yīng)式雙向綁定,在對象或數(shù)組新增屬性頁面無響應(yīng)的情況

 更新時間:2023年04月20日 15:50:11   作者:潮汐未見潮落  
這篇文章主要介紹了vue2之響應(yīng)式雙向綁定,在對象或數(shù)組新增屬性頁面無響應(yīng)的情況及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

vue2響應(yīng)式雙向綁定,在對象或數(shù)組新增屬性頁面無響應(yīng)

問題描述

vue2 中可以將數(shù)據(jù)與視圖進(jìn)行綁定,修改 data 對象的屬性值將引起對應(yīng)視圖的改變。

Vue2的數(shù)據(jù)視圖綁定是通過JS特性這一語法實現(xiàn),其使用中存在數(shù)據(jù)屬性丟失的這 一 bug,主要針對 對象或數(shù)組 屬性丟失。

使用 antv a-select (下拉框)組件,使用 v-mode 綁定對象 的值,但是 對象之前是沒有賦值的,是一個 空對象 ,這就導(dǎo)致了 頁面視圖不刷新 ,但是 屬性值有變化 ,這可以說是 vue2 的一個缺陷。

// 空對象

queryParam:?{

??????},

解決方法

方法一 (設(shè)置初始值)

給 綁定的對象 賦初始值 null 或者 ' ' 

  queryParam: {
        approveStatus : null ,    
      },

 如果是普通 輸入框 input ,這樣的方法沒什么問題,但是 我的頁面使用 a-select 下拉框,默認(rèn)有提示消息( placeholder),如果 賦初始值 為空 ,下拉框會填充空白內(nèi)容 ,覆蓋之前的提示消息 ,這樣的頁面 會比較不美觀且不友好

  <a-select  v-model="queryParam.approveStatus" placeholder="審核狀態(tài)" :allowClear="true">
        <a-select-option v-for="status of videoApproveStatus" :key="status.id">
                 {{  status.text }}
        </a-select-option>
 </a-select>
                    
  <a-select  v-model="queryParam.videotypeid" placeholder="視頻類型" :allowClear="true">
         <a-select-option v-for="d in videotype" :key="d.myid">
                 {{ d.name }}
          </a-select-option>
   </a-select>          

       

雖然這種方法可以解決綁定對象屬性丟失問題,但是如果給 每個屬性設(shè)置 初始值 為 null,那么所有的下拉框都是空白 , 可以看到 下拉框 賦初始值 為 null ,頁面的效果非常不友好 ,沒有提示信息 ,所有這種方法不推薦

方法二 (創(chuàng)建一個新的對象,替換原對象)

這種方法可以用于需要添加多個新屬性,再把原對象與新屬性合并到新對象中

Object.assign(目標(biāo)對象,原對象, 新屬性)

this.queryParam = Object.assign({}, this.queryParam, obj)

我這里是 利用 a-select 下拉框 自帶的 下拉框 改變方法 ,@change ,該方法有兩個參數(shù) value 和 option ,value 代表你改變的值 ,option (我也不太明白 ,反正里面東西很多),然后 我利用 這個 @change 方法 和  Object.assign(目標(biāo)對象,原對象, 新屬性), 解決了狀態(tài)丟失問題 ,大家可以 參考下面的代碼 ,根據(jù)自己的實際情況進(jìn)行調(diào)整 (每個人的情況都不一樣)

 <a-select @change="handleChange"  v-model="queryParam.approveStatus" placeholder="審核狀態(tài)" :allowClear="true">
       <a-select-option v-for="status of videoApproveStatus" :key="status.id">
               {{  status.text }}
       </a-select-option>
 </a-select>
 handleChange(value,option) { 
      if(option) {
        //  解決雙向綁定狀態(tài)丟失
          this.queryParam = Object.assign({}, this.queryParam, option.context.queryParam)
      } else {
        return 
      } 
    },

vue2實現(xiàn)響應(yīng)式數(shù)據(jù)

JS中的對象屬性

JS的對象有兩種屬性進(jìn)行描述 分別是數(shù)據(jù)屬性和訪問器屬性。

數(shù)據(jù)屬性有四個值:

  • [[Configurable]] 表示是否可以刪除定義,是否可以修改屬性,默認(rèn)為true
  • [[Enumberable]] 是否可以迭代
  • [[Writable]] 是否可以被修改
  • [[Value]] 對象具體的值

而訪問器屬性也有四個值:

  • [[Configurable]] 表示是否可以刪除定義,是否可以修改屬性,默認(rèn)為true
  • [[Enumberable]] 是否可以迭代
  • [[Get]] 獲取函數(shù),讀取屬性值時使用
  • [[Set]] 設(shè)置函數(shù),寫入屬性時調(diào)用

那么如何實現(xiàn)數(shù)據(jù)響應(yīng)呢?

利用Object.defineProperty()進(jìn)行數(shù)據(jù)劫持

實現(xiàn)響應(yīng)式的前提是可以捕捉到到數(shù)據(jù)的更改,獲取數(shù)據(jù)同理,這就需要利用JS對象的訪問器屬性,而更改這些屬性 就要用到JS中的一個方法 Object.defineProperty() 上述的屬性在更改時,哪怕更改一個屬性,所有屬性都會變?yōu)槟J(rèn)值。

具體使用方法如下:

let obj = {name:'Ton', age: 19}
_value = obj.name
Object.defineProperty(obj, name, {
? ? get(){
? ? ? ? return _value
? ? },
? ? set(newValue){
? ? ? ?_value = newValue
? ? }
})

方法的參數(shù)分別是 Object.defineProperty(對象名, 屬性名, {執(zhí)行器})

而get 函數(shù)在讀取該對象屬性時調(diào)用,返回的值為讀取的值; set 函數(shù)會在設(shè)置新值時調(diào)用 傳入的newValue為新值。

在Vue中 會用data一個對象包裹所有的值,因此可以用遍歷的方法給每個屬性加上該方法。

將該邏輯封裝到一個函數(shù)中:

let data = {
? ? name: 'Ton',
? ? age: 19,
? ? salary: '10k'
}

Object.keys(data).forEach( key => {?
? ? observe(data, key, data[key])
})
//形成閉包 內(nèi)部的變量不會消失
function observe(obj, key, value){
? ? Object.defineProperty(obj, key, {
? ? ? ? get(){
? ? ? ? ? ? return value
? ? ? ? },
? ? ? ? set(newValue){
? ? ? ? ? ? value = newValue
? ? ? ? }
? ? })
}

這樣data中的所有變量都會被綁定,但如果嵌套對象或數(shù)組,內(nèi)部的對象不會被檢測到。(可以用vue提供的 $set和 $delate 處理或 使用內(nèi)部重寫的數(shù)組方法)

與標(biāo)簽聯(lián)動

與標(biāo)簽聯(lián)動的方法有許多,最簡單的是使用id 來綁定,而Vue中是使用指令的方式。

過程主要分兩步:

  • 獲取dom
  • 將數(shù)據(jù)放上去
...
<div id="app">
? ? <div v-test="name" class="box"></div>
? ? <div v-test="age" class="box"></div>
</div>
...
function compile(){
? ? let app = document.getElementById('app')
? ? //獲取所有的子節(jié)點(diǎn) 值為3的是text節(jié)點(diǎn) 1為子標(biāo)簽節(jié)點(diǎn)
? ? app.childNodes.forEach( node => {
? ? ? ? if(node.nodeType === 1){
? ? ? ? ? ? //遍歷該節(jié)點(diǎn)的屬性 找出 v-text?
? ? ? ? ? ? //node.attributes是個類數(shù)組對象, 先轉(zhuǎn)化為數(shù)組
? ? ? ? ? ? Array.from(node.attributes).forEach( key => {
? ? ? ? ? ? ? ? //解構(gòu)對象 nodeName 找到屬性
? ? ? ? ? ? ? ? let { nodeName, nodeValue } = key?
? ? ? ? ? ? ? ? ?//如果存在 則修改值(關(guān)鍵步驟)
? ? ? ? ? ? ? ? if(nodeName === 'v-test'){
? ? ? ? ? ? ? ? ?? ?node.innerText = data[nodeValue]
? ? ? ? ? ? ? ??? ?}
? ? ? ? ? ? })
? ? ? ? }
? ? })
}
compile()
...

此時可以獲取節(jié)點(diǎn),并賦值數(shù)據(jù),與數(shù)據(jù)劫持聯(lián)動,最終結(jié)果如下:

let data = { name: 'Ton', age: 19}
//劫持?jǐn)?shù)據(jù)
Object.keys(data).forEach(key => {
? ? observe(data, key, data[key])
})
//形成閉包 內(nèi)部的變量不會消失
function observe(obj, key, value) {
? ? Object.defineProperty(obj, key, {
? ? ? ? get() {
? ? ? ? ? ? return value?
? ? ? ? },
? ? ? ? set(newValue) {
? ? ? ? ? ? value = newValue
? ? ? ? ? ? compile()
? ? ? ? }
? ? })
}
//獲取元素 將數(shù)據(jù)放入
function compile(){
? ? let app = document.getElementById('app')
? ? //獲取所有的子節(jié)點(diǎn) 包括很多節(jié)點(diǎn) 3 為text 節(jié)點(diǎn) 1為子標(biāo)簽節(jié)點(diǎn)
? ? app.childNodes.forEach( node => {
? ? ? ? if(node.nodeType === 1){
? ? ? ? ? ? //遍歷該節(jié)點(diǎn)的屬性 找出 v-text?
? ? ? ? ? ? //node.attributes是個類數(shù)組對象, 先轉(zhuǎn)化為數(shù)組
? ? ? ? ? ? let result = Array.from(node.attributes).filter( key => {
? ? ? ? ? ? ? ? //結(jié)構(gòu)屬性的 nodeName 找到屬性
? ? ? ? ? ? ? ? let { nodeName } = key?
? ? ? ? ? ? ? ? return nodeName === 'v-test'
? ? ? ? ? ? })
? ? ? ? ? ? if(result){
? ? ? ? ? ? ? ? node.innerText = data[result[0].nodeValue]
? ? ? ? ? ? }
? ? ? ? }
? ? })

}
compile()

每次修改也會引起DOM元素的修改,實現(xiàn)響應(yīng)式。

v-model的實現(xiàn)

同v-test(v-on) 的不同,v-model要實現(xiàn)雙向綁定,即 input框輸入的值也需要傳回data。實現(xiàn)的邏輯前面是相同的,都需要獲取元素,但需要新增將input輸入框的內(nèi)容,傳回。

let data = { name: 'Ton', age: 19}
//劫持?jǐn)?shù)據(jù)
Object.keys(data).forEach(key => {
? ? observe(data, key, data[key])
})
//形成閉包 內(nèi)部的變量不會消失
function observe(obj, key, value) {
? ? Object.defineProperty(obj, key, {
? ? ? ? get() {
? ? ? ? ? ? return value?
? ? ? ? },
? ? ? ? set(newValue) {
? ? ? ? ? ? value = newValue
? ? ? ? ? ? compile()
? ? ? ? }
? ? })
}
//獲取元素 將數(shù)據(jù)放入
function compile(){
? ? let app = document.getElementById('app')
? ? //獲取所有的子節(jié)點(diǎn) 包括很多節(jié)點(diǎn) 3 為text 節(jié)點(diǎn) 1為子標(biāo)簽節(jié)點(diǎn)
? ? app.childNodes.forEach( node => {
? ? ? ? if(node.nodeType === 1){
? ? ? ? ? ? //遍歷該節(jié)點(diǎn)的屬性 找出 v-text?
? ? ? ? ? ? //node.attributes是個類數(shù)組對象, 先轉(zhuǎn)化為數(shù)組
? ? ? ? ? ? let result = Array.from(node.attributes).filter( key => {
? ? ? ? ? ? ? ? //結(jié)構(gòu)屬性的 nodeName 找到屬性
? ? ? ? ? ? ? ? let { nodeName } = key?
? ? ? ? ? ? ? ? return nodeName === 'v-model'
? ? ? ? ? ? })
? ? ? ? ? ? if(result){
? ? ? ? ? ? ? ? node.value = data[result[0].nodeValue]
? ? ? ? ? ? ? ? addEventLisener('input', e => {
?? ??? ??? ??? ??? ??? ?data[result[0].nodevalue] = e.target.value?
?? ??? ??? ??? ??? ?}
? ? ? ? ? ? ? ? )
? ? ? ? ? ? }
? ? ? ? }
? ? })

}
compile()

但目前的方法并不完美,需要添加一個防抖函數(shù)

let data = { name: 'Ton', age: 19}
//劫持?jǐn)?shù)據(jù)
Object.keys(data).forEach(key => {
? ? observe(data, key, data[key])
})
//形成閉包 內(nèi)部的變量不會消失
function observe(obj, key, value) {
? ? Object.defineProperty(obj, key, {
? ? ? ? get() {
? ? ? ? ? ? return value?
? ? ? ? },
? ? ? ? set(newValue) {
? ? ? ? ? ? value = newValue
? ? ? ? ? ? compile()
? ? ? ? }
? ? })
}
//獲取元素 將數(shù)據(jù)放入
function compile(){
? ? let app = document.getElementById('app')
? ? //獲取所有的子節(jié)點(diǎn) 包括很多節(jié)點(diǎn) 3 為text 節(jié)點(diǎn) 1為子標(biāo)簽節(jié)點(diǎn)
? ? app.childNodes.forEach( node => {
? ? ? ? if(node.nodeType === 1){
? ? ? ? ? ? //遍歷該節(jié)點(diǎn)的屬性 找出 v-text?
? ? ? ? ? ? //node.attributes是個類數(shù)組對象, 先轉(zhuǎn)化為數(shù)組
? ? ? ? ? ? let result = Array.from(node.attributes).filter( key => {
? ? ? ? ? ? ? ? //結(jié)構(gòu)屬性的 nodeName 找到屬性
? ? ? ? ? ? ? ? let { nodeName } = key?
? ? ? ? ? ? ? ? return nodeName === 'v-model'
? ? ? ? ? ? })
? ? ? ? ? ? if(result){
? ? ? ? ? ? ? ? node.value = data[result[0].nodeValue]
? ? ? ? ? ? ? ? addEventLisener('input', debounce(handel, result[0].nodeValue)
? ? ? ? ? ? }
? ? ? ? }
? ? })
?? ?function debounce(fn, key, timer = 1000){
?? ??? ?let t = null
?? ??? ?return function(){
?? ??? ??? ?if(t) { clearTimeout(t) }
?? ??? ??? ?t= setTimeOut( _ => {
?? ??? ??? ??? ?t = null
?? ??? ??? ??? ?fn.call(this, key, arguments)
?? ??? ??? ?},timer)
?? ??? ?}
?? ?}
?? ?function handel(key, event){
?? ??? ?data[key] = event.target.value
?? ?}
}
compile()

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • vue限制文本輸入框只允許輸入字母、數(shù)字、禁止輸入特殊字符

    vue限制文本輸入框只允許輸入字母、數(shù)字、禁止輸入特殊字符

    這篇文章主要介紹了vue限制文本輸入框只允許輸入字母、數(shù)字、不允許輸入特殊字符,通過監(jiān)聽表單輸入的內(nèi)容,使用方法的缺陷,本文通過實例代碼介紹的非常詳細(xì),需要的朋友參考下吧
    2023-10-10
  • elementUI實現(xiàn)級聯(lián)選擇器

    elementUI實現(xiàn)級聯(lián)選擇器

    這篇文章主要為大家詳細(xì)介紹了elementUI實現(xiàn)級聯(lián)選擇器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • 詳解vue2和vue3如何定義響應(yīng)式數(shù)據(jù)

    詳解vue2和vue3如何定義響應(yīng)式數(shù)據(jù)

    這篇文章主要是來和大家一起討論一下vue2和vue3是如何定義響應(yīng)式數(shù)據(jù)的,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價值,感興趣的小伙伴可以了解下
    2023-11-11
  • vue實現(xiàn)一個滾動條樣式

    vue實現(xiàn)一個滾動條樣式

    滾動條能夠給用戶帶來極好的體驗效果,今天通過本文給大家分享vue實現(xiàn)一個滾動條樣式,代碼簡單易懂,需要的朋友參考下吧
    2021-07-07
  • 詳解滑動穿透(鎖body)終極探索

    詳解滑動穿透(鎖body)終極探索

    這篇文章主要介紹了滑動穿透(鎖body),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • 基于vue實現(xiàn)分頁組件的示例代碼

    基于vue實現(xiàn)分頁組件的示例代碼

    分頁組件是一種用戶界面元素,用于在長列表或數(shù)據(jù)集中分割內(nèi)容,分頁組件是每個開發(fā)人員必須掌握的一個組件,廣泛應(yīng)用在各個場所,用以用戶方便閱讀等,本文就給大家介紹一下如何基于vue寫出的分頁組件,需要的朋友可以參考下
    2023-08-08
  • vue3中虛擬dom的介紹與使用詳解

    vue3中虛擬dom的介紹與使用詳解

    Vue?是如何將一份模板轉(zhuǎn)換為真實的?DOM?節(jié)點(diǎn)的,又是如何高效地更新這些節(jié)點(diǎn)的呢,這些都離不開虛擬dom這個概念,下面我們就來了解下虛擬dom這個概念以及它是什么吧
    2024-01-01
  • 解決vue中el-date-picker?type=daterange日期不回顯的問題

    解決vue中el-date-picker?type=daterange日期不回顯的問題

    這篇文章主要介紹了解決vue中el-date-picker?type=daterange日期不回顯的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • vue實現(xiàn)點(diǎn)擊復(fù)制到粘貼板

    vue實現(xiàn)點(diǎn)擊復(fù)制到粘貼板

    這篇文章主要為大家詳細(xì)介紹了vue實現(xiàn)點(diǎn)擊復(fù)制到粘貼板,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • vue3無config文件夾打包后頁面空白問題及解決

    vue3無config文件夾打包后頁面空白問題及解決

    這篇文章主要介紹了vue3無config文件夾打包后頁面空白問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05

最新評論