一、url传值
- 页面跳转或打开新页面url传值
// 在a页面跳转或打开b页面中通过"?"拼接的方式传参
// 问号后的参数尽量以对象的形式,方便扩展
// 传参之前将参数转换为JSON字符串
// 为了防止url中有中文或者其它字符造成不可预期的错误,使用encodeURI和decodeURI对url进行编码
var params = {
id:'123',
name:'xiaowang'
}
window.location.href = encodeURI("http://localhost:8080/index.html?" + JSON.stringify(params))
// 在b页面中获取参数
var getUrlParams = function () {
var _url = window.location.href;
// 问号的位置
var _questionPlace = _url.indexOf('\?');
var _data = false;
if (_questionPlace != -1) {
// 截取字符串
_data = _url.substr(_questionPlace + 1);
// 对字符串进行解密
_data = decodeURIComponent(_data);
//获取数据对象
_data = JSON.parse(_data);
}
return _data;
},
var _params = fdGlobal.getUrlParams(); // _params = {id:'123',name:'xiaowang'}
- 注意不同浏览器url传递参数的长度限制
- IE浏览器对URL的长度现限制为2048字节
- 360极速浏览器对URL的长度限制为2118字节
- Firefox(Browser)对URL的长度限制为65536字节
- Safari(Browser)对URL的长度限制为80000字节
- Opera(Browser)对URL的长度限制为190000字节
- Google(chrome)对URL的长度限制为8182字节
二、iframe之间的动态传值方法postMessage
通过iframe打开弹窗的时候,往往会遇到在parent.html中进行了操作,操作完成后需要iframe嵌套的child.html进行数据请求更新页面。如在iframe弹窗中进行了新增操作,提交成功后需要父页面刷新列表,这时候常常需要使用到postMessage
// parent初始化js的时候监听message事件
window.onmessage = function (data) {
var _data = JSON.parse(data.data); // _data = {id:'123',name:'xiaowang'}
}
// child.html提交成功后发送消息,触发父页面的message事件
var params = {
id:'123',
name:'xiaowang'
}
parent.postMessage(JSON.stringify(params),'*');
// 有时候我们的列表页并不是父页面,而是和弹窗同级的顶层窗口下的iframe页面,不管是什么情况,我们只需要找到需要传递消息的window就可以了,例如有时候可能是
$(top.document).find("#jsIndexFrame")[0].contentWindow.postMessage(JSON.stringify(_params),'*');
三、 新开浏览器窗口传参
有时候我们新增或编辑页比较复杂,当前页面弹窗不太方便操作,需要新开窗口,此时postMessage不可用,此时可以通过localStorage作为媒介,监听localStorage变化
// b页面为新开窗口,打开时进行localStorage的监听
window.addEventListener('storage', function (e) {
console.log(e)
// 对象e会返回改变的storage的key,newValue和oldValue,可用作操作判断
if(e.key==='type' && e.newValue==='02'){
// type发生改变,为a页面传递改变信息,执行操作
}
// 操作完成后重置type,方便下次信息传递
window.localStorage.setItem('type','01')
})
// a页面中进行打开窗口和消息传递
<span onclick="openA()">打开</span>
<span onclick="setStorage()">更新</span>
<script>
localStorage.setItem('type','01');
var openA = function(){
window.open("./b.html")
}
var setStorage = function(){
localStorage.setItem('type','02')
}
</script>
四、vue中常用传值方法
- props/$emit
- 父组件通过props向子组件传值,组件中的数据共有三种形式:data、props、computed
- 子组件向父组件传值,通过事件形式,子组件通过$emit给父组件发送消息
// com1组件中
this.$emit('事件名','参数')
// 使用组件的父页面中
<com1 @事件名='func'><com1>
-
$
emit /$
on
即eventBus方法,这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级
var Event = new Vue();
Event.$
emit(事件名,数据);
Event.$
on(事件名,data => {});
Event.$
on使用过后离开页面时要使用Event.$
off 解除监听,否则监听会一直存在,新页面重新监听未解绑的相同事件,事件触发会叠加 $
attrs/$
listeners
- attrs,包含了父作用域中不被 prop 所识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件。通常配合 interitAttrs 选项一起使用
// index.vue
<template>
<div>
<h2>pxf</h2>
<child-com1
:foo="foo"
:boo="boo"
:coo="coo"
:doo="doo"
title="前端"
></child-com1>
</div>
</template>
<script>
const childCom1 = () => import("./childCom1.vue");
export default {
components: { childCom1 },
data() {
return {
foo: "Javascript",
boo: "Html",
coo: "CSS",
doo: "Vue"
};
}
};
</script>
// childCom1.vue
<template class="border">
<div>
<p>foo: {{ foo }}</p>
<p>childCom1的$attrs: {{ $attrs }}</p>
<child-com2 v-bind="$attrs"></child-com2>
</div>
</template>
<script>
const childCom2 = () => import("./childCom2.vue");
export default {
components: {
childCom2
},
inheritAttrs: false, // 可以关闭自动挂载到组件根元素上的没有在props声明的属性
props: {
foo: String // foo作为props属性绑定
},
created() {
console.log(this.$attrs); // { "boo": "Html", "coo": "CSS", "doo": "Vue", "title": "前端" }
}
};
</script>
// childCom2.vue
<template>
<div class="border">
<p>boo: {{ boo }}</p>
<p>childCom2: {{ $attrs }}</p>
</div>
</template>
<script>
export default {
inheritAttrs: false,
props: {
boo: String
},
created() {
console.log(this.$attrs); // {"coo": "CSS", "doo": "Vue", "title": "前端" }
}
};
</script>
- listeners和$attrs类似,它存放的是父组件中绑定的非原生事件
- provide/inject
用于祖先组件向其所有子孙后代组件进行传值
// A.vue
export default {
provide: {
name: 'pxf'
}
}
// B.vue
export default {
inject: ['name'],
mounted () {
console.log(this.name); // pxf
}
}
这种方式是非响应式的,A改变,B并不会改变,若要变为响应式
//方法一
provide() {
return {
theme: this//提供祖先组件的实例
};
},
//方法二,2.6后支持
provide() {
this.theme = Vue.observable({
color: "blue"
});
return {
theme: this.theme
};
}
- $parent/ $children与 ref
直接得到组件实例,使用后可以直接调用组件的方法或访问数据 - 插槽传值(作用域插槽)
// component-demo-01组件中
data:{
user:{firstName:'aaa',lastName:'bbb'}
}
<span>
<slot v-bind:user="user">
{{ user.lastName }}
</slot>
</span>
// 通过作用域插槽父组件可以访问子组件的值
<component-demo-01>
<template v-slot:default="slotProps">
{{slotProps.user.firstName}}
</template>
</component-demo-01>
vueX(使用详情可参考官方文档)