vue2+element-UI ,新增tab标签页并携带参数的问题

前端成长仔一枚,最近的一个项目中,遇到了一个bug,虽然不是很大,但是足够灵异。借此记录一下。

项目背景:项目首页使用的el-tree和el-tab-pane,没有使用路由,全部在一个根路由下由v-if控制显示。实习小白也不懂为什么这样,但是入乡随俗,我新增页面、tree结构和tab页的时候也用的这种方式。(事实证明,跟着前辈走方便又快捷。之前不信邪,非得用路由跳转,纠结到心脏病发,熬夜到十二点也解决不了问题)。

问题背景:本来欢快的使用v-if控制页面显示足够,但是产品提出新的需求,在A页面中设置按钮,点击按钮的时候可以新增一个tab展示B页面,并且将参数带过去。

解决办法一:不用路使用eventBus,由于A、B页面毫无关系,建立一个bus.js,用$emit传递要携带的参数,新打开的页面使用$on接收。

新建一个eventBus文件,取名为bus.js用于接收数据。

import Vue from "vue"
export default new Vue()

发送数据的组件在methods方法中新增方法:

import bus from "./bus.js"
methods:{
   //发送的是单个数据时:
   sendFormData(){
      bus.$emit("dataName", dataValue)
   }
  //发送的是多个数据时:
   sendFormData(){
      bus.$emit("dataName", dataValue1, dataValue2)
   }
}

接收数据的组件在methods方法中新增方法为:

import bus from "./bus"
methods:{
   recvFormData(){
       //接收单个数据
       bus.$on("dataName",msg=>{
          console.log(msg)
       })
   }
   //接收多个数据:
  在template中的写法为:@recvFormData=recvFormData(arguments)
   recvFormData(values){
       bus.$on("dataName",values=>{
          console.log(values)
       })
   }
}

然鹅,$emit传递的时候,那边新的页面已经在created周期中了,$on接收不到。看过网友的建议后,可以将$emit写在beforeDestroy阶段,好死不死,该需求就是在关闭 B的tab页面还能回到A的tab页面。该方法不行。

解决办法二:使用路由携带参数跳转。直接在根目录下创建新的children。然而,由于element-ui新增标签页给定的代码中写死了tab的content内容部分且是字符串的形式。如下:

methods: {
  addTab(targetName) {
    let newTabName = ++this.tabIndex + '';
    this.editableTabs.push({
    title: 'New Tab',
    name: newTabName,
    content: 'New Tab content'
   });
    this.editableTabsValue = newTabName;
  },
}

 首先,要将content设置为组件的形式,才能将新的页面传递进去。

改写content的方式:

1、引入要展示的组件:

import Admin from "@/components/views/Admin.vue"

2、将addTab方法中的content字段的值改为组件名字:

methods: {
  addTab(targetName) {
    let newTabName = ++this.tabIndex + '';
    this.editableTabs.push({
    title: 'New Tab',
    name: newTabName,
    content:"Admin"
   });
    this.editableTabsValue = newTabName;
  },
}

完成。

也是因为这种方式,当我们的路由从A页面跳转的时候,会展示Admin组件中的内容。为了避免内容的重复,可以将这个组件设为一个空组件。便可解决问题,这是一个投机取巧得方式,更加优化得方式有待学习。

由于解决办法二过于妖娆(繁琐),所以想到了可以用vuex做传值。

解决办法三:使用vuex,将要携带的参数写在state中。在A组件中点击按钮新增tab页面的同时,使用mutations修改state中的值。在module中新建一个js文件并设置命名空间namespaced:true。

(如果项目不大,可以不建模块。)

const state={
   dataName1:"",
   dataName2:"",
}
const mutations={
    changeData1(state,value){
        state.dataName1=value,
    },
    changeData2(state, value){
        state.dataName2=value
    }    
}
const actions={
    //一些异步调用
    funtion1(){
        return new Promise((resolve,reject)=>{...})
    }
}
 
export default{
    namespaced:true,
    state,
    mutations,
    actions
}

在A页面中,引入vuex仓库中的state和mutations,修改state中的值。

import {mapState, mapMutations} form "vuex"
export default{
    comoputed(){
        ...mapState('name',["dataName1", "dataName2"])
    }
    methods:{
        ...mapMutations("name",["changeData1", "changeData2"])
        //具体的业务逻辑代码(也就是点击事件)
        clickFn(){
            this.changeData1(value1)
            this.changeData2(value2)
        }
    }
}

在B页面中,如果B页面只被调用这一次,则可以不引入mutations,在本业务逻辑中,其他地方还需使用B页面,并且相应的参数为默认值,因此我的写法为:

import {mapState, mapMutations} from "vuex"
export default{
    computed(){
        ...mapState("name", ["dataName1","dataName2"])
    }
    mounted(){
        this.localData1 = this.dataName1
        this.localData2 = this.dataName2
    },
    /*由于其他页面会调用该页面,因此在这个页面离开时,要将vuex的值设为空,
    以免其他情况下的数据受到影响*/
    beforeDestroy(){
        this.changeData1("")
        this.changeData2("")
    },
    methods:{
        ...mapMutations("name", ["changeData1", "changeData2"])     
    }
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue2中,可以使用props来实现父组件向子组件传递参数。父组件通过在子组件的标签上绑定属性来传递参数,子组件通过props选项来接收参数。 具体使用方法如下: 1. 在父组件的模板中,使用子组件的标签,并绑定要传递的属性。例如,如果要传递一个名为"message"的属性,可以这样写: ```html <child-component :message="parentMessage"></child-component> ``` 2. 在子组件的选项中,使用props选项声明要接收的属性。例如,可以这样写: ```javascript props: { message: { type: String, // 属性值的类型 required: true // 是否必需 } } ``` 这样就完成了父组件向子组件传递参数的过程。子组件可以通过this.message来访问从父组件传递过来的参数。 总结: - 使用props可以实现父组件向子组件传递参数 - 在父组件中,使用子组件的标签并绑定属性来传递参数 - 在子组件中,使用props选项来声明要接收的属性 - 子组件通过this.propName来访问从父组件传递过来的参数 引用: : Vue 通过on/emit的方式来实现子组件向父组件传参。父组件通过在子组件的标签上绑定属性来传递参数,子组件通过props选项来接收参数。具体使用方法如下:在父组件的模板中,使用子组件的标签,并绑定要传递的属性。在子组件的选项中,使用props选项声明要接收的属性。这样就完成了父组件向子组件传递参数的过程。子组件可以通过this.propName来访问从父组件传递过来的参数。 : Vue2组件传参· props/emit传参使用介绍使用场景使用方法父组件向子组件传参子组件向父组件传参使用总结 $parent/ $children传参引用父组件引用子组件,使用$children 和 $refsbus使用方法使用总结 provide/inject传参使用介绍使用方法使用总结 : 最常见的父子组件通信方式 props支持参数验证 emit只会触发父组件的监听事件 不适合多层次组件参数传递,需要逐层传递参数 $parent/ $children传参 引用父组件

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值