Рассмотрим этот пункт на примере.
main.js
import Vue from 'vue';
import App from './App.vue';
import Cars from './components/Cars';
Vue.component('app-car', Cars);
new Vue({
el: '#app',
render: h => h(App)
})
app.vue
<template>
<div>
<h1> {{carName}} </h1>
<app-car
v-bind:carName="carName"
v-bind:carYear="carYear"
v-on:nameChanged="carName = $event"
></app-car>
</div>
</template>
<script>
export default {
data () {
return {
carName: 'Mazda',
carYear: 2018
}
}
}
</script>
<style></style>
cars.vue
<template>
<div class="carblock">
<h3>{{ carName }}</h3>
<p>{{ carYear }}</p>
<button @click="carChange">Изменить автомобиль</button>
</div>
</template>
<script>
export default {
props: ['carName', 'carYear'],
methods: {
carChange(){
this.carName = 'Ford'
this.$emit('nameChanged', this.carName)
}
}
}
</script>
<style scoped>
.carblock {
padding: 10px;
border: 3px solid #000000;}
</style>
Рассмотрим также на примере. main.js остается таким же.
app.vue
<template>
<div>
<h1> {{carName}} </h1>
<app-car
v-bind:carName="carName"
v-bind:carYear="carYear"
v-bind:changeFunc="changeNameAudi"
v-on:nameChanged="carName = $event"
></app-car>
</div>
</template>
<script>
export default {
data () {
return {
carName: 'Mazda',
carYear: 2018
}
},
methods: {
changeNameAudi() {
this.carName = 'Audi'
}
}
}
</script>
<style></style>
cars.vue
<template>
<div class="carblock">
<h3>{{ carName }}</h3>
<p>{{ carYear }}</p>
<button @click="carChange">Изменить автомобиль</button>
<button @click="changeFunc()">Aвтомобиль Audi</button>
</div>
</template>
<script>
export default {
props: {
carName: String,
carYear: Number,
changeFunc: Function
},
methods: {
carChange(){
this.carName = 'Ford'
this.$emit('nameChanged', this.carName)
}
}
}
</script>
<style scoped>
.carblock {
padding: 10px;
border: 3px solid #000000;}
</style>
Рассмотрим пример как можно связать два дочерних компонента между собой через родительский компонент.
main
import Vue from 'vue';
import App from './App.vue';
import Cars from './components/Cars';
import Counter from './components/Counter';
Vue.component('app-car', Cars);
Vue.component('app-counter', Counter);
new Vue({
el: '#app',
render: h => h(App)
})
app.vue
<template>
<div>
<h1> {{carName}} </h1>
<app-counter
:counter="counter"
></app-counter>
<app-car
:carName="carName"
:carYear="carYear"
:counter="counter"
:changeFunc="changeNameAudi"
@nameChanged="carName = $event"
@counterUpdated="counter = $event"
></app-car>
</div>
</template>
<script>
export default {
data () {
return {
carName: 'Mazda',
carYear: 2018,
counter: 0
}
},
methods: {
changeNameAudi() {
this.carName = 'Audi'
}
}
}
</script>
<style></style>
cars.vue
<template>
<div class="carblock">
<h3>{{ carName }}</h3>
<p>{{ carYear }}</p>
<button @click="carChange">Изменить автомобиль</button>
<button @click="changeFunc()">Aвтомобиль Audi</button>
<button @click="updateCounter">Counter up</button>
</div>
</template>
<script>
export default {
props: {
carName: String,
carYear: Number,
counter: Number,
changeFunc: Function
},
methods: {
carChange() {
this.carName = 'Ford'
this.$emit('nameChanged', this.carName)
},
updateCounter() {
this.$emit('counterUpdated', this.counter + 1)
}
}
}
</script>
<style scoped>
.carblock {
padding: 10px;
border: 3px solid #000000;}
</style>
counter.vue
<template>
<h1>Counter: {{ counter }}</h1>
</template>
<script>
export default {
props: [
'counter'
]
}
</script>
С помощью "event emitter" мы можем обмениваться данными между двумя дочерними элементами минуя родительский элемент в разработке простых приложений.
main.js
/* jshint ignore:start */
import Vue from 'vue'
import App from './App.vue'
import Cars from './components/Cars'
import Counter from './components/Counter'
Vue.component('app-car', Cars)
Vue.component('app-counter', Counter)
export const eventEmitter = new Vue()
new Vue({
el: '#app',
render: h => h(App)
})
app.vue
<template>
<div>
<h1> {{carName}} </h1>
<app-counter></app-counter>
<app-car
:carName="carName"
:carYear="carYear"
:changeFunc="changeNameAudi"
@nameChanged="carName = $event"
@counterUpdated="counter = $event"
></app-car>
</div>
</template>
<script>
export default {
data () {
return {
carName: 'Mazda',
carYear: 2018
}
},
methods: {
changeNameAudi() {
this.carName = 'Audi'
}
}
}
</script>
<style></style>
cars.vue
<template>
<div class="carblock">
<h3>{{ carName }}</h3>
<p>{{ carYear }}</p>
<button @click="carChange">Изменить автомобиль</button>
<button @click="changeFunc()">Aвтомобиль Audi</button>
<button @click="updateCounter">Counter up</button>
</div>
</template>
<script>
import {eventEmitter} from '../main.js'
export default {
props: {
carName: String,
carYear: Number,
changeFunc: Function
},
methods: {
carChange() {
this.carName = 'Ford'
this.$emit('nameChanged', this.carName)
},
updateCounter() {
//this.$emit('counterUpdated', this.counter + 1)
eventEmitter.$emit('counterUpdated', 3)
}
}
}
</script>
<style scoped>
.carblock {
padding: 10px;
border: 3px solid #000000;}
</style>
counter.vue
<template>
<h1>Counter: {{ counter }}</h1>
</template>
<script>
import {eventEmitter} from '../main.js'
export default {
data () {
return {
counter: 0
}
},
created () {
eventEmitter.$on('counterUpdated', (num) => {
this.counter += num
})
}
}
</script>
Мы можем передавать HTML от родителя компоненту вот таким образом.
app.vue
<template>
<div>
<app-car>
<p>simple text</p>
<h1 slot="title">{{ carName }}</h1>
<p slot="text">Lorem ipsum dolor sit amet consectetur adipisicing elit. Dignissimos cumque assumenda repellendus, accusamus laboriosam dolorem suscipit dolores quaerat soluta esse nobis aliquid rerum repellat! Fugit iure quasi vero obcaecati iste?</p>
</app-car>
</div>
</template>
<script>
export default {
data () {
return {
carName: "Ford"
}
}
}
</script>
<style></style>
cars.vue
<template>
<div class="carblock">
<slot></slot>
<slot name="title"></slot>
<br>
<br>
<slot name="text"></slot>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
.carblock {
padding: 10px;
border: 3px solid #000000;}
</style>