如何使用单个文件组件传递道具?

时间:2016-10-24 22:24:07

标签: javascript vue.js

来自React的Vue。在大多数情况下有很多相似之处,但通过props似乎有点不同。我无法找到有关如何使用单个文件组件执行此操作的大量文档。我在main.js导入了应用的所有数据。我想知道如何将currentUser等部分数据提供给ResourceInfo.vue?再假设这些都是单个文件组件。我是否需要将其传递到<App/>模板选项下的main.js部分,然后传递到<resource-info></resource-info>中的App.vue,然后以某种方式传递到ResourceInfo.vue?我也不想学习Vuex,因为我刚刚开始学习。谢谢!

main.js

import Vue from 'vue'
import App from './App'
import ResourceInfo from '../src/components/ResourceInfo'
var db = firebase.database();
var auth = firebase.auth();

/* eslint-disable no-new */
var vm = new Vue({
  el: '#app',
  data: function() {
    return {
        users: {},
        currentUser: {},
        quizzes: {},
        resources: []
    }
  },
  template: '<App/>',
  components: { App, ResourceInfo },
})

App.vue

<template>
  <div id="app">
    <navbar></navbar>
    <resource-info></resource-info>
  </div>
</template>

<script>
import Navbar from './components/Navbar'
import ResourceInfo from './components/ResourceInfo'

export default {
  name: 'app',
  components: {
    Navbar,
    ResourceInfo
  }
}
</script>

<style>
</style>

ResourceInfo.vue

<template>
</template>

<script>
var resourcesRef = firebase.database().ref('resources');

module.exports = {
  name: 'resource-info',
  data: function() {
    return {
      header: 'Before you build your quiz we just need some quick info.',
      resource: {
        type: '',
        title: '',
        url: '',
        desc: '',
        timesPassed: 0
      },
    }
  },
  firebase: {
    resources: resourcesRef
  },
  methods: {
    saveToFirebase: function() {
      resources.push({
        resource: this.resource
      })

      // Clear inputs  

      this.resource.title = '',
      this.resource.type = '',
      this.resource.desc = '',
      this.resource.url = ''

      console.log("Saving resource data...")

    }
  }
}
</script>

<style>
</style>

2 个答案:

答案 0 :(得分:7)

@DanM。已经提供了答案,我希望你能按照他的指导设法修复你的props

我正在写这个答案,所以我可以在我的应用程序中分享我处理currentUser的方法(仅限登录用户)。这是我的项目结构(这个答案高度简化):

模板:webpack,使用vue init webpack my-project

使用vue-cli安装

我的应用文件:

  • ./ main.js :app条目文件
  • ./ App.vue :使用router-view负责页面布局,例如页眉,页脚和路径内容
  • ./ components / :常用组件,如导航栏,页脚等。
  • ./ routes / :路由组件。我更喜欢把它放在这里而不是混乱我的组件文件夹。
  • 还有更多......

我的main.js中的代码:只是用于定义路由和引导应用程序的标准代码。这里没什么特别的。

App.vue中的代码 - 这里是获取currentUser的地方。我也会插入导航栏,通过currentUser

传递props
<template>
    <div class="app-container">
        <app-navbar :currentUser="currentUserInfo"></app-navbar>
        <router-view></router-view>
        <app-footer></app-footer>
    </div>
</template>
<script>
import AppNavbar from "./components/app-navbar.vue"
import AppFooter from "./components/app-footer.vue"

export default {
    components: {
        "app-navbar": AppNavbar
    },
    data: function() {
        return {
            currentUserInfo: {
                loading: true
            } // start with an empty object and modify later
        }
    },
    // ... all other code ...
    created: function() {
        // Ensure that this is a logged-in user. Or else redirect to login page
        this.$http.get("/api/currentUser").then(response => {
            // process response
            this.currentUserInfo = response
            this.currentUserInfo.loading = false
        }, error => {
            // user not found. exit the Vue app and go to login page (directly from server)
            // Refer to my other answer: http://stackoverflow.com/a/40194152/654825

            // Or alternatively, you can serve your App's index.html only for logged-in users. Then you will never reach here.
        })
    },
    // ... more code ...
}
</script>

现在在您的组件 ./ components / navbar.vue 中接收currentUser,如下所示:

<template>
    <div class="navbar">
        <!-- some code - branding, etc.. -->
        <div>{{currentUser.loading ? "Loading..." : currentUser.name}}</div>
        <!-- some more code - logout link, etc.. -->
    </div>
</template>
<script>
export default {
    props: ["currentUser"],
    // and more ...
}
</script>

需要消化很多东西。我也广泛使用vuex,我没有在上面的示例中显示,因为您不想vuex

我希望它有助于构建您的应用。

答案 1 :(得分:5)

有几种方法可以实现这一目标。

方法#1 - 使用&#39;模板&#39;

如果您想从for(int i=0; i < mylist.size(); i++) { println mylist[i] } 向下传递道具,则需要在那里编辑模板并首先将数据传递到main.js

<强> main.js

App

...并在 App.vue

new Vue({
  ...
  template: '<App :current-user="currentUser"/>'
  ...
})

然后,<template> <div id="app"> <navbar></navbar> <resource-info :current-user="currentUser"></resource-info> </div> </template> <script> module.exports = { ... props: ['current-user'] ... } </script> ... 中将currentUser提供ResourceInfo.vue(请记得添加props: ['current-user'])。

方法#2 - 通过&#39;渲染&#39; ATTRS

渲染块允许在您要渲染的组件上定义属性。

在您的情况下,currentUser可以像这样传递:

var vm = new Vue({ 
    el: '#app', 
    data: function() { 
        return { 
            users: {}, 
            currentUser: {}, 
            quizzes: {}, 
            resources: [] 
        }
    }, 
    render (h) { 
        return ( 
            '<App />', 
            { attrs: { currentUser } } 
        ) 
    }, 
    components: { App, ResourceInfo } 
})

然后在App.vue中,您可以通过道具访问currentUser

import Navbar from './components/Navbar'
import ResourceInfo from './components/ResourceInfo'

export default {
  name: 'app',
  props: ['current-user']
  components: {
    Navbar,
    ResourceInfo
  }
}

现在你可以将它进一步传递到ResourceInfo.vue,正常情况下(见下文)。

一般传递道具

<强> App.vue

<template>
  <div id="app">
    <navbar></navbar>
    <resource-info :current-user="currentUser"></resource-info>
  </div>
</template>
...

ResourceInfo.vue 中添加props,如下所示:

<template>
  <pre>{{currentUser}} <!-- dumb example --></pre>
</template>

<script>
var resourcesRef = firebase.database().ref('resources');

module.exports = {
  name: 'resource-info',
  props: ['current-user'], // You can also do prop validation here
    ...
  }
}
</script>

...

您可以阅读有关道具here的更多信息: - )