说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

详解React Flux架构工作方式

HTML文档下载 WORD文档下载 PDF文档下载
Flux是Facebook内部用来构建React应用的一套架构,该架构的最大特点是其倡导的单向数据流方案。本文将重点讨论Facebook Flux架构的工作方式,以及开发者应该如何在项目中使用它。

【编者按】作者Ken Wheeler在《 Getting To Know Flux, the React.js Architecture》一文中 讨论Facebook的Flux架构的工作方式,以及开发者应该如何在项目中使用它。为了让前端开发者更好地掌握本文内容,景庄对该文章进行了翻译,内容如下:

什么是Flux

Flux是Facebook内部用来构建React应用的一套架构。它本身并不是一个框架或库。它仅仅是一个用于完善React应用开发的一种新的应用程序架构,Flux架构最大的特点是其倡导的单向数据流方案。

Facebook还提供了Dispatcher的开源库。你可以将Dispatcher认为是一种全局pub/sub系统的事件处理器,用于向所注册的回调函数广播payloads。通常情况下,如果你使用Flux架构,你可以借助于Facebook提供的这个Dispatcher实现,并且可以借助NodeJS中的EventEmitter模块来配置事件系统, 从而帮助管理应用程序的状态。

组成结构

Flux主要包括下面四个独立的组件,下面简单地解释下:

  • Actions:帮助向Dispatcher传递数据的辅助方法;
  • Dispatcher:接收action,并且向注册的回调函数广播payloads;
  • Stores:应用程序状态的容器&并且含有注册到Dispatcher的回调函数;
  • Controller Views:React组件,从Store获取状态,并将其逐级向下传递给子组件。

让我们通过一幅图来简单看一下这四个部分的关系:


如何处理外部API

但是,很多场景下不仅仅包括应用程序内部的状态数据,还可能包括来自外部的数据,也就是如果我们需要消费RESTful服务,那么我们该如何将这些外部数据引入到Flux架构的单向数据流中呢?经过实践,我们发现,在Action中引入外部数据流是个不错的实践, 数据然后再被送到Store中。

在继续阅读之前,我强烈建议你阅读下Facebook提供的Flux官方示例程序的 源代码。在你简单阅读了这个例子的源代码后,我们再来详细的探讨Flux中这几个组件的作用:

Dispatcher

我们首先来看看Dispatcher的作用:你可以将Dispatcher看成是Flux架构中整个数据流程的管理者。或者你可以将它看成你整个应用的中央交换机。Dispatcher接收actions作为payloads,并且将payloads分发给所注册的回调函数。

那么它就是一个pub/sub吗?

不完全是。Dispatcher会将payload广播给所有向它注册的回调函数,并且包括了允许你以指定次序调用这些回掉函数的执行逻辑,例如在处理前等待数据更新。在Flux架构中只有一个Dispatcher,它是你整个应用的中央Hub。我们来创建一个简单的Dispatcher:

var Dispatcher = require('flux').Dispatcher;var AppDispatcher = new Dispatcher();AppDispatcher.handleViewAction = function(action) {  this.dispatch({    source: 'VIEW_ACTION',    action: action  });}module.exports = AppDispatcher;

在上面的代码中,我们创建了一个Dispatcher的实例,它包括了一个叫做handleViewAction的方法。创建这个方法的目的是为了让你能够轻松的区分, 是视图层触发的action,还是服务器/API触发的action。

在handleViewAction方法中调用了dispatch方法(该方法来自Dispatcher实现),它会将payloads广播给所有注册到它的回调函数 (注意,这里所说的回调是在store中注册给Dispatcher的)。然后,action会触发Store中相应事件,并最终体现在state的更新上。

可以用下面这张图来表示这个过程:


依赖

Facebook所提供的Dispatcher模块还有一个非常赞的功能,那就是它能够定义依赖,并在Store中向Dispatcher注册回调函数。 因此,如果你的应用的某个部分依赖于其他部分的数据更新,为了能够进行合适的渲染,Dispatcher中的waitFor方法将会非常有用。

为了能够利用这一特性,我们需要在Store中存储注册给Dispatcher的回调函数的返回值,这里,我们命名为dispatcherIndex:

ShoeStore.dispatcherIndex = AppDispatcher.register(function(payload) {});

然后在Store中处理每一个被分发的action时,我们可以使用Dispatcher的waitFor方法来确保我们的ShoeStore已经被更新了,示例代码如下:

