vue有没有类似冻结组件的功能?

发布于 2022-09-12 02:23:36 字数 4540 浏览 21 评论 0

比如我暂时冻结组件A,那么冻结期间组件A的一切活动都暂停(比如双向绑定或者其他事件),其他组件不影响,一段时间后还可以解冻。

因为现在有个需求,有两个dialog里有两个组件绑定了同一个变量X,但组件A接收的是String类型,组件B接收的是Array类型,我已经实现弹出组件B的时候将变量X初始值改为[],关闭组件B时再将X初始值改回""。但现在我打开组件B的时候A组件的绑定值也变成[]了导致控制台报错了。

现在想问有没有类似冻结组件的方法,在B弹出时将A组件冻结,不会触发双向绑定事件?


更新一下需求:

我有一个通用的Form组件,每个Form组件里又有很多输入组件,这些组件绑定的变量放在vuex里。现在我把Form组件放到Dialog里,一个页面可能会存在多个Form组件,我现在根据FormId在vuex里划分区域,但又不想每次都传formId去获取和更新。于是我在vuex里定义个变量activeFormId用于存放当前活动的fromId,打开一个dialog就push一个formId,关闭dialog就pop他的formId。然后在vuex里就能根据activeFormId顶层元素知道当前最顶层的formId,从而响应数据获取和更新。这样外层组件就不需要每次获取和更新vuex数据都要传formId了。
但现在就碰到了上边的问题,如果两个form里有相同的变量名,但变量类型又不同就会报错。

  • 如果两个变量都是输入框(接收值都是String)是没有问题的。

GIF.gif

  • 但如果一个是输入框(接收值String),一个是多选框(接收值Array)就会报错

附上完整测试代码

  • store/index.js

const state={

  testVariable:{
    default:{

    },

  },
  activeFormId:['default'],

};
const getters = {
    getTestVariable(state){
      let key=state.activeFormId[state.activeFormId.length-1];
      return state.testVariable[key];
    },
    getActiveFormId(state){
      return state.activeFormId[state.activeFormId.length-1];
    }
};

 const mutations = {
    setTestVariable(state,value){
      let key=state.activeFormId[state.activeFormId.length-1];
      console.log('setTestVariable,key=',key);
      let newObj=JSON.parse(JSON.stringify(state.testVariable));
      newObj[key]=value;
      state.testVariable=newObj;
    },
    activeFormidPush(state,value){
      state.activeFormId.push(value);
    },
    activeFormidPop(state,value){
      state.activeFormId.pop(value);
    }

};

  const actions = {
   setTestVariableAction(context,value){
     context.commit('setTestVariable',value);
   },
   activeFormidPushAction(context,value){
     context.commit('activeFormidPush',value);
   },
   activeFormidPopAction(context,value){
     context.commit('activeFormidPop',value);
   }
};
const store=new Vuex.Store({
  state,
  getters,
  mutations,
  actions
});
export  default store;
  • TestForm.vue
<template>
  <div>
    variable:<span>{{$store.state.testVariable}}</span>
    <br>
    activeFormid:{{$store.state.activeFormId}}
    <br><br><br><br><br>
    <el-dialog
      title="form2"
      style="margin-top: 200px;"
      append-to-body
      :visible.sync="form2Show"
      @close="form1Close"
      width="50%">
      <span>我是form2</span>
      <!--<el-input v-model="value2"></el-input>-->
       <el-checkbox-group v-model="value2">
        <el-checkbox label="复选框 A"></el-checkbox>
        <el-checkbox label="复选框 B"></el-checkbox>
        <el-checkbox label="复选框 C"></el-checkbox>>
      </el-checkbox-group>
    </el-dialog>
    <el-dialog
      title="form1"
      append-to-body
      :visible.sync="form1Show"
      @close="form2Close"
      width="50%">
      <span>我是form1</span>
      <el-input v-model="value1"></el-input>
      <el-button @click.native="openForm2">打开form2</el-button>
    </el-dialog>
    <el-button @click.native="openForm1">打开form1</el-button>
  </div>
</template>
<script>
  export default{
    data(){
      return {
        form1Show:false,
        form2Show:false
      }
    },
    mounted(){

    },
    computed:{
      value1:{
        get(){
          let obj=this.$store.getters.getTestVariable;
          return obj&&obj.inputval;
        },
        set(val){
          this.$store.dispatch('setTestVariableAction',{inputval:val});
        }
      },
      value2:{
        get(){
          let obj=this.$store.getters.getTestVariable;
          return obj&&obj.inputval;
        },
        set(val){
          console.log('val=',val);
          this.$store.dispatch('setTestVariableAction',{inputval:val});
        }
      }
    },
    methods:{
      openForm1(){
        this.$store.dispatch('activeFormidPushAction','1');
        this.form1Show=true;
      },
      openForm2(){
        this.$store.dispatch('activeFormidPushAction','2');
        this.form2Show=true;
      },
      form1Close(){
        this.$store.dispatch('activeFormidPopAction','1');
      },
      form2Close(){
        this.$store.dispatch('activeFormidPopAction','2');
      }
    }
  }
</script>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

ぃ弥猫深巷。 2022-09-19 02:23:36
  1. 你要想明白,框架不会照顾每个人的想法,所以只能使用者适应框架,不能指望自己的每个想法都能找到答案
  2. 据我所知 Vue 没有所谓的“冻结”功能
  3. 你这个需求可以用 v-if 根据变量类型适当释放组件,也可以用 computed 来返回不同的数据给不同的组件
鹿港巷口少年归 2022-09-19 02:23:36

这里问题难道不是因为数据被共享了吗?

深拷贝切断引用。

庆幸我还是我 2022-09-19 02:23:36

你只要保证为string类型的时候渲染A不渲染B,为array类型时渲染B不渲染A不就好了,因为我不清楚你的具体业务逻辑,提供一个思路,通过v-if来判断,A:v-if="typeof value === 'string'",B:v-if="Array.isArray(value)" ( ﹁ ﹁ )当然这个比较简单粗暴

还有你为什么不定义两个变量呢。。。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文