有很多不同的方法可以解决这个问题。我怀疑这将是一个详尽的列表,但我可以给出一些可能性。
1。全局存储值
这里明显的选择是 Vuex 商店。只需将相关数据放入 store 中,组件就可以获取所需的内容。
但是,全局商店不一定是 Vuex。如果您没有其他理由引入 Vuex,那么您可能更喜欢更临时的东西。
存储的另一种方法是将数据保存在$root,官方文档中描述了这种方法:
https://vuejs.org/v2/guide/state-management.html#Simple-State-Management-from-Scratch
另一种选择是拥有一个可以将数据保存为单例的.js 文件。有多种方法可以做到这一点,但最简单的形式可能是这样的:
export default {
myData: null
}
然后您将 import 该对象并根据需要读取/写入 myData 的值。它不一定是反应式的,但我假设初始值将在开始时设置,在创建应用程序之前,并且在那之后不会改变。
2。将值存储在 Vue 原型中
这与上述非常相似,但我认为值得单独提及。它看起来像这样:
Vue.prototype.$myComponentData = 'someValue'
然后在任何组件中,您都可以通过属性$myComponentData 访问该值。
文档:https://vuejs.org/v2/cookbook/adding-instance-properties.html
3。提供/注入
provide/inject 机制是鲜为人知的 Vue 功能之一,但它提供了使用 props 将数据向下传递给子组件的替代方法。它有各种优点和缺点,通常你会尝试使用道具。
https://vuejs.org/v2/api/#provide-inject
简而言之,它允许组件为其所有后代提供命名值,而无需单独显式地将其传递给每个后代。然后后代组件可以选择他们想要注入的命名属性。
您将无法使用 provide/inject 将不同的值传递给后代组件,但在您的情况下,值是相同的,所以它应该可以工作。
如果您认为这种方法可能适合您,那么我建议您进一步阅读:
https://blog.logrocket.com/how-to-make-provide-inject-reactive/
4。重构以删除重复
虽然这不太可能是您采用的解决方案,但我认为值得一提。
这个问题的起始前提似乎是明确传递道具是一种重复形式。额外的噪音和额外的努力可能会犯错误。
有可能我们可以在传递道具的同时删除该重复项。这里的关键是重构模板,使子组件仅具有一次功能。
显然,这需要在一个循环中,以便我们仍然可以获得所有所需的组件。该循环需要一个合适的数据结构来驱动它,以便创建所有正确的组件。
我假设问题中的模板是简化的。如果您确实连续有多个实例,那么重构为使用 v-for 应该非常简单。如果(看起来更有可能)组件嵌套在布局中的不同位置,那么尝试将其编码到数据结构中以避免一些模板重复可能会变得笨拙。
希望这个想法很清楚,但如果不是,您可以阅读一下:
https://michaelnthiessen.com/reducing-redundant-repetition
5。动态组件
这就是问题中提到的。有多种方法可以做到这一点,但这个想法的核心是我们在运行时更改我们的组件定义。这并不一定意味着创建一个新组件,它同样可能意味着在现有组件定义中加入一些东西。我们已经看到了这个想法的变体,使用前面提到的Vue.prototype 方法。
理论上它可以通过 prop 的 default 值来完成,但似乎没有必要使用 prop,除非在某些情况下以通常的方式从外部设置该 prop。
我们可以使用data 将其设置为属性,但我个人很想使用Vue.prototype 技巧的变体将属性添加到组件自己的原型中:
MyComponent = Vue.extend({
template: `<div>{{ value }}</div>`
})
MyComponent.prototype.value = 'some value'
new Vue({
el: '#app',
components: {
MyComponent
}
})
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
<div id="app">
<my-component></my-component>
</div>
从性能角度来看,使用原型相对便宜。反应性存在潜在问题,但它们仅适用于值可以更改的情况,而在这种情况下则不能。
只是为了明确说明prop 和data 方法:
MyComponent = {
template: `<div>{{ value }}</div>`
}
PreConfiguredComponent = Vue.extend({
extends: MyComponent,
props: {
value: {
default: 'some prop value'
}
}
})
new Vue({
el: '#app',
components: {
MyComponent: PreConfiguredComponent
}
})
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
<div id="app">
<my-component></my-component>
</div>
和:
MyComponent = {
template: `<div>{{ value }}</div>`
}
PreConfiguredComponent = Vue.extend({
extends: MyComponent,
data () {
return {
value: 'some data value'
}
}
})
new Vue({
el: '#app',
components: {
MyComponent: PreConfiguredComponent
}
})
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
<div id="app">
<my-component></my-component>
</div>
您同样可以尝试直接调整导入的 MyComponent 而不是扩展它。