case 'BUY_SHOES':  AppDispatcher.waitFor([    ShoeStore.dispatcherIndex  ], function() {    CheckoutStore.purchaseShoes(ShoeStore.getSelectedShoes());  });  break;

Stores

在Flux中,可以用Store来分领域的管理应用程序的状态,例如ShoeStore、AppStore等。从一个更高层角度来看,可以简单地认为应用的每一个部分可以对应于一个Store,Store可以用来管理数据,定义数据检索方法,此外,Store中还包括了注册给Dispatcher的回调函数。

下面我们来看一个简单的Store的例子:

var AppDispatcher = require('../dispatcher/AppDispatcher');var ShoeConstants = require('../constants/ShoeConstants');var EventEmitter = require('events').EventEmitter;var merge = require('react/lib/merge');// Internal object of shoesvar _shoes = {};// Method to load shoes from action datafunction loadShoes(data) {  _shoes = data.shoes;}// Merge our store with Node's Event Emittervar ShoeStore = merge(EventEmitter.prototype, {  // Returns all shoes  getShoes: function() {    return _shoes;  },  emitChange: function() {    this.emit('change');  },  addChangeListener: function(callback) {    this.on('change', callback);  },  removeChangeListener: function(callback) {    this.removeListener('change', callback);  }});// Register dispatcher callbackAppDispatcher.register(function(payload) {  var action = payload.action;  var text;  // Define what to do for certain actions  switch(action.actionType) {    case ShoeConstants.LOAD_SHOES:      // Call internal method based upon dispatched action      loadShoes(action.data);      break;    default:      return true;  }    // If action was acted upon, emit change event  ShoeStore.emitChange();  return true;});module.exports = ShoeStore;

以上代码可能做的最重要的一件事就是:我们使用NodeJS中的EventEmitter模块来扩展我们的Store。这使得我们的Store能够监听和广播事件。这也使得我们的视图/组件能够基于这些事件来更新。 这是因为我们的控制器视图(Controller View)会监听我们的Store, 并利用这一点通过发出事件方式通知控制器视图应用程序的状态发生了改变, 从而进行视图层的重新渲染。

在Store中还有一个值得注意的事,那就是我们使用Dispatcher的regiter方法来注册回调函数。 这意味着,我们创建的Store会监听来自AppDispatcher的广播,这里我们使用switch语句来 区分广播内容所对应的action。如果一个相关的action发生了,那么就触发一个change事件,并且监听 此事件的视图会根据新的状态(state)进行重新渲染。这个过程如下图所示。


在上面的代码中,ShoeStore中还包括一个公共方法getShoes(),它可以在控制器视图中被调用, 用于检索所有在_shoes对象中的数据,并且使用这个数据作为组件的状态数据。因为这是个非常简单 的例子,在实际应用开发中你可以使用更加复杂的数据处理逻辑。

Action创建器和Actions

行为创建器(Action Creators)是一组会在视图中被调用的方法(也可以在其他地方使用), 它们用于向Dispatcher发送actions。也就是说,我们使用Dispatcher分发的payloads,实际上就是actions。

在Facebook提供的例子中,action的类型常数被用于定义这些action所被应用的场景,并且是伴随着action一起被传递的。现在,在所注册的回调函数内部,这些actions可以根据他们的action类型来处理。

我们可以看一个简单的类型常数的定义:

var keyMirror = require('react/lib/keyMirror');module.exports = keyMirror({  LOAD_SHOES: null});

在上面的代码中,我们用了React的keyMirror库来生成我们的类型常数的Key/Value对。如果仅仅是看这个文件,我们大致可以猜到我们的应用会加载鞋子(shoes)。借助于类型常数,可以使得应用 中涉及到的事物变得更加地可组织,可以让开发者能通过这样的高层抽象来组织应用程序。

现在,让我们来大致的看一个对应的行为创建器(action creator)的定义:

var AppDispatcher = require('../dispatcher/AppDispatcher');var ShoeStoreConstants = require('../constants/ShoeStoreConstants');var ShoeStoreActions = {  loadShoes: function(data) {    AppDispatcher.handleAction({      actionType: ShoeStoreConstants.LOAD_SHOES,      data: data    })  }};module.exports = ShoeStoreActions;

