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

How Do I Pass Props Using Single File Components?

本文关键字:Props 组件 何使用 单个 文件      更新时间:2023-09-26

从React来到Vue。在大多数情况下,有很多相似之处,但通过props似乎有点不同。我找不到关于如何使用单个文件组件做到这一点的太多文档。我在main.js中导入应用程序的所有数据。我想知道我怎么能得到我的部分数据,如currentUser,例如,到ResourceInfo.vue ?再次假设这些都是单个文件组件。我是否需要通过main.js模板选项下的<App/>部分传递它,然后在App.vue中进入<resource-info></resource-info>,然后以某种方式进入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>

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

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

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

我的应用程序文件:

  • ./main.js: app入口文件
  • 。/应用程序。vue:使用router-view
  • 负责页面布局,如页眉,页脚和路由内容
  • 。/components/:通用组件,如导航栏,页脚等
  • 。/routes/:路由组件。我喜欢把它放在这里,而不是把它放在我的组件文件夹里。
  • 和更多…

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

代码在我的App.vue -这里是currentUser获取。导航条也被插入,我通过props传递currentUser

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

现在接收currentUser在你的组件./components/navbar。的修改如下:

<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 -使用'template'

如果你想从main.js传递道具,你需要编辑那里的模板,并首先将数据传递给App:

main.js

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 -通过'render'属性传递

渲染块允许定义你正在渲染的组件的属性。

在您的情况下,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通过props:

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中添加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>
...

你可以在这里阅读更多关于props的信息:-)