Vue.js:如何在单文件组件中指定props?

38
我正在定义一个单文件组件
我想在该组件上使用props选项。
但是代码应该放在哪里?
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
  </div>
</template>

<script>
export default {
  data () {
    return {
      // note: changing this line won't causes changes
      // with hot-reload because the reloaded component
      // preserves its current state and we are modifying
      // its initial state.
      msg: 'Hello World!'
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1 {
  color: #42b983;
}
</style>

请查看下面@Gijsberts的答案,其中包含有关VueJS样式指南以及如何输入props的重要说明。 - Mohammad
4个回答

27

经过长时间的实验,我发现了一个实用的解决方案:

项目文件结构:

src/
  assets/
  components/
    Home.vue
  App.vue
  main.js
package.json
config.js
index.html

现在,我们希望在使用 vue-route 的情况下,可以访问根组件——App的vm字段,在子组件Home.vue中进行操作。

main.js:

import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App'

Vue.use(VueRouter);

let router = new VueRouter();

router.map({
    '/': {
        name: 'home',
        component: require('./components/Home')
    }
});

router.start(App, 'body');

App.vue:

<template>

    <p>The current path: {{ $route.path }}.</p>
    <p>Outer-Value: {{ outer_var }}</p>
    <hr/>

    <!-- The below line is very very important -->
    <router-view :outer_var.sync="outer_var"></router-view>

</template>

<script>
    import Home from './compnents/Home.vue'

    export default {
        replace: false,
        components: { Home },
        data: function() {
            return {
                outer_var: 'Outer Var Init Value.'
            }
        }
    }
</script>

Home.vue

<template>
    <div>
        <p><input v-model="outer_var" /></p>
        <p>Inner-Value: {{ outer_var }}</p>
    </div>
</template>

<script>
    export default {
        // relating to the attribute define in outer <router-view> tag.
        props: ['outer_var'],
        data: function () {
            return {
            };
        }
    }
</script>

结论

请注意,内部属性限制的是组件标签上的属性(在本例中为<router-view>标签),并不是直接限制父组件。

因此,我们必须将传递的props字段手动绑定为组件标签上的属性。参见:http://vuejs.org/guide/components.html#Passing-Data-with-Props

另外,请注意我在该属性上使用了.sync,因为默认情况下绑定是单向向下的:参见http://vuejs.org/guide/components.html#Prop-Binding-Types

可以看到,通过嵌套组件共享状态有些混乱。为了更好的实践,我们可以使用Vuex


2
请优先使用 vue.js 标签,而不是 vuejs 标签,因为前者已经接近 1000 个问题,而后者甚至没有 10 个问题,实际上应该被删除。这样做会获得更多的关注 ;) - Yerko Palma
5
@YerkoPalma,哈哈,你注意到那个点了...事实上,我想在这个标签上得到5个点,然后创建一个同义词...一切都是为了那个闪闪发光的徽章...你介意给我一个点来达成目标吗? - Alfred Huang

24

你可以这样做:

app.js

<template>
  <div class="hello">
    <h1>{{ parentMsg }}</h1>
    <h1>{{ childMsg }}</h1>
  </div>
</template>

<script>
export default {
  props: ['parentMessage'],
  data () {
    return {
      childMessage: 'Child message'
    }
  }
}
</script>

<style scoped>
h1 {
  color: #42b983;
}
</style>

主要.js

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

new Vue({
  el: '#app',
  data() {
    return {
      message: 'Parent message'
    }
  },
  render(h) {
    return h(App, { props: { parentMessage: this.message } })
  }
});

这看起来像是 TypeScript 语法,我对吗?用普通的 JS 怎么样?例如使用 require - Michael W. Czechowski
@NEXTLEVELSHIT 对我来说这只是普通的JS,但是在Vue框架中。可能是通过Babel使用es2015。 - Michael Giovanni Pumo

18

几个月前,Vue推出了自己的风格指南,用于参考和类似的事情。 Props是其中一个参考,实际上是一个必不可少的参考。

props: ['status']

好的

props: {
  status: String
}

更好的是

props: {
  status: {
    type: String,
    required: true,
    validator: function (value) {
      return [
        'syncing',
        'synced',
        'version-conflict',
        'error'
      ].indexOf(value) !== -1
    }
  }
}

你可以在这里找到更多相关内容。


你甚至可以使用 includes 代替 indexOf(value) !== -1 - Soldeplata Saketos
样式指南适用于v2版本,他要求单文件组件,这些组件应该是v3版本(我认为)。 - cauchi
@cauchi,你说错了,SFC在Vue.js 2+中已经存在了 :) - Giesburts

0

就像这样,在调用createApp()时传递props

查看图片


1
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接