在上面的代码中,我们在定义了ShoeStoreActions对象,并在其中定义了loadShoes()方法, 该方法内调用了来自AppDispatcher的handleViewAction方法,并且将相应的行为类型与 我们提供的数据相关联。现在,我们可以在我们的视图代码或API中引入这个action文件。我们可以调用ShoeStoreActions.loadShoes(ourData)方法来向Dispatcher发送payload,随后Dispatcher会将它广播出去。ShoeStore则会监听来自Dispatcher的广播,并且触发相应的事件来加载相应的鞋子。

控制器视图 Controller View

你可以简单的将控制器视图理解为React组件,这些组件会监听change事件,如果事件发生了, 就从Stores中获取应用程序新的状态数据。随后,可以将数据通过props逐级向子组件传递。这个过程大致如下图所示:


让我们来看看代码长啥样:

/** @jsx React.DOM */var React = require('react');var ShoesStore = require('../stores/ShoeStore');// Method to retrieve application state from storefunction getAppState() {  return {    shoes: ShoeStore.getShoes()  };}// Create our component classvar ShoeStoreApp = React.createClass({  // Use getAppState method to set initial state  getInitialState: function() {    return getAppState();  },    // Listen for changes  componentDidMount: function() {    ShoeStore.addChangeListener(this._onChange);  },  // Unbind change listener  componentWillUnmount: function() {    ShoesStore.removeChangeListener(this._onChange);  },  render: function() {    return (      <ShoeStore shoes={this.state.shoes} />    );  },    // Update view state when change event is received  _onChange: function() {    this.setState(getAppState());  }});module.exports = ShoeStoreApp;

在上面的代码中,我们使用addChangeListener来监听change事件,并且在接收到事件后更新应用程序的状态数据。

我们的应用程序状态数据存储在Store中,因此我们可以用Store中的公共方法来获取数据,然后将其设置为应用程序的状态。

完整的数据流程

前面我们依次解读了Flux架构中的每一个独立部分,我们有了对Flux架构中的每一个组件的一个大致的认识, 并且能大致的了解了Flux架构的工作流。在这之前,我们已经通过了几张图片描述了数据在组件之间的流向, 现在让我们将上面的子流程组合起来,以更好的理解Flux的数据流:


小结

在读完这篇文章后,如果你之前并不了解Facebook的Flux架构,那么希望你现在能够说理解了。 但另一方面,如果不在React的实际编程开发中使用这一架构,你是很难真正的体会到Flux架构的 特点的。

当你使用Flux后,你会发现没有Flux的React应用开发就相当于是没有jQuery的DOM遍历操作。也就是说, 没有Flux你可以照常进行React应用开发,但是你在代码组织和数据流程上会缺乏优雅的解决方案。

另一个方面,如果你想使用FLux架构,但你并不想使用React,那么你可以参考 Delorean,它是一个Flux框架,并且可以让你使用Ractive.js或者Flight。另一个值得参考的库是 Fluxxor,它实现了在紧耦合的Flux组件中包含一个中央Flux实例。

最后,再次说明,如果要真正的理解Flux,你就得在实际开发中体验它。

原文链接:Getting To Know Flux, the React.js Architecture

译者简介:景庄,前端工程师,关注Node.js、前端工程化。个人博客: http://wwsun.github.com。


欢迎加入CSDN前端交流群2:465281214,进行前端技术交流。  

也可参加CSDN前端大讲堂(微信公开课),享受高含金量在线公开课,与专家讲师在线切磋交流。

如何加入CSDN前端大讲堂?由于该群目前已超过人数限制,所以您首先不得不 扫描下面二维码,加CSDN编辑陈秋歌为好友,然后请她邀请您加入CSDN前端大讲堂微信群。加好友时,请务必注明“申请加入CSDN前端大讲堂”。


