动态组件 加 组件传值 解决业务问题。
小白又来了,因为小白又遇到问题了。
问题描述
这次小白遇到的问题是项目中和业务相关的问题,在一个列表的详情操作项中,原定的设计是用一个dialog弹出框来显示内容详情。但是甲方“爸爸”说了,这样总体感觉有点小。希望能够以页面的形式显示内容详情。经过小白的深思熟虑之后,决定还是用动态组件解决问题。
解决方案:
首先要先创建一个子组件。
<template>
<div>
<p>子组件</p>
</div>
</template>
<script>
export default {
methods: {
// 子组件中的方法
childMethod() {
console.log('这是子组件的方法');
}
}
};
</script>
第二部,在父组件中引入子组件,并且通过ref来获取子组件实例。
<template>
<div>
<!-- 将ref绑定到子组件 -->
<child-component ref="childRef"></child-component>
<button @click="callChildMethod">调用子组件方法</button>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
methods: {
// 在父组件中定义方法,通过ref调用子组件的方法
callChildMethod() {
// this.$refs.childRef 是子组件的实例
this.$refs.childRef.childMethod();
}
}
};
</script>
这样一个简单的动态组件就可以实现啦。
不过小白遇到的问题,比这个要稍微复杂一点。
因为业务中的详情页面需要一个布尔值来控制这个动态组件的显示或隐藏。并且这个布尔值需要在两个组件中同时使用。这里就有涉及到了组件间传值的问题。
vue中常用的组件间传值方法:
1.Props(父传子):
在父组件中通过props属性传递数据给子组件。
子组件通过props接收父组件传递的数据。
<!-- ParentComponent.vue -->
<template>
<ChildComponent :message="parentMessage" />
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
data() {
return {
parentMessage: 'Hello from parent!'
};
},
components: {
ChildComponent
}
};
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
props: {
message: String
}
};
</script>
2 $emit 和 自定义事件(子传父):
子组件通过$emit触发一个自定义事件,将数据传递给父组件。
父组件通过在子组件上监听这个事件,并在相应的方法中处理传递的数据。
<!-- ParentComponent.vue -->
<template>
<div>
<ChildComponent @customEvent="handleCustomEvent" />
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
methods: {
handleCustomEvent(data) {
console.log('Received data from child:', data);
}
},
components: {
ChildComponent
}
};
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<button @click="triggerCustomEvent">Send Data to Parent</button>
</div>
</template>
<script>
export default {
methods: {
triggerCustomEvent() {
// 通过 $emit 触发自定义事件,并传递数据给父组件
this.$emit('customEvent', 'Data from child');
}
}
};
</script>
3 Vuex(全局状态管理):
使用Vuex来管理应用的全局状态,可以实现任意两个组件之间的数据共享。
// store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
sharedData: 'Hello from Vuex!'
},
mutations: {
updateSharedData(state, newData) {
state.sharedData = newData;
}
},
actions: {
updateSharedData(context, newData) {
context.commit('updateSharedData', newData);
}
},
getters: {
getSharedData: state => state.sharedData
}
});
在.vue文件中
<!-- ParentComponent.vue -->
<template>
<div>
<p>{{ sharedData }}</p>
<ChildComponent />
</div>
</template>
<script>
import { mapState } from 'vuex';
export default {
computed: {
...mapState(['sharedData'])
}
};
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<button @click="updateSharedData">Update Shared Data</button>
</div>
</template>
<script>
import { mapActions } from 'vuex';
export default {
methods: {
...mapActions(['updateSharedData']),
updateSharedData() {
// 通过 Vuex 的 action 更新全局状态
this.updateSharedData('New data from child');
}
}
};
</script>
4 Provide / Inject:
使用provide和inject选项来在父组件中提供数据,然后在子组件中注入这些数据。
这使得父组件的数据在整个组件树中可用,而无需通过props一层层传递。
<!-- ParentComponent.vue -->
<template>
<div>
<p>{{ sharedData }}</p>
<ChildComponent />
</div>
</template>
<script>
export default {
provide() {
return {
sharedData: 'Hello from Provide/Inject!'
};
}
};
</script>
<!-- ChildComponent.vue -->
<template>
<div>
<p>{{ injectedData }}</p>
</div>
</template>
<script>
export default {
inject: ['sharedData'],
computed: {
injectedData() {
return this.sharedData;
}
}
};
</script>
这里小白使用的是$emit的方式将子组件的值传递给父组件,并且在父组件中使用。
在子组件中
goBack() {
this.isDetails = false;
this.$emit('goBack',this.isDetails);
},
在父组件中
第一步引入子组件
import Detail1 from '@/views/UserRightsManagement/DictionaryDetail/Detail1.vue'
第二步调用子组件
<Detail1 ref="d1" v-show="isDetails" @goBack="ChildValue"></Detail1>
第三步接受值
ChildValue(value) {
this.isDetails = value;
},
这样这个布尔值就可以在这两个组件中随意使用啦!