代码之家  ›  专栏  ›  技术社区  ›  Freddy Muskelberg

为所有实例设置组件属性/向所有组件实例传递相同的数据

  •  0
  • Freddy Muskelberg  · 技术社区  · 5 年前

    我有一个组件,其中每个实例都需要一些数据被传递给它,该组件被多次使用,并且该组件的所有实例都应该接收相同的数据/属性。

    <my-component :someProp="someValue"></my-component>
    <my-component :someProp="someValue"></my-component>
    <my-component :someProp="someValue"></my-component>
    <!-- ...and lots more... -->
    

    这是我目前的方法:

    我怎么能填充我的一些多余的实例? 我试过了Vue.扩展()但无法确定它期望的语法,该部分的文档不够清晰。 这就是我想象中的工作原理:

    // App.vue
    import MyComponent from './components/MyComponent'
    
    const PreConfiguredComponent = Vue.extend(MyComponent, {
      props: {
        someProp: "someValue"
      }
    })
    
    export default {
      name: 'app',
      data: () => ({}),
      components: {
        MyComponent: PreConfiguredComponent
      }
    }
    

    你明白了吧,我不知道怎么表达得更好。不需要使用道具,但我不知道其他传递数据的方法。

    0 回复  |  直到 5 年前
        1
  •  2
  •   skirtle    5 年前

    有很多不同的方法来处理这个问题。我怀疑这是否会像一个详尽的清单,但我可以给一些可能性的感觉。

    1全局存储值

    但是,全球商店不一定是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

    三。提供/注入

    这个 provide / inject mechanism是一个鲜为人知的Vue特性,但它提供了一种替代方法,可以使用props将数据向下传递到子组件。它有各种利弊,通常你会尝试使用道具。

    https://vuejs.org/v2/api/#provide-inject

    简而言之,它允许组件向其所有子代提供一个命名值,而无需将其显式地分别传递给每个子代。然后,子组件可以选择要注入的命名属性。

    提供 / 注入 将不同的值传递给子代组件,但在您的情况下,值是相同的,因此它应该可以工作。

    如果您认为这种方法适合您,那么我建议您进一步阅读:

    https://blog.logrocket.com/how-to-make-provide-inject-reactive/

    虽然这不太可能是你的解决方案,但我认为值得一提。

    这个问题的出发点似乎是明确地传递道具是一种重复的形式。有可能犯错的额外噪音和额外的努力。

    我们可以在传递道具的同时移除重复。这里的关键是重构模板,使子组件只具有一次功能。

    显然,这需要在一个循环中,这样我们仍然可以得到所有想要的组件。这个循环需要一个合适的数据结构来驱动它,以便创建所有正确的组件。

    我假设问题中的模板是一个简化。如果您确实连续地有几个实例,那么重构以使用 v-for 应该是微不足道的。如果组件被嵌套在布局中的不同位置,那么仅仅为了避免模板重复而在数据结构中编码可能会很麻烦。

    https://michaelnthiessen.com/reducing-redundant-repetition

    5动态组件

    这就是问题中所暗指的。我们的核心思想是改变组件的定义。这并不一定意味着要创建一个新的组件,它同样可以意味着在现有组件定义中插入一些东西。我们已经看到了这个想法的变化 Vue.prototype 前面提到的方法。

    理论上可以用 default 道具的价值,但似乎没有必要使用道具,除非道具将以通常的方式从外部设置。

    我们可以用 data 但就我个人而言,我会倾向于使用 Vue.原型

    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 数据

    MyComponent = {
      template: `<div>{{ value }}</div>`
    }
    
    PreConfiguredComponent = Vue.extend({
      extends: MyComponent,
    
      props: {
        value: {
          default: 'some prop value'
        }
      }
    })
    
    new Vue({
      el: '#app',
    
      components: {
        MyComponent: PreConfiguredComponent
      }
    })
    <脚本src=“https://unpkg.com/vue@2.6.10/dist/vue.js“></script>
    
    <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
      }
    })
    <脚本src=“https://unpkg.com/vue@2.6.10/dist/vue.js“></script>
    
    <div id=“app”>
    <my component></my component>
    </div>

    你同样可以尝试调整导入的 MyComponent 直接而不是延伸。