中国工程院院士李德毅:大数据时代的认知计算 创新工场联合创始人汪华:2013年中国移动互联网进入深入区 百度副总裁李明远:解答关于百度轻应用的八大疑问 谷歌推出PNaCl,帮助开发者在任何硬件和网站上运行代码 阿里云:双十一350亿交易额的幕后英雄 索尼移动智能设备全球技术总监Goran Andersson:索尼移动可穿戴设备解决方案 腾讯社交网络事业部副总裁陈磊:腾讯移动开发者服务体系 基调网络副总裁陈靖华:全面掌握移动应用性能 蓝港在线创始人王峰:手游新时代下的机会与挑战! Couchbase CEO Bob Wiederhold:数据库云端同步,移动应用开发的未来 三星电子大中华区副总裁黄伽卫:构建移动互联生态,解读内容服务新方向 MDCC 2013移动开发者大会:新浪潮,新硬件! 网站建设,如何平衡产品特性和利益需求? 开发者是如何提升技能水平的 Databricks核心成员专访:大数据时代“智能手机”Spark 数据密集、快速启动、核心应用,IBM存储重兵布阵 企业移动应用与BYOD:移动互联大势所趋 “首届智能硬件峰会”上午会议亮点汇总 代价究竟高不高,苹果为什么要在Android专利诉讼上花费2亿美元? 产品与设计专题论坛(下):App之美 产品与设计专题论坛(上):扁平还是拟物?产品说了算! 首届移动娱乐游戏峰会:中外手游的交锋与对抗(下) 研发人员超过500,基金会金牌会员,华为豪赌OpenStack New way of thinking:索尼SmartWatch 2应用开发马拉松大赛圆满结束 离了你地球照样转,谷歌地图并非苹果的必需品 面试必备的9大成功秘诀 Chuck Goldman:乔布斯从来不会说苹果不是企业应用的公司 全球最大的图片社交分享网站Pinterest发布首个API UX设计程序的五个谬论 研发周报:2013年美国开发者薪资调查报告 【开源推荐】PredictionIO:构建预测功能的机器学习服务器 关于volatile 修饰词 过去用Delphi开发数据库都是用Access,现在急需使用SQL Server。请问:我必须掌握SQL Server中的那些内容。 如果我想删除日志文件的所有记录该怎么办?????? 怎么样把两个ArrayList合并成一个??我在文档里找了半天也没找到!急~~!!!!!!! 请问,NT4.0下怎样配置网关和路由? 请问如何知道一个弹出菜单是否以经关闭 升级后问题,奇怪,请指教? 什么是存储过程? 大侠们帮忙看看,简单问题 急:因出差,明天(12.20,第二期)的“微软.net高级程序员培训”转让(包括资料)!今晚6:00前联系,13910321169. 请问怎样才能在Access中选取指定行数的记录如第5-10条. 关于XML命名空间的疑问?请教各位高手帮帮忙!谢谢! 请问哪里有《情深深雨蒙蒙》下载??? ******斑竹快出来啊 看看我这个贴子啊!!!!!!!!!!!!!! 如何读取寄存器中的数据? 请问在数据库中如何操作日期型字段: Help,如何把本机加入主域服务器? 急:因出差,明天(12.20,第二期)的“微软.net高级程序员培训”转让(包括资料)!今晚6:00前联系,13910321169 怎么用vbscript定义一个函数阿。我想作一个下拉框的onchange事件,请指教 如何确定adoquery的数据是否被修改了? 有关程序调试的问题 全都转行卖大白菜。 对于各个.h和.cpp文件分工如何,我的各种函数各个变量到底该放在哪个文件中的哪个class中? 如何停止asp调用的dll文件,我调用my_dll.dll文件一次之后就不能对my_dll.dll更改了,为什么?怎样解决? 急:因出差,明天(12.20,第二期)的“微软.net高级程序员培训”转让(包括资料)!今晚6:00前联系,13910321169.. 关于附件下载过程中权限控制的问题 如何编辑LILO文件? 糊涂啦。。。看看汉字库(hzk24)吧? 请问在listbox控件中如何设置特定行的颜色? 问一个关于ODBC的问题 急:因出差,明天(12.20,第二期)的“微软.net高级程序员培训”转让(包括资料)!今晚6:00前联系,13910321169.... 各位大侠,哪有设计专家系统的c语言的源代码阿(全分奉送)? 请问:如何处理MFC提供的CList类模板产生的异常问题呢? 散分!快抢! 调用对象 阿呆,只有你能救我了~~!!!!! 100大洋~~!!! Excel报表的汇总 请问VC有像Delphi或者C++Builder那样的作报表的工具吗? delphi怎么调用CHM文件啊? win98 登陆win nt Java远程调用的合法类型(legal types for Java RMI)都有哪些? 安装盘的制作问题 如何设置多个Timer? VFP的程序怎么才能运行在任何目录下?主程序应该怎么写? 这个问题很老套,但对于一个什么想成为一个优秀程序员的菜鸟来说,很重要,谢谢!进入........... @_@ 怎么灌水? 向资深灌水工请教! 难到这个问题没人回答吗?????http://www.csdn.net/Expert/topic/430/430088.shtm StringGrid中单元格合并问题? Delphi的TMainMenu和TPopupMenu没有Font属性,请问如何修改它们的字体? like 查询小问题 紧急求救:网管程序开发! 水平面上有一个物体受水平方向力的作用由静止开始无摩擦的运动,经过位移s1,速度达到v又经过位移s速度达到2v,则两段位移中该力所做功之比是多少? 将1~10这十个自然数分别填入图中的十个○内,使各条线段上四个○内数的和相等,每个三角形三个顶点上○内数的和也相等. 一个梯形,下底长14CM,高12CM,如果下底减少6CM,它就成为一个平行四边形.梯形的面积是多少? 在水平面上有一个质量为M的物体,在水平力作用下由静止开始运动一段距离后,到达一斜面底端.这时撤去外力.物体冲上斜面,沿斜面上滑的最大距离和水平面上运动的距离相等,然后物体又沿斜 一个梯形的下底是上底长度的3倍,将上底延长8厘米,则梯形变成平行四边形.梯形的上、下底各是多少厘米? 根号5在4*4方格上怎么画急 在恒定力F作用下,物体由静止开始运动,经过一段位移s后,速度达到v,做功为w.在相同的恒定合力F作用下,物体的速度由0增至nv,则F做得功是原来的___倍,若要物体的速度由v增至nv,则需对它做的功 为什么水在沸腾的实验中,发现上升的气泡大小不一样:开始时,气泡上升时逐渐变小;沸腾后气泡上升时逐渐变大,这是为什么? 10*10的方格中怎样画根号三不用尺子等辅助工具:calli159 怎么画根号2与1垂直 插入一个图片 水平地面上有一质量为10kg的物体,在50N水平力作用下由静止开始运动,6秒内位移为36m,6s末撤去这个水平力,则再经 s,前进 m距离物体停止运动.快 一个梯形的上底是下底的3倍,如果将梯形的下底延长8厘米,那么这个梯形变成了平行四边形.这个梯形的上、下底各是几厘米 要算式 利用4*4的方格画出边长为根号5的正方形只要算式,越快越好 一个三角形有多少个角?如果在三角形中添画一条线段,会增加多少个小于180 度角?在添画一条线段呢一个三角形有多少个角?如果在三角形中添画一条线段,会增加多少个小于180度角?在添画一条 一个梯形的上底是下底长度的3倍,如果将梯形的下底延长8厘米,那么这个梯形就成了平行四边形.上下底分别多少厘米 两个同样的梯形上底长23cm下底长27cm高20cm如果把这两个梯形分拼成一个平行四边形平行四边形的面积是多少是练习册上的, 一个三角形从一个角到对边引一条线分成2个三角形,问:有这个三角形共有几个角对边的那个平角算不? 梯形下底是上底的3倍,如果把上底延长8厘米就成了一个平行四边形,梯形的上底和下底是多少厘米 一个平行四边形的一条边是27cm,高是15cm,另一条边是18cm,另一条边上的高是多少? 一个三角形与一个平行四边形的面积和底都相等,平行四边形的高是4厘米,三角形的高是多少厘米? 长16厘米宽10厘米的长方形框架拉成一平行四边形,面积减少16平发厘米,那这平行四边形的高是多少厘米 数学题(等腰三角形的周长为16,底边上的高为4,求等腰三角形的面积) 泡泡枪的泡泡水怎么做?要求:做法简单,并且可以使用放心,对宝宝无害? 把一个面积是81平方厘米的正方形框架拉成一个平行四边形框架,面积减少了4.5平方厘 数学题解答器等腰三角形底边上的高为8周长为32,则三角形的面积为? 玩具泡泡枪里的泡泡水怎么配 材料中的“气球小车”是被怎样推动的 等腰三角形底边上的高为4厘米,周长为16厘米,求三角形的面积 将面积是72平方厘米的长方形框架拉成一个平行四边形后,面积减少9平方厘米.已知将一个面积是72平方厘米的长方形框架拉成一个平行四边形,面积减少了9平方厘米,已知长方形框架的长时9 从n边形出发,连接其余各顶点,n边形有几个三角形. 在家自己用钢盆电解水,却发现有新物质生成,图中气泡为氢气,那黄色的就是不明物质,我用的水槽在家自己用钢盆电解水,却发现有新物质生成,图中气泡为氢气,那黄色的就是不明物质,我用的 把一个长9厘米,宽6厘米的长方形框架拉成一个平行四边形,这时面积减少了10平方厘米,求平行四边形的面积 桌上放一个装满水的瓶子,中间有一个气泡,用手推一下瓶子,气泡将会向哪边运动,为什么? 一个梯形,上底长8厘米,如果下底缩短6厘米,则变成一个平行四边形,面积缩小了15平方厘米,梯形面积是C一个梯形,上底长8厘米,如果下底缩短6厘米,则变成一个平行四边形,面积缩小了15平方厘米, 如何自做泡泡水 水平放置的小瓶内装有水,其中有气泡,当瓶子从静止状态突然向右运动时,小气泡在瓶内将向何方运动?当瓶子向右匀速运动突然停止时,小气泡在瓶内又将如和运动? 数学题:小红要建一个面积为40平方厘米的三角形纸片,它的一边是10cm,那么它这边上的高是【】? 自制泡泡水过程作文怎么写 把一个长10cm宽8cm的长方形的框架拉成一个平行四边形这时面积减少了12平方cm平行四边形的高是多少cm用方程解 一个三角形的面积是100平方厘米,已知高是10厘米,则它的底是多少厘米? 如何自制吹泡泡水?小孩子玩的吹泡泡的玩具,用一个圆圈形的工具沾上泡泡水一吹,就能吹出好多泡泡, 桌上放一个装满水的瓶子,中间有一个气泡,用手推一下瓶子,气泡将是向前,但是气泡有惯性呀,不是先向原来位置的方向吗拜托,瓶子是横放的 ,气泡在液面 问一道数学题,等腰三角形斜边长为8厘米,因此三角形的面积是多少平方厘米? 自制泡泡水怎么弄?怎么记得小时候肥皂水就可以了呢 在三角形内一顶点引射线,当引到30条射线时有多少个三角形,规律及公式? 在网格中画出面积是根号10的正方形根号10不是周长 吹泡泡的水怎么自制 由三角形的一个顶点向对边引m条线段,可以得到多少个三角形?假设三角形个数为n,请写出n和m之间的关系式. 正方形网格中的每个正方形的边长都是1,以格点为顶点,画出一个三角形,使三边长分别是根号13,根号34,根号45. 把一个长为8厘米、宽为6厘米的长方形框架拉成一个平行四边形,这时面积减少了8平方厘米.求平行四边形的边为8厘米的边上的高是多少厘米? 1.三角形的中线是指连接三角形的一个顶点与它的对边的____的线段2.三角形的角平分线是指三角形的一个内角的____ __于对边交点的线段3.三角形的分类:①按___分,可分为______ _______ _______②按__ 将一个装满水静止瓶子向左推动,问水中气泡运动状况水具有惯性,仍保持原来静止的状态,但是既然瓶子已经运动,水怎么可能还会有静止的状态呢?高分悬赏 求解 1.把一个长为8厘米、宽为6厘米的长方形框架拉成一个平行四边形,这时面积减少了8平方厘米.求平行四边形边求平行四边形边长为8厘米的边上的高是多少厘米? 从三角形的一个顶点到它的对边作一条( ),( )之间的线段叫做三角形的高.( )叫做三角形的底. 正方形网格中画一个等腰三角形DEF,是它的腰长为根号5,且他的顶点都在都在格点上,一共可以画几个三角形..注意,彼此不全等 把一个长为8厘米,宽为6厘米的长方形框架拉成一个平行四边形,这时面积减少了8平方厘米.求平行四边形做边长为8厘米的边上高是多少厘米? 一辆运油的油罐车,油上方有气泡,当气泡突然想后运动时,此时车可能处于什么状态,为什么!要正确的答案, 水平放置的小瓶内装有水,中有气泡当瓶子突然从静止向右加速 则小气泡将如何运动 物体原来静止在水平地面上,在水平向东、大小不变的力作用下,物体做匀加速运动,经过一段位移到A点时速度为V.此时作用力方向不变、大小立即增大为原来的3倍,又经过同样大小的一段位移 三角形的一个顶点到()的()线段叫做三角形的高 在上底18cm,下底30cm,高12cm的梯形中剪下一个最大的平行四边形,剩下的面积是多少平方厘米?列式计算
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn