# share_data **Repository Path**: codeResp/share_data ## Basic Information - **Project Name**: share_data - **Description**: 非 vuex 的数据共享解决方案. - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-01-26 - **Last Updated**: 2022-01-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # vue 实现数据共享模式. vue 都是组件化的开发模式. 整个组件树中,组件和组件之间的关系如下图所示. ![截屏2022-01-26 下午6.27.05](assets/%E6%88%AA%E5%B1%8F2022-01-26%20%E4%B8%8B%E5%8D%886.27.05.png) 父子组件传值一般用 `props` & `events` 即可. 但是非父子组件之间,如果传值会有很多的解决方案. 一般都建议使用 `vuex` 官方提供的集中式状态管理工具. 但此方案有可能过于笨重,写起来也并不方便,还需要专门引入 `vuex` 库,增大项目的打包体积. --- ## 使用 store 模式 使用 `store` 模式来解决组件间数据状态共享的问题. `store` 模式的核心很简单: + 每个组件实例都能访问到这个`store`对象. + 当 `store` 对象的某个值发生改变时,所有依赖于这个 `store` 组件的对象都会更新. --- ## 第一种 store 模式 定义一个很简单的全局单例对象,此提供一些数据,在组件间共享. 将此对象定义在需要使用到的组件,并设置在 `data` 属性上即可. ```JavaScript export default { shareName: "张三", changeName (name) { this.shareName = name }, changeNameAsync (name) { setTimeout(() => { this.shareName = name }, 2000); } } ``` A 组件需要使用. ```JavaScript import shareData from "../share_data/share_data"; export default { name: "HelloWorld", data () { return { shareData, // 此数据被框架内部的 initData 设置成响应式,被设置依赖的收集和触发. }; }, methods: { changeShareName () { this.shareData.changeName("李四"); }, }, }; ``` B 组件需要使用. ```javascript import shareData from "../share_data/share_data"; export default { name: "HelloWorld", data () { return { shareData, }; }, methods: { changeShareName () { this.shareData.changeNameAsync("王五"); }, }, }; ``` 效果: ![单例模式](assets/%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F.gif) 总结: + 定义一个数据单例 (`export default & import` 在 webpack 打包后,就是单例的,没有必要在进行特别处理)对象用于存储需要在组件间共享的数据. + 共享数据对象间接依赖组件本身的 `data` 节点,将它转换成响应式,并完成数据的依赖收集和更新触发. --- ## 第二种 store 模式 第一种 `store` 模式虽然已经完成了数据的共享和数据的修改,但有时候,我们需要更过的对数据操作的功能. 所有,就有了第二种. **使用一个 `new Vue` 实例,去承载共享数据的功能. 实例内部的 `methods`, `computed` , `watch` 等,可以用于对数的监视和控制.** > 此 `new Vue` 实例,主要功能是在共享数据提供.它不需要在 UI 上显示.所以,也不需要 `template` 以及 `render`. ```javascript import Vue from 'vue' // 提供一个不在 UI 上显示的 Vue 组件实例. // 让其的主要目的是为了保持数据共享和响应式. const share_data = new Vue({ data () { return { shareName: '张三' } }, methods: { changeName (name) { this.shareName = name }, async changeNameAsync (name) { return new Promise((resolve, reject) => { setTimeout(() => { this.shareName = name resolve(this.shareName) }, 2000); }) } }, watch: { shareName: { handler (newVal, oldVal) { if (newVal === oldVal) return // otherwise do something..... }, immediate: true } } }) export default share_data // main.js import shareData from './share_data/share_data' Vue.prototype.$shareData = shareData ``` 在 A 组件上使用 ```javascript ``` 在 B 组件上使用 ```javascript ``` 效果: ![非显示组件模式](assets/%E9%9D%9E%E6%98%BE%E7%A4%BA%E7%BB%84%E4%BB%B6%E6%A8%A1%E5%BC%8F.gif) 总结: + 定义一个非显示的 `new Vue` 组件实例,用于数据管理. + 相比较简单的 `plain object` 共享, 组件实例提供了丰富了数据管理的 `API` 功能.