全局数据管理

简介: 全局数据管理

全局数据管理


记账页面和标签页面都可以新增标签。可是现在有一个bug。在标签页面新增标签之后,在记账页面不会自动同步,要刷新一下才能同步。

这是因为这两个页面的数据tagList都是分别从tagListModel里fetch的。所以就导致了数据不同步。

解决方案:在更高一层的地方统一去tagListModel里fetch一次,把取出来的设成一个全局的属性,然后分别在两个页面直接使用。

我们选择在main.ts入口文件里声明这个全局属性:

window.tagList=tagListModel.fetch()

可是这样会报错,说window里没有这样一个属性。

那么我们就只能在custom.d.ts里自定义声明window里有这样一个属性。

interface Window  {
    tagList: Tag[]
}

这样再回到main.ts,就没有报错了。

然后就可以在两个页面直接使用。

在Money.vue:

export default class Money extends Vue{
        tags=window.tagList
}

在Labels.vue:

export default class Labels extends Vue {
        tags=window.tagList
}

这样就没有那个bug了。在标签页面新增一个标签后,在记账页面也会自动同步。

把数据放到window上以后,读取数据就是通过window操作的。但是写数据,比如删除,增加,修改标签,还是通过tagListModel这个对象的API操作的。

那么为了看起来一致,我们最好把这些API也封装到window上。

//main.ts
//record store
window.recordList=recordListModel.fetch()
window.createRecord=(record: RecordItem)=>{
  recordListModel.create(record)
}
// tag store
window.tagList=tagListModel.fetch()
window.createTag=(name: string)=>{
  const message=tagListModel.create(name)
  if(message==='duplicated'){
    window.alert('标签名重复')
  }else{window.alert('添加成功')}
}
window.removeTag=(id: string)=>{
  tagListModel.remove(id)
}
window.updateTag=(id: string,newName: string)=>{
  return tagListModel.update(id,newName)
}
window.findTag=(id: string)=>{
  return window.tagList.filter(tag=>tag.id===id)[0]
}

把recordListModel,tagListModel上的属性,方法都封装到window上以后,有一个问题。1. window上的变量太多了。2. 太依赖window了,如果在不支持window的情况下,就无法操作。

解决办法: 不要window,把这些API都封装到一个store对象上。在store目录里新建一个index2.ts

const store={
    //record store
    recordList: recordListModel.fetch(),
    createRecord: (record: RecordItem) => {
        recordListModel.create(record);
    },
    // tag store
    tagList: tagListModel.fetch(),
    createTag: (name: string) => {
        const message = tagListModel.create(name);
        if (message === 'duplicated') {
            window.alert('标签名重复');
        } else {
            window.alert('添加成功');
        }
    },
    removeTag: (id: string) => {
        tagListModel.remove(id);
    },
    updateTag: (id: string, newName: string) => {
        return tagListModel.update(id, newName);
    },
    findTag: (id: string) => {
        return store.tagList.filter(tag => tag.id === id)[0];
    }
}
export default store;

以后操作数据就全部调用store

可是这样store对象里有两种数据的操作,我们最好还是把他们分开:

import recordStore from '@/store/recordStore';
import tagStore from '@/store/tagStore';
const store={
    ...recordStore,
    ...tagStore
}
export default store;

分成recordStore和tagStore两个文件。然后统一在store里浅复制

那么全局数据管理的好处是什么?

  1. 解耦:将所有数据相关的逻辑放入 store(也就是 MVC 中的 Model,换了个名字而已)。即从localStorage里取数据,存数据,对数据增删改查,都由store里的API提供,别人要对数据操作,直接调用API就可以,不需要关心里边的逻辑。
  2. 数据读写更方便:任何组件不管在哪里,都可以直接读写数据。比如说,原来Tags子组件里的标签列表是由它的父组件Money传进去的,如果它要增加标签,不能自己增加,要把数据传出去在外边修改。现在做了全局数据管理之后,Tags子组件完全可以自己直接调用store,读写数据,不需要由父组件操作。
  3. 控制力更强:组件对数据的读写只能使用 store 提供的 API 进行(当然也不排除有猪队友直接对 tagList 和 recordList 进行 push 等操作,这是没有办法禁止的) 前提:

我们在Money.vue里,通过recordList=store.recordList ,这个data是从存储库里取出来的,他是一个数组,所以他们共用一个地址。所以我在store里对store.recordList进行增删改查时,我的vue实例的数据recordList也会随着改变。

但是如果store里的数据不是对象,而是基本数据类型的数据呢?

我们知道,如果是基本数据类型,如字符串,数字等,传递时是复制值的。

如:如果在store里声明一个数字,

const store={
    count:0,
    addCount(){
        this.count+=1
    },
    ...recordStore,
    ...tagStore
}

然后在Money里,

