【问题标题】:Vuejs how to pass data from main.js to App.vue with propsVuejs如何使用props将数据从main.js传递到App.vue
【发布时间】:2019-03-08 00:35:04
【问题描述】:

我遇到了一个问题,即 App 组件和 HelloWorld 组件没有从 main.js 获取传递的数据。这在 Vue 中应该是一件相当简单的事情。

您可以在图像中看到根元素的计数器定义为 10,它只是没有被填充到任何子组件中。几乎就像 main.js 中的第 12 行没有任何效果一样。如果我单击并显示“计数器:未定义”。我究竟做错了什么?几个小时以来,我一直在用头撞墙。

这是我的 main.js

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({

  components: {App},
  data: {
    counter: 10
  },
  template: '<App :counter="counter" />',
  //computed: {
  //  counterInc: function () {
  //    return this.counter++
  //  }
  //},
  methods: {
    updateCounter (x) {
      this.counter = x
    }
  },

  render: h => h(App)
}).$mount('#app')

这是我的 App.vue

<template>
  <div id="app">
    <img alt="logo" src="./assets/logo.png">
    <HelloWorld msg="Our Message" :counter="counter"/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'app',
  props: ['counter'] ,
  components: {
    HelloWorld
  },
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

这是我的 helloworld.vue

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>
      Here lies all of our operations for automating some strenuous tasks. <br>
    </p>
    <h3>Get Started {{ counter }}</h3>
    <ul>
    <li><a v-on:click="updateCounter()" class="generateRollup">Generate Purchase Price</a></li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String,
    counter: String,
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #0093D0;
}
.generateRollup:hover {
  cursor: pointer;
}
</style>

【问题讨论】:

  • 确定这段代码不会产生错误?
  • 是的 100% 确定,我正在查看 chrome 控制台并没有看到任何错误,'"vue-cli-service serve' 也没有返回错误。

标签: javascript vue.js


【解决方案1】:

所以我个人不怎么使用render 函数,但是你可以做的是让你的代码工作是在实际的 html 页面中提供初始模板并将 Vue 实例挂载到它。我在这里做了一个codepen:https://codepen.io/crustyjew/pen/jeWPgY

要点是删除你的render函数,在html中添加以下内容

<div id="app">
  <app :counter="counter" />
</div>

留下.$mount('#app') 将其挂载到您提供的html。

【讨论】:

  • 看起来我无法删除渲染功能,因为我在删除它时收到警告。 - [Vue 警告]:您正在使用仅运行时构建的 Vue,其中模板编译器不可用。要么将模板预编译为渲染函数,要么使用编译器包含的构建。
  • 由于我无法删除渲染,所以我进行了一些研究,并在根目录中创建了一个包含 // vue.config.js module.exports = { configureWebpack: { resolve: { alias: { 'vue$': 'vue/dist/vue.esm.js' } } } } 内容的 vue.config.js 并删除了 render: 行并应用了您的编辑。它现在完美无缺。使用包含编译器的编译器与我使用它的方式有什么注意事项?
  • 我认为他们在官方文档站点上有所不同,但基本上我的理解是带有模板编译器的那个有点“重”而没有的可以是如果您自己编译所有模板,则用作更轻的版本,这在某些 CORS 和内容安全情况下可能会有所帮助。
【解决方案2】:

Matti 已经为您提供了答案,但您可能需要考虑一下您的项目结构。将数据从根组件传递到最低的子组件不应该是目标。 在您的情况下,您有两种选择:

  1. 使用事件从您的组件发出事件以更新另一个组件中的状态。请参阅https://vuejs.org/v2/guide/components-custom-events.html 了解更多信息。
  2. 使用像 vuex 这样的状态管理。 Vuex 用于全局处理你的状态。您可以使用来自所有组件的 getter 访问状态,而无需手动将数据传递给需要访问数据的每个组件。此外,vuex 提供了动作/突变,允许您更新状态。如需更多信息,请参阅https://vuex.vuejs.org/

对于小型项目,vuex 可能需要太多开销才能获得相同的结果。但是,如果您的项目变得越来越大,那么在通过多个组件传递数据时,真的很难知道组件中发生了什么。

【讨论】:

  • “将数据从根组件传递到最低的子组件不应该是目标。” 为什么我不应该有这样做的目标?我在 main.js 中发生了需要传播给孩子的事情。你是说孩子不应该知道他们的父母和父母的数据吗?我会研究vuex。谢谢!
  • 是的,组件应该只对自己负责。除非你有类似的东西,例如。一个 ListComponent 和一个 ItemComponent,那么就可以像提到的那样传递你的道具。但是,如果变得更复杂,例如将道具传递给各种组件并且深入,通常最好使用事件或 vuex。希望现在更清楚了。
【解决方案3】:

如果你不想使用包含模板编译器的 vue 构建,那么你可以像这样实现 render 函数来传递 prop 值:

render: h => h(App, {
  props: {
    'counter': 10
  }
})

(来源:https://vuejs.org/v2/guide/render-function.html#createElement-Arguments - render 函数的 h 参数是 createElement 的别名。)

【讨论】:

    猜你喜欢
    • 2019-03-22
    • 2021-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 2019-09-20
    • 2018-01-15
    相关资源
    最近更新 更多