昨天的博客中总结了后端响应结果的包装Response(meta, data)。今天就简单谈谈博主在项目开发过程中的是如何借助于Vue.js的特性构造数据缓存区的。

鉴于煤矿井下精确人员定位系统的运行复杂性,就不再使用项目代码来做展示。这里,就通过编写一个简易的project demo进行展示Vue构造数据缓存区的便捷使用。


1、软件准备

请在切入正题之前,保证自己的电脑上装好了如下软件:

(1)node.js 6.9.5(会自动安装npm)

(2)vue 2.x , vue-cli(如果vue 2.x安装不成功,可以直接安装vue-cli,会自动安装依赖vue 2.x)

(3)Atom或者Sublime Text编辑器(用于前段代码的编写)

(4)JDK 1.8,Tomcat 8.x, Eclipse(用于运行后端代码)


2、资源准备

编写JavaScript实现数据的深拷贝的工具方法。

extends.js文件


/**
 * 深拷贝实现的继承:实现真正意义上的数组和对象的拷贝
 * @param p 要继承的类
 * @returns {___anonymous398_399}
 */
export function deepCopy(p) {
	var F = (p.constructor === Array) ? [] : {};

	for(var i in p) {
		if((typeof p[i]).toString.toLowerCase === "object") {
			F[i] = deepCopy(p[i]);
		} else {
			F[i] = p[i];
		}
	}
	F.uber = p;
	return F;
};



3、正式开工

(1)在自己的workspace目录下,打开terminal工具(或者windows下的cmd),通过vue init webpack vuecachepro命令创建项目

(2)通过Atom或者Sublime Text编辑器打开项目vuecachepro,其目录结构如下:

人员定位java开源 人员定位系统_vue.js

(3)把上述准备的资源文件extends.js文件拷贝到src/assets目录下

(4)打开src/components/Hello.vue文件,作如下修改:


<template>
  <div class="hello">
    <div id="search-wrapper">
        <input type="text" class="search-input" v-model="telephone" placeholder="请输入telephone..." />
        <button type="button" class="search-btn" @click="findPersonByTelephone()">查询</button>
    </div>
    <div class="hr"></div>
    <div id="result-wrapper">
      <table>
        <thead>
          <tr>
            <th>name</th>
            <th>age</th>
            <th>gender</th>
            <th>telephone</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td v-if="person != null">{{ person.name }}</td>
            <td v-if="person != null">{{ person.age }}</td>
            <td v-if="person != null">{{ person.sex }}</td>
            <td v-if="person != null">{{ person.telephone }}</td>
          </tr>
        </tbody>
      </table>
    </div>
    <div class="hr"></div>
    <div id="list-wrapper">
      <template v-for="person in personListCache.personList">
        <div class="line">
          <div class="telephone">{{ person.telephone }}</div>
          <div class="name">{{ person.name }}</div>
          <div class="age">{{ person.age }}</div>
          <div class="more">
            <a href="javascript: void(0)" @click="showDetail(person)">show {{ person.name }} detail</a>
          </div>
        </div>
      </template>
    </div>
  </div>
</template>

<script>
import { deepCopy } from '../assets/extends';

export default {
  name: 'hello',
  data () {
    return {
      telephone: '',
      person: {},
      personListCache: {
        personList: [],
        total: 0
      }
    }
  },
  mounted () {
    this.defaultLoadPersonList();
  },
  methods: {
    defaultLoadPersonList () {
      let self = this;

      // 模拟从后台返回的数据结果集
      let personArr = [{
        telephone: '15536542221',
        name: 'Jack',
        age: 23,
        sex: 'male'
      }, {
        telephone: '15536542222',
        name: 'David',
        age: 27,
        sex: 'male',
      }, {
        telephone: '15536542223',
        name: 'Grace',
        age: 26,
        sex: 'female'
      }, {
        telephone: '15536542224',
        name: 'Chace',
        age: 27,
        sex: 'male'
      }, {
        telephone: '15536542225',
        name: 'Bryan',
        age: 32,
        sex: 'male'
      }];

      self.personListCache.personList = personArr;
      self.personListCache.total = 5;
    },
    findPersonByTelephone () {
      let self = this;

      let personList = self.personListCache.personList;
      for (let i = 0; i < personList.length; i++) {
        if (personList[i].telephone == self.telephone) {
          // 一定要记得使用deepCopy一下person,而不要直接操作person的数据,不然会产生级联修改效应
            self.person = deepCopy(personList[i]);
            delete self.person.uber;

            self.telephone = '';
            break;
        }
      }
    },
    showDetail(person) {
      // 这里进行了省略,如果要在模态框中对数据进行增删改查操作,一定要进行deepCopy一下
      let _result = "name: " + person.name + "\n\n"
                  + "age: " + person.age + "\n\n"
                  + "gender: " + person.sex + "\n\n"
                  + "telephone: " + person.telephone;
      alert(_result);
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
a {
  color: #42b983;
}

#search-wrapper {
  width: 100%;
  clear: both;
  height: 50px;
  line-height: 50px;
}

#search-wrapper input {
  height: 20px;
  line-height: 20px;
  width: 30%;
}

#search-wrapper button {
  height: 26px;
  line-height: 26px;
  width: 10%;
}

div.hr {
  border-top: 2px solid #EEE;
}

.line {
  height: 50px;
  margin-top: 15px;
}

.telephone, .name, .age, .more {
  display: inline-block;
  margin-top: 15px;
  margin-right: 10px;
}

#result-wrapper table {
  margin-left: 40%;
  margin-right: 40%;
}
table thead tr th {
  width: 25%;
}
</style>



(5)当前目录结构为:

人员定位java开源 人员定位系统_缓存_02

(6)在Terminal或者windows下的cmd工具,切换到当前项目的目录下,执行npm install命令,安装包依赖,然后再执行npm run dev运行项目,在浏览器中:http://localhost:8080/即可看到如下页面:

人员定位java开源 人员定位系统_vue.js_03

进行相应操作即可。


4、总结

如何构造Vue数据缓存区,减少请求后端获取数据次数?

1、首先需要准备extends.js文件,其是为了解决操作Vue数据缓存区数据时会产生的联动性

2、需要在Vue数据区域作如下操作:

人员定位java开源 人员定位系统_数据_04

3、使用过程中一定要记得通过extends.js文件中的deepCopy方法进行操作数据

findPersonByTelephone () {
      let self = this;

      let personList = self.personListCache.personList;
      for (let i = 0; i < personList.length; i++) {
        if (personList[i].telephone == self.telephone) {
          // 一定要记得使用deepCopy一下person,而不要直接操作person的数据,不然会产生级联修改效应
            self.person = deepCopy(personList[i]);
            delete self.person.uber;

            self.telephone = '';
            break;
        }
      }
    },



尤其是针对页面表格中的记录进行选取,然后再二级页面—模态框中进行增删改查操作时,极易产生数据联动性。所以有如此情况时一定要借助于deepCopy方法。


博主实在限于源代码的不可开放性。所以请各位见谅,只能通过这个简陋的project进行介绍Vue构造数据缓存区。