Reputation: 1694
I have a form that contains some custom components like custom-input
, custom-button
, etc. in my custom-form
component. My custom components (except custom-form
) contain a disabled
props. I want to set the disabled
props to true in all custom components when a submit button is clicked.
I need to do that dynamically and I don't know which custom components are used in a form. I also need to mention that, It is possible that I have more than one form on a page.
How can I handle that?
Here is what I've tried.
--- 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>
Upvotes: 4
Views: 3366
Reputation: 1694
I solved this issue by the below approach. I don't know if there are any cases that may cause a problem or not but I did some tests and it was fine.
//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>
//MainComponent
<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>
//Mainpage
<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>
Upvotes: 1
Reputation: 4252
Props!
// main component / view
<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>
Upvotes: 4