vue 數(shù)組中嵌套的對象添加新屬性--頁面更新

我們知道vue屬于MVVM框架告匠,數(shù)據(jù)操作視圖蛛倦。對data對象中的數(shù)據(jù)進(jìn)行監(jiān)聽捧弃,當(dāng)偵測到數(shù)據(jù)改變時相應(yīng)數(shù)據(jù)所影響的頁面也會觸發(fā)更新许赃。所以我們所需要的這些響應(yīng)式數(shù)據(jù)止喷,受到j(luò)avascript的限制,vue不能檢測到對象屬性的添加或刪除混聊,因為Vue利用的是Object的defineProperty()方法弹谁,在初始化實列時將屬性轉(zhuǎn)為getter/setter,所以屬性必須在data對象上才能讓vue轉(zhuǎn)換它句喜。
當(dāng)然這只是一般的屬性预愤,以一般字符串,數(shù)字咳胃,布爾值這樣的基本數(shù)據(jù)類型作為屬性值的響應(yīng)植康,當(dāng)然我們有時候的訴求的初始化屬性的屬性值不只有這樣的基本數(shù)據(jù)變量,我們還會用到數(shù)組展懈,對象這樣的引用數(shù)據(jù)變量销睁。引用數(shù)據(jù)變量就是對地址的引用供璧,只是對象的指針發(fā)生變化,并沒有重新生成一個對象冻记,此處省略過多其他介紹睡毒,應(yīng)該這些都比較懂。冗栗。演顾。

vue在這種情況下給我們提供了$set這種響應(yīng)式方法去操作頁面更新。其實這只是set簡單的對象不是嵌套很深的那種隅居,那如果是那樣嵌套比較深的那種我們該怎樣去做呢钠至?說多了不如來個業(yè)務(wù)情景然后擼幾行代碼看一下:

這樣的一個場景我們從后臺請求下一個list相當(dāng)于渲染成一個Table,我們需要賦予每行都有自己獨(dú)立的編輯功能和顯示功能。類似于這樣的效果:


每行都有單獨(dú)的編輯功能

