Vue.js: How to specify props in single file component?

Alfred Huang picture Alfred Huang · Apr 17, 2016 · Viewed 28k times · Source

I'm defining a single file component

I want to use props option on that component.

But where can I add the code?

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

Answer

Alfred Huang picture Alfred Huang · Apr 17, 2016

After a long time of experiment, I found out a practical solution:

The project file structure:

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

Now, we want to access the root component -- App's vm fields inside the sub-component Home.vue, with vue-route on.

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>

Conclusion

Note that the inner prop bound the property on the attribute of the component tag (<router-view> Tag in this case.), NOT directly on the parent component.

So, we must manually bind the passing props field as an attribute on the component tag. See: http://vuejs.org/guide/components.html#Passing-Data-with-Props

Also, notice I used a .sync on that attribute, because the binding is one-way-down by default: http://vuejs.org/guide/components.html#Prop-Binding-Types

You can see, sharing the status through nesting components is a bit confused. To make a better practice, we can use Vuex.