一、url传值

  1. 页面跳转或打开新页面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'}
  1. 注意不同浏览器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中常用传值方法

  1. props/$emit
  • 父组件通过props向子组件传值,组件中的数据共有三种形式:data、props、computed
  • 子组件向父组件传值,通过事件形式,子组件通过$emit给父组件发送消息
// com1组件中
        this.$emit('事件名','参数')
        
        // 使用组件的父页面中
        <com1 @事件名='func'><com1>
  1. $emit / $on
    即eventBus方法,这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级
    var Event = new Vue();
    Event.$emit(事件名,数据);
    Event.$on(事件名,data => {});
    Event.$on使用过后离开页面时要使用Event.$off 解除监听,否则监听会一直存在,新页面重新监听未解绑的相同事件,事件触发会叠加
  2. $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类似,它存放的是父组件中绑定的非原生事件
  1. 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
           };
       }
  1. $parent/ $children与 ref
    直接得到组件实例,使用后可以直接调用组件的方法或访问数据
  2. 插槽传值(作用域插槽)
// 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(使用详情可参考官方文档)