當(dāng)然實現(xiàn)效果多種多樣胎源,但我們就當(dāng)后臺給我們的list數(shù)據(jù)是:

   [
        {
          name: '第1行',
          textShow: true,
          text: ''
        },
         {
          name: '第2行',
          textShow: true,
          text: ''
        },
         {
          name: '第3行',
          textShow: true,
          text: ''
        },
         {
          name: '第4行',
          textShow: true,
          text: ''
       

我們的頁面為這樣

<template>
  <div>
    <ul v-if="list">
      <li v-for="(item, index) in list" :key="index">
        <span>{{item.name}}</span>
        <span ref="text" v-show="item.textShow">
          {{item.txt}}
        </span>
        <input type="text" v-model="item.txt" v-show="!item.textShow">
        <button @click="edit(item)" v-show="item.showEditBtn">編輯</button>
        <button @click="confirm(item)" v-show="!item.showEditBtn">確定</button>
      </li>
    </ul>
  </div>
</template>

當(dāng)然看上面的數(shù)據(jù)機(jī)構(gòu)我們可以看出其實顯示隱藏編輯和確定的數(shù)據(jù)參數(shù)并沒有給咱們棉钧,其實就是我們需要在數(shù)組中對象增加一個新屬性“showEditBtn”去判定:那有時候我們可能會這樣寫:

mounted () {
    this.arr.forEach(item => {
      item.showEditBtn = true
    })
  },

當(dāng)我們看頁面效果居然無動于衷,


只顯示確定乒融,應(yīng)該顯示編輯呀掰盘!

哈哈!看到上面這種效果赞季,我們應(yīng)該明白了愧捕,showEditBtn屬性并不是初始化在data對象里面的,雖然arr屬于data對象申钩,但你應(yīng)該再好好想想js不能監(jiān)測但對象的變化次绘,當(dāng)然這時候我們可以考慮如何去偵測,必須讓對象變化撒遣。
此時我們可以這樣改寫

 mounted () {
    this.arr.forEach(item => {
      this.$set(item, 'showEditBtn', true)
    })
  },
這個姿勢可以呀

這樣他就可以偵測到你對象中的屬性的變化邮偎,當(dāng)然這是一種比較官方的姿勢也是一種比較推薦的姿勢。
我們考慮一下义黎,對象沒有變化我們沒有更新頁面禾进,單純的等號賦值只是引用地址的變化,本身不等于數(shù)組的變化廉涕,那我們讓他的數(shù)組真正變化(重新創(chuàng)建不就可以了)泻云,我們利用Object. assign()去進(jìn)行淺拷貝對象。

mounted () {
    this.arr.forEach(item => {
      item.showEditBtn = true;
    })
    this.arr = Object.assign({},this.arr)
  },
這個姿勢也可以呀

當(dāng)然這種方式我們可以現(xiàn)效果狐蜕,但我們不如用第一種宠纯,第一種只是單純?nèi)ジ淖円粋€數(shù)組中嵌套的對象的屬性而已,而第二種方法直接淺拷貝的一個數(shù)組對象层释。
當(dāng)然婆瓜,第二種有沒有變通之法,當(dāng)然有贡羔!我們考慮一下廉白,如果之前的功能只是單純的去渲染一個list,

arr: [
        {
          name: '第1行'
        },
         {
          name: '第2行'
        },
         {
          name: '第3行'
        },
         {
          name: '第4行'
        }

沒有編輯功能个初,編輯功能是后來加的,并且遇見的后臺比較懶蒙秒,它就維持這個數(shù)據(jù)結(jié)構(gòu)不變勃黍,那我們是不是有想法了,這樣就啟迪了第二種方式的變通晕讲,
我們不忙著將獲取到的list賦值給arr,我們對他進(jìn)行改寫:

mounted () {
    list.forEach(item => {
      item.textShow = true;
      item.text = ' ';
      item.showEditBtn = true;
    })
    this.arr = list
  },

// 同時我們將改寫好的arr放在
 <ul v-if="arr">
 <li v-for="(item, index) in arr" :key="index">

通過上面的方法我們可以提前預(yù)判我們需要怎樣的數(shù)據(jù)去驅(qū)動視圖马澈,然后我們最先將它初始化在data對象中瓢省,這就需要寫代碼錢我們有個思考全面的過程。
當(dāng)然如果想第一種設(shè)想我們只是單純的去隱藏編輯和確定功能痊班,我們可不可以將在data里去聲明一個單純的全局變量勤婚,不去嵌在數(shù)組和對象那種很隱秘的角落,我想正大光明的成為一個data對象中單獨(dú)的控制變量currentShow涤伐。我們可以分析一下:
因為在寫遍歷列表的時候我們通過v-for循環(huán)去寫馒胆,所以我們?nèi)绻タ刂葡嗤δ茉氐娘@示隱藏,我們引用全局變量currentShow凝果,當(dāng)我們觸發(fā)某個行為去改變currentShow的值時祝迂,我們會發(fā)現(xiàn)所有的item都會相應(yīng)的變化,雖然你操作的是其中一個:


會是這樣的效果

當(dāng)然我們想想因為我們?nèi)值腸urrentShow變量是完全變化一致的器净,我們要想單獨(dú)去操作每行元素型雳,我們該怎樣去做?其實也很簡單山害,我們再加個判斷纠俭,同時滿足這兩個結(jié)果才會觸發(fā)行為,這個判斷必須是每行獨(dú)一無二的浪慌,哈哈冤荆!肯定是index索引了,我們可以再聲明一個data對象屬性currentIndex权纤,當(dāng)我們對每行進(jìn)行操作時钓简,我們將this.currentIndex等于這行的索引,我們增加的判斷就可以變成

v-show="currentIndex === index && currentShow"

每行變化時currentIndex都在變化妖碉,他只能等于操作行的索引涌庭,感覺有一種借力打力的效果。不過實現(xiàn)了


定義變量接力打力

以上雖不是難的東西欧宜,但貴在舉一反三坐榆,簡書記之!H呷住席镀!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末匹中,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子豪诲,更是在濱河造成了極大的恐慌顶捷,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件屎篱,死亡現(xiàn)場離奇詭異服赎,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)交播,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門重虑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人秦士,你說我怎么就攤上這事缺厉。” “怎么了隧土?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵提针,是天一觀的道長。 經(jīng)常有香客問我曹傀,道長辐脖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任卖毁,我火速辦了婚禮揖曾,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘亥啦。我一直安慰自己炭剪,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布翔脱。 她就那樣靜靜地躺著奴拦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪届吁。 梳的紋絲不亂的頭發(fā)上错妖,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機(jī)與錄音疚沐,去河邊找鬼暂氯。 笑死,一個胖子當(dāng)著我的面吹牛亮蛔,可吹牛的內(nèi)容都是我干的痴施。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼辣吃!你這毒婦竟也來了动遭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤神得,失蹤者是張志新(化名)和其女友劉穎厘惦,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體哩簿,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宵蕉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了节榜。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片国裳。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖全跨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情亿遂,我是刑警寧澤浓若,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站蛇数,受9級特大地震影響挪钓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜耳舅,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一碌上、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧浦徊,春花似錦馏予、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至冕香,卻和暖如春蛹尝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背悉尾。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工突那, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人构眯。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓愕难,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子务漩,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容