Как динамически изменять дочерние компоненты из родительского в Vue. js - PullRequest
1 голос
/ 18 июня 2020

У меня есть форма, содержащая некоторые пользовательские компоненты, такие как custom-input, custom-button и т.д. c. в моем custom-form компоненте. Мои пользовательские компоненты (кроме custom-form) содержат реквизиты disabled. Я хочу установить для реквизита disabled значение true во всех настраиваемых компонентах при нажатии кнопки отправки.

Мне нужно делать это динамически, и я не знаю, какие настраиваемые компоненты используются в форме. Я также должен упомянуть, что, возможно, у меня есть более одной формы на странице.

Как я могу с этим справиться?

Вот что я пробовал.

--- Main Component ---
<template>
  <div>
    <slot />
  </div>
</template>
<script>
export default {
}
</script>
--- Component1 ---
<template>
  <div>
    <span v-if="!disabled">this is Comp1</span>
  </div>
</template>
<script>
export default {
  props: {
    disabled: {
      type: Boolean,
      default: false
    }
  }
}
</script>
--- Component2 ---
<template>
  <div>
    <span v-if="!disabled">this is Comp2</span>
  </div>
</template>
<script>
export default {
  props: {
    disabled: {
      type: Boolean,
      default: false
    }
  }
}
</script>
--- My directive ---
import Vue from 'vue'

Vue.directive('disable', {
  bind: (el, binding, vnode) => {
    methods.setChildrent(vnode.context.$children, binding.value)
  }
})

const methods = {
  setChildrent(children, value) {
    children.forEach(element => {      
      this.setChildrent(element.$children, value)
      if(element.$options.propsData)
        if ('disabled' in element.$props)
          element.$props.disabled = value
    })
  }
}

--- Page ---
<template>
  <MainComp v-disable="true">
    <Comp1></Comp1>
    <Comp2></Comp2>
  </MainComp>
</template>

<script>
import Comp1 from './Comp1.vue'
import Comp2 from './Comp2.vue'
import MainComp from './MainComp.vue'
import Directives from '../directives/index.js'
export default {
  name: 'HelloWorld',
  components: {
    Comp1,
    Comp2,
    MainComp,
  },
  directives: {
    Directives
  },
  props: {
    msg: String
  },
  methods: {
  },
  mounted() {   
  }
}
</script>

Ответы [ 2 ]

2 голосов
/ 18 июня 2020

Props!

// главный компонент / представление

<template>
    <custom-form />
    <custom-form />
</template>

<script>
import CustomForm from './CustomForm'

export default {
    components: { CustomForm },
    data() {
        return {
            disabled: false
        }
    },
    methods: {
        setDisabled() { 
            this.disabled = true
        }
    }
}
</script>

// CustomForm. vue

<template>
    <form @submit.prevent="submit">
        <custom-element :disabled="disabled" />
        <custom-element :disabled="disabled" />
    </form>
</template>

<script>
    import CustomElement from './CustomElement'

    export default {
        data() { 
            return {
                disabled: true
            }
        },
        props: ['disabled'],
        components: { CustomElement },
        methods: {
            submit() {
                this.disabled = true
            }
        }
    }
</script>

// CustomElement. vue

<template>
    <input :disabled="disabled" />
</template>

<script>
    export default {
        props: ['disabled']
    }
</script>
0 голосов
/ 18 июня 2020

Я решил эту проблему следующим образом. Я не знаю, есть ли случаи, которые могут вызвать проблему или нет, но я провел несколько тестов, и все прошло хорошо.

// Component1

<template>
  <div>
    <span v-if="!disabled">this is Comp1</span>
  </div>
</template>
<script>
export default {
  props: {
    disabled: {
      type: Boolean,
      default: false
    }
  }
}
</script>

// Component2

<template>
  <div>
    <span v-if="!disabled">this is Comp2</span>
  </div>
</template>
<script>
export default {
  props: {
    disabled: {
      type: Boolean,
      default: false
    }
  }
}
</script>

// Главный компонент

<template>
  <div>
    <slot />
  </div>
</template>
<script>
export default {
  props: {
    disabled: {
      type: Boolean,
      default: false
    }
  },
  watch: {
    disabled(val) {
      this.setChildrenStatus(val)
    }
  },
  methods: {    
    setChildrenStatus(status) {      
      this.$slots.default.forEach(item => {
        if (item.componentOptions && item.componentOptions.propsData) {
          item.componentOptions.propsData['disabled'] = status
        }
      })
    }    
  }
}
</script>

// Главная страница

<template>
  <MainComp :disabled="disabled">
    <Comp1></Comp1>
    <Comp2></Comp2>
    <br>
    <button @click="setDisabled">submit</button>    
  </MainComp>
</template>

<script>
import Comp1 from './Comp1.vue'
import Comp2 from './Comp2.vue'
import MainComp from './MainComp.vue'
export default {
  name: 'HelloWorld',
  components: {
    Comp1,
    Comp2,
    MainComp,
  },
  data() {
    return {
      disabled: false
    }
  },
  props: {
    msg: String
  },
  methods: {
    setDisabled() {
      this.disabled = !this.disabled
    }
  }
}
</script>


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...