前端答疑-对象引用-Vue共享数据源的三种方式

简介: 事情发生在上周团队技术分享的时候。起因在于一个问题:vue 中多个组件如何使用同一个变量,我们叫这个变量为 baseConfig 吧。说实话我没想到那么多人不理解其中的知识。今天我整理一下发出来。

方案一:VUEX


什么是 Vuex


Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。

状态自管理应用包含以下几个部分:


  • state,驱动应用的数据源;
  • view,以声明方式将 state 映射到视图;
  • actions,响应在 view 上的用户输入导致的状态变化。


以下是一个表示“单向数据流”理念的简单示意:

bVGvdp.webp.jpg


Vuex 的应用


其实看完了上面的介绍,我们就明白,这是一个非常符合我们需求的工具。那么我们就来看看怎么去应用。


  • mapState 辅助函数 当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性。


  • 从下面的例子可以看到,我们子组件中的值是通过计算属性来从 store 中获取的。这样在通过 mutations 等方式改变之后,我们的值也会动态更新。


  • 当然,你的页面简单的时候,也不需要再去使用 Vuex,考虑一下后面的方案吧。


const store = new Vuex.Store({
  state: {
    baseConfig: {
        server_name: 'lilnong.top'
    }
  }
})
// 创建一个 User 组件
const Serv = {
  template: `<div>{{ server_name }}</div>`,
  computed: {
    server_name() {
      // this.$store
      return store.state.baseConfig.server_name
    }
  }
}
const app = new Vue({
  el: '#app',
  store, // 这样可以把 store 的实例注入所有的子组件
  components: { Serv },
  template: `
    <div class="app">
      <serv></serv>
    </div>
  `
})


方案二:父子组件传参


父传参的方式


baseConfig 需要定义在最外面,然后给所有的子组件都传递进去,当有改变的时候,子组件也会跟着改变。


{
    data: {
        baseConfig: {
            server_name: 'lilnong.top'
        }
    }
}
<child :server_name="baseConfig.server_name" :baseConfig="baseConfig">


子组件接受参数的方式


每个子组件都需要接收。


{
    props:['server_name', 'baseConfig'],//这种是无默认值,无类型检查的,正常使用不推荐这种写法
}


父子组件方案的优缺点


  1. 所有的父组件都需要传递参数,所有的子组件都要接收参数。


  1. 传入的问题可以通过,传入一个对象的所有参数来解决


方案二:路由组件传参


该方案也叫方案二,并不是我写错了,是因为他们的场景是一样。


在 Vue Router 的路由中,我们把组件配置在 routes 中,导致我们无法在模板之中传递参数。


这里我们需要使用他提供的 props 属性来传参,文档地址jsRun测试地址


lilnong.top测试地址
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar }
]
const router = new VueRouter({
  routes // (缩写) 相当于 routes: routes
})
const app = new Vue({
  router
}).$mount('#app')


<div id="app">
  <h1>Hello App!</h1>
  <p>
    <router-link to="/foo">Go to Foo</router-link>
    <router-link to="/bar">Go to Bar</router-link>
  </p>
  <router-view></router-view>
</div>


方案三:全局对象(store 模式)


简单状态管理起步使用 --官方文档


全局对象


就是如下使用,定义一个全局对象,然后修改这个全局对象就好了


const sourceOfTruth = {}
const vmA = new Vue({
  data: sourceOfTruth
})
const vmB = new Vue({
  data: sourceOfTruth
})


store 模式


原理上来讲,还是全局对象,但是通过简单的规定,来明确数据流向

var store = {
  debug: true,
  state: {
    message: 'Hello!'
  },
  setMessageAction (newValue) {
    if (this.debug) console.log('setMessageAction triggered with', newValue)
    this.state.message = newValue
  },
  clearMessageAction () {
    if (this.debug) console.log('clearMessageAction triggered')
    this.state.message = ''
  }
}
var vmA = new Vue({
  data: {
    privateState: {},
    sharedState: store.state
  }
})
var vmB = new Vue({
  data: {
    privateState: {},
    sharedState: store.state
  }
})

view.webp (9).jpg


争论核心:全局对象方案究竟行不行?原理?


好了,三种方案这里就已经介绍完了。那开始看看我们的争论:全局放个对象的方式不行(对方观点),数据更新时组件不会自动更新


先说原理,内存地址


vue 数据绑定的原理大家都懂吧?通过 defineProperty 来劫持,Dep 收集依赖等等。


对于对象类型的数据,我们变量里面保存的其实是一个指向堆的地址,我们来看下面的这个例子。

var obj = {};//定义了一个对象,`obj` 存放的是一个地址
obj.a = 1;//通过 `obj` 的地址,找到对象,然后给对象里面放了 `a=1` ;
var obj1 = obj;//把 `obj` 的地址,给 `obj1` 复制了一下
obj1.a = 2;//通过 `obj1` 的地址,找到对象,然后给对象里面放了 `a=2` ;
//这个时候,对象里面存放的就是{a:2}//console.log(obj, obj1)
//这里引出了另一个问题 深拷贝与浅拷贝


这里也就是我的核心原理。


  1. 定义一个对象(保存在 window 上)
  2. 通过对象变量保存的是地址的原理
  3. 我们在其他组件都用 window 上的对象以此来达到目的。


再说场景,细化问题


是不是看到上面的原理好简单?但是往往不是这么简单,下面咱们分析一下情况


  1. window 上没绑对象,而是其他类型这么办?比如说 nullundefined
    主要原理就是地址引用。


  1. 对象覆盖,就是如下的这个赋值场景。其实我理解你是想给obj重新都赋值一下。
