vue增刪改查(CURD)含Demo

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


在管理員的一些後台頁面裡,個人中心裡的數據列表裡,都會有對這些數據進行增刪改查的操作。比如在管理員後台的用戶列表裡,我們可以錄入新用戶的信息,也可以對既有的用戶信息進行修改。在vue中,我們更應該專注於對數據的操作和處理。


比如我們有一個這樣的頁面:


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


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


我們把這些用戶信息保存到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只負責展示。


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


// 获取需要渲染到页面中的数据

setSlist(arr) {

    this.slist = JSON.parse(JSON.stringify(arr));

}

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


<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>

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


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數組,展示出查詢後的數據。這裡我們的查詢實現了兩個小功能:


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


同步更新表格中的數據


這裡我們通過用戶名和郵箱進行查詢,因此在過濾數據時,需要檢測用戶名和郵箱是否含有查詢的單詞。我們先給輸入框綁定一個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); // 将修改后的数据传递给父组件

        }

    }

});

父組件,在父組件中截取change和modify事件,再用changeOverlay和modify來實現:


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

<!-- segmengfault -->

6. 總結

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


留言

這個網誌中的熱門文章

Vue 安裝