组件(Component)是 Vue 中很重要的一个功能,一个 Vue 页面会有多个组件组成,组件之间也会经常需要互相传递数据和调用功能。这里简单写一下 Vue 组件之间的通信。因为本人正在学习 Vue 所以可能写的不够全面,这里使用的是单文件组件。

父组件和子组件通信

props

父组件代码:

<template>
  <div id="app">
    <my-content content="hello"></my-content>
  </div>
</template>

<script>
//  引入content组件
import content from './components/content'

export default {
  components: {
    //  注册 content 组件
    'my-content': content
  },
  data() {
    return {
      hello: 'hello'
    }
  }
}
</script>

其中的 my-content 就是子组件,在调用子组件的标签中有一个 content 属性,content 属性中的内容就是要传给子组件的数据,属性名称可以自定义,这里的 content 属性 绑定了 data 中的 hello ,当父组件中的 hello 中的内容改变时子组件接收的内容也会改变。子组件可以通过 props 来接收数据。

子组件代码:

<template>
  <div id="content">{{content}}</div>
</template>

<script>
export default {
  name: 'content',
  //  通过 props 接收父组件的内容
  props: ['content']
}
</script>

子组件名称为: content ,在父组件中注册为: my-contentprops 中的 content 就是用来接收父组件传来的数据,props 中的内容需要和父组件调用子组件的属性相同。子组件可以直接绑定 props 中的数据,如果要在方法中调用可以使用 this ,例如上面的子组件使用 content 接收 方法中就可以使用 this.content 来调用数据。

如果要传递多项数据可以定义多个属性和多个 props ,但是多个属性和 props 不太美观,而且不能传数组。对于多项数据写法如下:

父组件代码:

<template>
  <div id="app">
    <my-content v-bind:content="article"></my-content>
  </div>
</template>

<script>
//  引入content组件
import content from './components/content'

export default {
  components: {
    //  注册 content 组件
    'my-content': content
  },
  data() {
    //  要传给 content 组件的数据
    return {
      article: {
        time: '2019年11月12日 20:20',
        author: '冰是睡着的水',
        content: '这里是内容'
      }
    }
  }
}
</script>

在父组件中需要使用 v-bind 来绑定数据,子组件还是用 props 接收。

子组件代码:

<template>
  <div id="content">
    <div>{{content.author}}</div>
    <div>{{content.time}}</div>
    <div>{{content.content}}</div>
  </div>
</template>

<script>
export default {
  name: 'content',
  //  通过 props 接收父组件的内容
  props: ['content']
}
</script>

ref

通过 ref 注册引用,父组件可以直接调用子组件的方法和访问子组件的 DOM 和数据。

父组件代码:

<template>
  <div id="app">
    <button @click="setContent" type="button">把数据传给content组件</button>
    <my-content ref="content"></my-content>
  </div>
</template>

<script>
//  引入content组件
import content from './components/content'

export default {
  components: {
    //  注册 content 组件
    'my-content': content
  },
  methods: {
    setContent() {
      //  直接设置 content 的 data
      this.$refs.content.content = 'Hello World'
    }
  }
}
</script>

上面在调用子组件的元素中使用 ref 属性 注册了一个 content 的引用,使用 ref 注册后就可以直接访问注册元素的 DOM 和方法。访问的时候使用 $refs 引用,上面父组件中的 this.$refs.content.content 就是引用注册的 content 中的 content 数据,最后一个 content 就是子组件 data 中的 content

子组件代码:

<template>
  <div id="content">{{content}}</div>
</template>

<script>
export default {
  name: 'content',
  data() {
    return {
      content: ''
    }
  }
}
</script>

子组件和父组件通信

$emit

子组件通过 $emit 可以直接调用父组件的自定义事件。

子组件代码:

<template>
  <div id="content">
    <button @click="sendMessage" type="button">传递数据</button>
  </div>
</template>

<script>
export default {
  name: 'content',
  methods: {
    sendMessage() {
      //  通过$emit来调用app组件的showMessage事件
      this.$emit('showMessage', 'Hello app')
    }
  }
}
</script>

子组件通过 $emit 调用父组件的自定义事件,其中的 showMessage 也就是第一个参数就是事件名称,Hello app 也就是第二个参数就是要传递的内容。

父组件代码:

<template>
  <div id="app">
    <my-content @showMessage="showMessage"></my-content>
  </div>
</template>

<script>
//  引入content组件
import content from './components/content'

export default {
  components: {
    //  注册 content 组件
    'my-content': content
  },
  methods: {
    showMessage(content) {
      alert(content)
    }
  }
}
</script>

上面的父组件在调用子组件的元素中定义了一个名为 :showMessage 的自定义事件,showMessage 事件又绑定了名为: showMessage 的方法,showMessage 方法接收的参数就是子组件通过 $emit 发送的参数。

以上就是 Vue 组件的通信,因为本人也是正在学 Vue 所以写的可能还不够全面,以后可能还会有补充。