vue實現對錶格數據的增刪改查(CURD)

原文地址:https://www.xiabingbao.com/vue/2017/07/10/vue-curd.html javascript

在管理員的一些後臺頁面裏,我的中內心的數據列表裏,都會有對這些數據進行增刪改查的操做。好比在管理員後臺的用戶列表裏,咱們能夠錄入新用戶的信息,也能夠對既有的用戶信息進行修改。在vue中,咱們更應該專一於對數據的操做和處理。 html

好比咱們有一個這樣的頁面: vue

vue實現對錶格數據的增刪改查(CURD)

咱們在這個頁面裏,就實現了增刪改查4個功能,點擊連接查看demo【http://www.xiabingbao.com/demo/vue-curd/index.html】。 java

咱們把這些用戶信息保存到list的數組中,而後增刪改查就在這個數組上進行:編程

list: [
    {
        username: 'aaaaa',
        email: '123@qq.com',
        sex: '男',
        province: '北京市',
        hobby: ['籃球', '讀書', '編程']
    },
    {
        username: 'bbbbb',
        email: 'bbbbbbb@163.com',
        sex: '女',
        province: '河北省',
        hobby: ['彈琴', '讀書', '插畫']
    }
    // ...
]

設置這些數據主要也是複習一下vue對錶單的處理操做,這裏面的表單有:文本輸入框,單選按鈕,select選擇框,複選框等。數組

1. 展現數據

咱們的數據都放在數組list中,可是這裏並不直接對list對循環輸出,而是先把list中的數據給一個數組slist,對slist進行循環輸出。由於咱們在後面的查詢功能中須要對數據進行過濾,數組list一直保存着原始數據(包括新增、修改後或已刪除後),而數組slist只負責展現。 ide

在vue中提供一個setSlist方法,將須要展現的數據給了數組slist:ui

// 獲取須要渲染到頁面中的數據
setSlist(arr) {
    this.slist = JSON.parse(JSON.stringify(arr));
}

而後在html中使用v-for把slist數組渲染出來:this

<tr v-cloak v-for="(item, index) of slist">
    <td>{{index+1}}</td>
    <td>{{item.username}}</td>
    <td>{{item.email}}</td>
    <td>{{item.sex}}</td>
    <td>{{item.province}}</td>
    <td>{{item.hobby.join(' | ')}}</td>
    <td><a href="javascript:;" @click="showOverlay(index)">修改</a> | <a href="javascript:;" @click="del(index)">刪除</a></td>
</tr>

在操做這一欄中,給修改和刪除操做綁定上事件。spa

2. 增長和刪除功能

把增長功能和刪除合併到一塊兒,是這兩個功能相對來講都比較簡單。

增長用戶時使用push方法,把用戶的信息添加到list數組的最後:

this.list.push({
    username: 'ffff',
    email: 'fffffff@163.com',
    sex: '女',
    province: '河南省',
    hobby: ['彈琴', '插畫']
});

這樣就能添加一位ffff的用戶了。

刪除用戶時,經過splice(index, 1),能夠刪除index位置的數據,頁面上的數據自動就會更新。

3. 修改功能

當咱們想要修改某個元素時,能夠把這個位置上的數據取出來放到彈層裏(或者其餘某個位置),在彈層裏的信息能夠取消或者修改後進行保存。