obj={};
obj2 = obj;
obj.a = 1;
obj2 = {a:2,b:3};//这里把 obj2 的地址换成了新的一个对象
//console.log(obj, obj2)


但是不能这样写,正确操作如下:


  1. Object.assign(obj2, {a:2,b:3})
  2. 一个一个值的写 obj2.a=2;obj2.b=3;

       c.后添加的属性,没有计入vue的数据观察队列(新手经常犯的错误


  1. 对象变更检测注意事项


于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除:

var vm = new Vue({
 data: {
   a: 1
 }
})
// `vm.a` 现在是响应式的
vm.b = 2
// `vm.b` 不是响应式的


  1. 对象解决方案 Vue.set(object, propertyName, value)
    对象解决方案(实例内) this.$set(object, propertyName, value)


       b.数组更新检测将一些方法进行了封装push()、pop()、shift()、unshift()、splice()、sort()、reverse()。通过上面的方法来改变数组可以监听到改变。由于 JavaScript 的限制,Vue 不能检测以下数组的变动:


  1. 当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
  2. 当你修改数组的长度时,例如:vm.items.length = newLength


总结


共享数据三种方法


  1. vuex
    大而全,使用复杂


  1. 组件值传递
    原生自带,使用复杂,适合组件相关数据


  1. store
    简单,不适合复杂项目。工程的话,还是推荐 vuex


对象引用需要注意的地方


  1. 不能给变量二次赋值obj2={}


  1. 只有对象类型才是存地址, ArrayObject
    StringNull等不包括在内


  1. 增加数据要注意是否被观察到
  1. 对象:注意 Vue.set
  2. 数组:使用规定方法


测试地址,采用 setTimeout 来模拟异步操作。


资料


  1. VUEX 中文站
  2. 状态管理 --vue官网
相关文章
|
存储 前端开发 安全
前端如何存储数据:Cookie、LocalStorage 与 SessionStorage 全面解析
本文全面解析前端三种数据存储方式:Cookie、LocalStorage与SessionStorage。涵盖其定义、使用方法、生命周期、优缺点及典型应用场景,帮助开发者根据登录状态、用户偏好、会话控制等需求,选择合适的存储方案,提升Web应用的性能与安全性。(238字)
521 0
|
7月前
|
JavaScript 前端开发 Java
制造业ERP源码,工厂ERP管理系统,前端框架:Vue,后端框架:SpringBoot
这是一套基于SpringBoot+Vue技术栈开发的ERP企业管理系统,采用Java语言与vscode工具。系统涵盖采购/销售、出入库、生产、品质管理等功能,整合客户与供应商数据,支持在线协同和业务全流程管控。同时提供主数据管理、权限控制、工作流审批、报表自定义及打印、在线报表开发和自定义表单功能,助力企业实现高效自动化管理,并通过UniAPP实现移动端支持,满足多场景应用需求。
649 1
|
存储 监控 安全
前端框架的数据驱动方式如何保证数据的安全性?
总之,前端框架的数据驱动方式需要综合运用多种手段来保证数据的安全性。从传输、存储、访问控制到防范攻击等各个方面进行全面考虑和实施,以确保用户数据的安全可靠。同时,不断加强安全管理和技术创新,以应对不断变化的安全挑战。
438 60
|
8月前
|
移动开发 前端开发 JavaScript
Vue与React两大前端框架的主要差异点
以上就是Vue和React的主要差异点,希望对你有所帮助。在选择使用哪一个框架时,需要根据项目的具体需求和团队的技术栈来决定。
480 83
|
9月前
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
480 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
7月前
|
JavaScript 前端开发 编译器
Vue与TypeScript:如何实现更强大的前端开发
Vue.js 以其简洁的语法和灵活的架构在前端开发中广受欢迎,而 TypeScript 作为一种静态类型语言,为 JavaScript 提供了强大的类型系统和编译时检查。将 Vue.js 与 TypeScript 结合使用,不仅可以提升代码的可维护性和可扩展性,还能减少运行时错误,提高开发效率。本文将介绍如何在 Vue.js 项目中使用 TypeScript,并通过一些代码示例展示其强大功能。
290 22
|
9月前
|
前端开发 Cloud Native Java
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
|
10月前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
646 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
9月前
|
人工智能 JavaScript 前端开发
Vue 性能革命:揭秘前端优化的终极技巧;Vue优化技巧,解决Vue项目卡顿问题
Vue在处理少量数据和有限dom的情况下技术已经非常成熟了,但现在随着AI时代的到来,海量数据场景会越来越多,Vue优化技巧也是必备技能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
JavaScript 前端开发 搜索推荐
Vue的数据驱动视图与其他前端框架的数据驱动方式有何不同?
总的来说,Vue 的数据驱动视图在诸多方面展现出独特的优势,其与其他前端框架的数据驱动方式的不同之处主要体现在绑定方式、性能表现、触发机制、组件化结合、灵活性、语法表达以及与后端数据交互等方面。这些差异使得 Vue 在前端开发领域具有独特的地位和价值。
262 58

热门文章

最新文章

  • 1
    前端如何存储数据:Cookie、LocalStorage 与 SessionStorage 全面解析
  • 2
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
  • 3
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
  • 4
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
  • 1
    前端如何存储数据:Cookie、LocalStorage 与 SessionStorage 全面解析
    521
  • 2
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
    195
  • 3
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
    192
  • 4
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
    147
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
    252
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
    365
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
    160
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
    96
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
    162
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
    228