数据传递在项目中是个很重要的话题,因为它牵扯到了一个APP,或者web-app的最重要一步:功能联动。
丝毫不隐瞒的说,笔者曾经迫切的想要学node.js的动力之一就在于它可以作为后端去进行数据的处理和传递使用。这在之前是不可能单单通过前端实现的。
原生JavaScript中的数据传递
后来,HTML进化到了HTML5,内增了API——localStorage & sessionStorage。
但是有一点难受的是:这两个API的主要作用是去“持久存储数据”,而并不能做到真正的“传递”。
因为localStorage存储在浏览器当前页面的Application中,去往下一个页面时并不能带过去。
但是我们有ajax。别慌,这里并不是要讲ajax,只是我们通过ajax的get请求可以发现:url可以传递参数并带到另一个页面去解析、使用,而一般不会对页面造成什么影响(xss先不说)
<a href="phoneshow.html?id=0"></a>
然后我们可以在另一个页面通过split解析url,取出参数,如:
function addphonetip(){
//获取当前路径并切割ID
var url = window.location.href;
var phoneid = url.split("?")[1];
//获取当前ID的手机信息字符串
phoneid = phoneid.replace("id=","").trim();
//获取并显示————手机名称
phonename = phones[phoneid].split(" ")[0];
document.getElementById("phonename").innerHTML = phonename.replace(/_/g," ");
//获取并显示————手机价格
Price = phones[phoneid].split(" ")[2];
document.getElementById("Price").innerHTML = Price;
//获取并显示————手机描述
phonenamemini = phones[phoneid].split(" ")[1];
document.getElementById("phonenamemini").innerHTML = phonenamemini;
//获取并显示————手机图片路径
var phonesrc = "./img/"+phonename.replace(/_/g," ")+".png";
var phoneimg = document.getElementById("phoneimg");
phoneimg.src = phonesrc;
}
当然,还有一种方法是去修改外链JS中的【全局变量】。
vue组件间数据传递
vue作为典型的PWA(单页面应用),它依赖“组件”的形式将功能进一步划分、解耦。
vue中使用localStorage就简单很多,在vue-cli中,你可以:
//设置storage
localStorage.xxx="xxx";
//取出storage
localStorage.xxx
vue中组件传值也是要分情况的:
(1)父子组件间传值
所用技术:props
、emit
、on
在笔者的上一个项目中,有下面一段代码:
<city-alphabet :cities="cities" @change="handleChange"></city-alphabet>
//同组件内,js
handleChange(letterr){
this.letterr=letterr
}
//alphabet组件中
export default{
props:{
cities:Object
},
methods:{
handleClick(e){
this.$emit('change',e.target.innerText)
}
}
}
(2)爷孙组件间传值
所用技术:provide
、reject
(这一块用的不多,代码日后笔者遇到合适的即贴过来)
(3)非父子组件间传值
这个有三种解决方案:
- 若是兄弟组件,则可按照(1)所说,先由一个组件传值给父组件,然后再由父组件传给另一个子组件;
- vuex
vuex笔者曾经写过单独博客,这里不再赘述,首先必须记住下面这张图:
- 新建文件,作为Bus总线:
//在components文件夹下创建msg.js
import Vue from 'vue'
export default new Vue
然后,在需要使用的组件中都先引入:import Msg from './msg.js'
余下和(1)一样用$emit
、$on
即可。
react中的数据传递
父组件向子组件传递:props
子组件向父组件传递
- 传递带参的方法
- redux
跨组件传递,解决数据比较深,传递了多层props的问题
context
React.createContext(defaultValue);
兄弟节点间传递数据
redux:
- 同步:
action,reducer,store
store是存储数据的地方:
createStore()用来创建store方法,接受一个回调函数reducer,和一系列中间件
store.subscribe()
注册事件
store.dispatch()
通过发送action,触发事件,发送action后,reducer根据action改变state的值
store.getState()
得到所有的state值
react-redux:
mapStateToProps(state, ownProps) 拿到state,页面刷新
mapDispatchToProps(dispatch, ownProps) 拿到state,等待响应页面操作,触发事件。
connct(mapStateToProps, mapDispatchToProps)(子组件)
- 异步:
redux-thunk
微信小程序中的数据传递
其实笔者在微信小程序中用的最多的就是localStorage了,微信小程序和前面这几个都不同,用localStorage风险小——没几个人会在手机上打开console!
但是微信小程序中明确指出了一种类似vuex的语法规则:
app.js中的global
因为app.js就相当于微信小程序中的“全局容器”,我们完全可以在其中存放一个“读取函数”、一个“修改函数”,以及这两个函数牵扯到的数据变量:
var g_text=null;
App({
getText(){
return g_text;
},
updateText(text){
g_text=text;
}
})
在需要的地方(js文件中)先引入文件:
const app=getApp();
然后便可以在不同场景下调用对应函数,改变/获取位于app.js中的“全局变量”值,在其他文件中同样步骤再获取/修改。
以上所说皆为“在不同页面/组件中传递【私有】数据” —— 这里的“私有”表明了“只是为了增加页面/组件间的联动性,而不能作用于用户之间的联系”,要想达到后者,还就要后台的参与不可,这个笔者后续会带来。