假設咱們彈層裏的數據是selectedlist,那麼每次修改時,把index位置的數據給了selectedlist,而後在彈層中修改selectedlist。咱們也能看到修改數據的類型: 文本框(用戶名,郵箱),單選按鈕(性別),select選擇框(所在省份),多選框(愛好),這裏咱們主要練習的是表單處理(https://cn.vuejs.org/v2/guide...)。彈層是否顯示用變量isActive來控制:

// 修改數據
modifyData(index) {
    this.selected = index; // 修改的位置
    this.selectedlist = this.list[index];
    this.isActive = true;
}

有沒有發現一個問題,當修改彈層中的信息時,表格中的數據也同步更新了。但是咱們自己是但願當點擊保存按鈕時,才把彈層中的數據保存到表格裏。問題的根源就出在這裏:

this.selectedlist = this.list[index];

由於list[index]是個Object類型的數據,若使用=賦值,則賦值操做爲淺度拷貝(把數據的地址賦值給對應變量,而沒有把具體的數據複製給變量,變量會隨數據值的變化而變化),selectedlist與list[index]使用相同的數據地址,互相引發數據值的變化。所以這裏咱們須要進行深度拷貝:

this.selectedlist = JSON.parse( JSON.stringify(this.list[index]) ); // 先轉換爲字符串,而後再轉換

當用戶修改數據後,selectedlist就會發生變化,點擊保存按鈕時,將數據從新保存到index位置:

/*
  this.list 數據數組
  this.selected 剛纔修改的位置
  this.selectedlist 須要保存的數據
*/
Vue.set(this.list, this.selected, this.selectedlist);

4. 查詢功能

在第1小節中咱們已經說過,在頁面表格中展現的是slist中的數據,就是爲了方便執行查詢操做:

// 獲取須要渲染到頁面中的數據
setSlist(arr) {
    this.slist = JSON.parse(JSON.stringify(arr));
}

每次根據某些條件將過濾後的數據賦值給slist數組,展現出查詢後的數據。這裏咱們的查詢實現了兩個小功能:

  1. 用戶在輸入某個字符後,自動在輸入框下方用列表展現出用戶可能要查詢的詞語(如用戶名等)

  2. 同步更新表格中的數據

這裏咱們經過用戶名和郵箱進行查詢,所以在過濾數據時,須要檢測用戶名和郵箱是否含有查詢的單詞。咱們先給輸入框綁定一個input事件,同時用datalist展現用戶可能要查詢的詞語:

<input type="text" placeholder="search" @input="search" list="cars" class="search">
<datalist id="cars">
    <option v-for="item in searchlist" :value="item"></option>
</datalist>

search功能的實現,searchlist爲在輸入框下方展現的可能要搜索的詞語,ss數組則保存過濾後的數據,當循環完畢後,設置調用setSlist方法修改slist數組:

// 搜索
search(e) {
    var v = e.target.value,
        self = this;
    self.searchlist = [];
    if (v) {
        var ss = [];

        // 過濾須要的數據
        this.list.forEach(function (item) {
            // 檢測用戶名
            if (item.username.indexOf(v) > -1) {
                if (self.searchlist.indexOf(item.username) == -1) {
                    self.searchlist.push(item.username);
                }
                ss.push(item);
            } else if (item.email.indexOf(v) > -1) {
                // 檢測郵箱
                if (self.searchlist.indexOf(item.email) == -1) {
                    self.searchlist.push(item.email);
                }
                ss.push(item);
            }
        });
        this.setSlist(ss); // 將過濾後的數據給了slist
    } else {
        // 沒有搜索內容,則展現所有數據
        this.setSlist(this.list);
    }
}

每當用戶輸入或者刪除一個字符時都會調用search方法,執行查詢操做,當用點擊展現詞語列表時,也會調用search方法。

5. 將彈層獨立爲組件

其實咱們應該發現,修改功能(或新增功能)從代碼和樣式上相對來講比較獨立,咱們把彈層獨立爲組件的形式,把須要修改的數據經過props傳遞給該組件(新增數據時,能夠給組件傳遞一個空數據),當用戶點擊保存時,再經過$emit給了父組件(子組件不能直接父級的數據,須要用data或者computed生成一個局部變量,而後再使用$emit方法把這個局部數據再傳遞上去):

// 彈層組件 
Vue.component('model', {
    props: ['list', 'isactive'],
    template: `<div class="overlay" v-show="isactive">
                    <div class="con">
                        <h2 class="title">新增 | 修改</h2>
                        <div class="content">
                            /* 省略 */
                        </div>
                    </div>
               </div>`,
    computed: {
        modifylist() {
            return this.list;
        }
    },
    methods: {
        changeActive() {
            this.$emit('change'); // 關閉彈層,修改isactive值
        },
        modify() {
            this.$emit('modify', this.modifylist); // 將修改後的數據傳遞給父組件
        }
    }
});

父組件,在父組件中截取changemodify事件,再用changeOverlaymodify來實現:

<model :list='selectedlist' :isactive="isActive" v-cloak @change="changeOverlay" @modify="modify"></model>
<!-- segmengfault -->

6. 總結

洋洋灑灑寫了很多,其實裏面的難點不太多,主要是form表單方面的操做,再一個就是練習下組件間的數據與事件傳遞。內容比較簡單,歡迎各位批評指正。

若是你以爲不錯,歡迎關注個人公衆號:wenzichel
wenzichel

原文地址:https://www.xiabingbao.com/vue/2017/07/10/vue-curd.html

相關文章
相關標籤/搜索