export default class Money extends Vue{
        count=store.count
        add(){
            store.addCount()
            console.log(store.count);
        }

把store.count赋值给自己的data,然后点击一个按钮调用add。发现页面里展示的count,没有变,还是0.

因为这是值传递,改变的只是store里的count。

那怎么做能同步呢?使得修改store.count,我这个实例上的count也会跟着改变呢?

不要用data获取,因为data只会获取一遍,后边的就不会再更新了

用computed计算属性

@Component({
        components: {FormItem, Type, Tags, NumPad},
        computed:{
            count(){
                return store.count
            }
        }
})

在ts里,computed写在@Component里。

我这个count是一个计算属性,他的值是返回store.count的值。但是点击之后,页面上的0还是没有加1 .

因为Vue并没有监听store对象,所以改变store,Vue并不知道。那就把store写在data里,

import store from "@/store/index2.ts"
  export default{
    data(){
      return {
        store:store,
      }
    }
  }

为了不重复,我们把它放在App.vue里,这样Vue就监听了store对象。

这样做了以后,点击按钮,成功加1.

之后为了方便,不管是对象,还是基本的数据类型,我们都放在计算属性里,然后全局监听store对象。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
相关文章
|
前端开发 测试技术 对象存储
Grafana Loki查询加速:如何在不添加资源的前提下提升查询速度
Grafana Loki查询加速:如何在不添加资源的前提下提升查询速度
461 59
|
XML 前端开发 Java
怎样将MultipartFile和File互转
该文介绍了如何在Java开发中优雅地转换MultipartFile和File。MultipartFile是Spring框架用于接收上传文件的类,而File是操作系统文件的代表。文章提供了三种将MultipartFile转换为File的方法:使用`transferTo`方法、FileOutputStream和Java NIO。另外,还介绍了在测试场景下将File转换为MultipartFile,通过MockMultipartFile实现。
1411 1
|
9月前
|
算法
新公海池:实现客户资源的最大化挖掘
在当今商业环境中,CRM行业正经历关键转型。传统线索分配模式常导致资源浪费和分配不均,影响销售业绩与企业发展。自动化线索分配系统通过算法和规则引擎,根据线索来源、客户地域等多因素精准分配,确保及时有效跟进。新公海池模式集中管理线索、客户和商机,灵活调整分配规则,支持线索回收再分配,避免资源浪费。这不仅提升资源利用效率,还助力企业降低获客成本,提高销售转化率,增强整体竞争力。自动化线索分配将成为CRM行业的核心竞争力,助力企业在激烈市场竞争中脱颖而出。
|
传感器 监控 搜索推荐
物联网技术在智能家居中的应用:技术革新与未来展望
【7月更文挑战第21天】物联网技术在智能家居中的应用已经取得了显著的成效,并展现出广阔的发展前景。通过实现设备集成、远程控制与监控、能源管理与节能减排等功能,物联网技术为智能家居系统带来了诸多优势和创新点。未来,随着技术的不断进步和市场的不断扩展,智能家居将更加智能化、自动化和人性化,成为我们生活中不可或缺的一部分。
|
存储 SQL Java
MySQL中的字段类型对应于Java对象中的数据类型
还在纠结javaType和jdbcType?MySQL数据类型对应Java什么类型?JdbcType类型和Java对象有什么对应关系?数据库类型的Integer是对应int还是对应Integer?本文带你一探究竟!
592 1
MySQL中的字段类型对应于Java对象中的数据类型
|
Java Linux Windows
[亲测有效]BAT批处理脚本执行Jar包,使用自带Java环境Jre
写好了一个jar包,使用了Java8的新特性,需要发布给客户,考虑到客户并不一定会使用Java8,所以就把JRE8一起发布了,分为Windows和Linux两个版本,各自写了一个脚本来运行。
|
SQL 关系型数据库 MySQL
MyBatis-plus配置自定义SQL(执行用户传入SQL)
MyBatis-plus配置自定义SQL(执行用户传入SQL)
952 0
|
弹性计算 关系型数据库 MySQL
数据库连接异常:create connection error, url: jdbc:mysql://ip/数据库名, errorCode 0, state 08S01问题处理
今天项目中新增了一部分接口,本地测试好之后打包部署到测试环境,数据库竟然连接失败,报错信息如下:create connection error, url: jdbc:mysql://ip/数据库名, errorCode 0, state 08S01,这个报错信息的意思数数据库连接异常,相信很多人都遇到过,现在总接一下数据库远程连接遇到此问题的定位思路。
数据库连接异常:create connection error, url: jdbc:mysql://ip/数据库名, errorCode 0, state 08S01问题处理
|
安全 测试技术 Shell
网站渗透测试报告速写模板指南
网站渗透测试服务在给客户写报告模板或者检查表的时候,应逐步完善。写报告在渗透测试中耗费大量的时间和精力。花费的时间取决于客户和经理期望的交付成果。(中文大概意思是客户和老板能不能看懂你的报告)奖励项目报告通常比渗透测试报告短,但是无论什么格式,您都将受益于为每个文档和测试类型创建模板(黑盒、白盒、Web、网络、wifi)。
558 0
网站渗透测试报告速写模板指南
|
安全 算法 网络协议
IPSec隧道配置案例(手动模式)
要求 • 配置IP地址、DHCP、路由、NAT • 内网可以访问公网2.2.2.2 • 配置IPsec VPN • PC1能直接访问PC2 • 抓包验证数据是否加密
891 0
IPSec隧道配置案例(手动模式)