admin管理员组

文章数量:1279124

Coming to Vue from React. For the most part there are a lot of similarities but passing props seems a little different. I couldn't find much documentation on how to do this using single file ponents. I import all my data for the app in main.js. I'm wondering how I can get parts of my data like currentUser for example, to ResourceInfo.vue? Again assuming these are all single file ponents. Do I need to pass it down through the <App/> part under main.js template option, then into <resource-info></resource-info> in App.vue then somehow into ResourceInfo.vue? I'd like to stay away from having to learn Vuex as well because I'm just starting out. Thanks!

main.js

import Vue from 'vue'
import App from './App'
import ResourceInfo from '../src/ponents/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/>',
  ponents: { App, ResourceInfo },
})

App.vue

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

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

export default {
  name: 'app',
  ponents: {
    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>

Coming to Vue from React. For the most part there are a lot of similarities but passing props seems a little different. I couldn't find much documentation on how to do this using single file ponents. I import all my data for the app in main.js. I'm wondering how I can get parts of my data like currentUser for example, to ResourceInfo.vue? Again assuming these are all single file ponents. Do I need to pass it down through the <App/> part under main.js template option, then into <resource-info></resource-info> in App.vue then somehow into ResourceInfo.vue? I'd like to stay away from having to learn Vuex as well because I'm just starting out. Thanks!

main.js

import Vue from 'vue'
import App from './App'
import ResourceInfo from '../src/ponents/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/>',
  ponents: { App, ResourceInfo },
})

App.vue

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

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

export default {
  name: 'app',
  ponents: {
    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>
Share Improve this question asked Oct 24, 2016 at 22:24 maxwellgovermaxwellgover 7,1519 gold badges41 silver badges66 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

@DanM. has already provided the answer, and I hope you managed to fix your props as per his guidance.

I am writing this answer so I can share my method of dealing with currentUser in my app (only for logged-in users). Here is my project structure (highly simplified for this answer):

Template: webpack, installed using vue init webpack my-project using vue-cli

My app files:

  • ./main.js: app entry file
  • ./App.vue: responsible for page layout, like header, footer, and route contents using router-view
  • ./ponents/: Common ponents like navbar, footer, etc.
  • ./routes/: Route ponents. I prefer to put it here instead of cluttering my ponents folder.
  • and a lot more...

Code in my main.js: Just the standard code to define routes and bootstrap the app. Nothing special here.

Code in my App.vue - here is where currentUser gets fetched. Navbar also gets inserted, where I pass currentUser via 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 "./ponents/app-navbar.vue"
import AppFooter from "./ponents/app-footer.vue"

export default {
    ponents: {
        "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./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>

Now receive currentUser in your ponent ./ponents/navbar.vue as follows:

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

Thats a lot to digest. I also use vuex extensively, which I did not show in the sample above as you did not want vuex.

I hope it helps to structure your app.

There are a couple of ways you can achieve this.

Method #1 - using 'template'

If you want to pass props down from main.js, you need to edit the template there and pass the data down to App first:

main.js

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

...and in App.vue

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

<script>
module.exports = {
  ...
  props: ['current-user']
  ...
}
</script>
...

Then, currentUser will be available in ResourceInfo.vue (remember to add props: ['current-user']).

Method #2 - passing down via 'render' attrs

Render blocks allow defining attributes on the ponent you're rendering.

In your case, currentUser can be passed down like so:

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

Then in App.vue you'll be able to access currentUser via props:

import Navbar from './ponents/Navbar'
import ResourceInfo from './ponents/ResourceInfo'

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

Now you can pass it further down to ResourceInfo.vue as you'd normally would (see below).


Passing props in general

App.vue:

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

And add props in ResourceInfo.vue, like so:

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

...

You can read more about props here :-)


本文标签: javascriptHow Do I Pass Props Using Single File ComponentsStack Overflow