First, by value

1. Parent to child: using the props attribute

Features :(unidirectional data flow, read-only)

If you try to modify it directly, you will get an error like this:

If you use the value as the initial value, use data or computed, or use watch to listen for changes.

Use as an initial value

Static/dynamic transfer

The parent component adds a custom property via v-ON. It passes the property to the child component. The child component receives the custom property via the props property.

<template>
  <div id="app">
    <Test weather="Sunny day" :day="today" :time="time" :list="list"/>
  </div>
</template>

<script>
import Test from "./components/Test";
export default {
  name: 'app'.components: {
    Test
  },
  data(){
    return{
      today: 'Thursday'.time: '21:55.list: [{
               id: 1.age: '6'
              }, {
              id: 2.age: '7'}, {id: 3.age: '8'}}}}]</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

#nav {
  padding: 30px;
}

#nav a {
  font-weight: bold;
  color: #2c3e50;
}

#nav a.router-link-exact-active {
  color: #42b983;
}
</style>
Copy the code

Child component: test.vue

<template>
  <div class="Test">
    <h2>{{ msg }}</h2>
    <h3>{{weather}}</h3>
    <h4>Today is {{day}}</h4>
    <h5>{{time}}</h5>
    <ul>
      <li v-for="item in list">{{item.age}} {{item.age}}</li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'Test'.props: ['day'.'time'.'weather'.'list'].data(){
    return {
      msg: 'Child component'}}}</script>

<style scoped>
li{
  list-style: none;
}
</style>

Copy the code

The results are as follows:

2, child send parent: by custom event $emit

$emit binds a custom event to a child component and passes the parameters attached to the event to the parent component. The parent component listens to the event and receives the parameters passed to it via v-on.

<template>
  <div id="app">
    <Test :age='age' @patch="fn1" @dis="fn2"/>
  </div>
</template>

<script>
import Test from "./components/Test";
export default {
  name: 'app'.components: {
    Test
  },
  data(){
    return{
        age: 6}},methods: {fn1: function(a){
      this.age++
      console.log(a)
    },
    fn2: function(b){
      this.age--
      console.log(b)
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

#nav {
  padding: 30px;
}

#nav a {
  font-weight: bold;
  color: #2c3e50;
}

#nav a.router-link-exact-active {
  color: #42b983;
}
</style>
Copy the code

Child component: test.vue

<template>
  <div class="Test">
      <h1>{{ msg }}</h1>
      <h2>Age: {{age}</h2>
      <button @click="$emit('patch',66)">age</button>
      <button @click="$emit('dis',['a', 'b', 'c'])">Age reduce</button>
  </div>
</template>

<script>
export default {
  name: 'Test'.props: ['age'].data(){
    return {
      msg: 'Child component'}}}</script>

<style scoped>
li{
  list-style: none;
}
</style>
Copy the code

The results are as follows:

Click the left button

Click the right button

When you need to get the parent method from the component and get the return value, you can use props to send the parent return value from the parent to the component. Such as:

Copy the code

Routes can also be passed as normal components, and arguments can also be passed using props and $emit

3. Cross-component delivery (not parent-child) : Use VUex

For more information on vuex use, see the article: VUEX Brief Summary

Method calls

1. The parent component invokes the child component

Parent and children methods are not recommended to use refs, which is equivalent to adding id to the child component. If you add ref to the child component, you can call the child component method directly.

<template>
    <div>Child components</div>
</template>

<script>
export default {
  name: "test".methods: {
    init(){
      console.log('Child component method called')}}}</script>

<style scoped>

</style>

Copy the code

The parent component:

<template>
  <Son ref="son"></Son>
</template>

<script>
export default {
  name: "test".components: {
    Son: () = > import('@/components/Son')},methods: {
    test(){
      this.$refs.son.init()
    }
  }
}
</script>

<style scoped>

</style>

Copy the code

1. The child component invokes the parent component

Pass the same value as above, using $emit to call