Vue.js Component Integration: Mixins, Refs, Parent Access, and Slots
Mixins to Component and Function Reuse
Mixins allow you to inject reusable functionality and component registrations into multiple Vue components.
Example Mixin File (commonMixin.js):
import NavigationBar from '@/components/NavigationBar'
import DataDisplay from '@/components/DataDisplay'
export default {
components: {
NavigationBar,
DataDisplay
},
methods: {
handleUserAction() {
console.log('User action triggered')
}
}
}
Parent Component Using Mixins:
<template>
<div class="container">
<NavigationBar>
<div slot="left-section">Left Content</div>
<div slot="right-section" @click="handleUserAction">Right Content</div>
</NavigationBar>
<div class="main-content">
<h1 ref="mainHeading" id="mainHeading">Main Title</h1>
<p ref="description" id="description">Content description</p>
<button @click="retrieveElements">Get DOM Elements</button>
<DataDisplay ref="dataComponent"/>
<button @click="fetchChildData">Get Child Component Data</button>
</div>
</div>
</template>
<script>
import commonMixin from '@/mixins/commonMixin'
export default {
mixins: [commonMixin],
data() {
return {
parentMessage: 'Data from parent component'
}
},
methods: {
retrieveElements() {
console.log(document.getElementById('mainHeading'))
console.log(document.getElementById('description'))
console.log('--- Vue refs ---')
console.log(this.$refs.mainHeading)
console.log(this.$refs.description)
},
fetchChildData() {
this.$refs.dataComponent.info = 'Updated value'
console.log(this.$refs.dataComponent.info)
}
}
}
</script>
When a component defines a method with the same name as a mixin method, the component's method takes precedence.
Accessing Child Components with $refs
The $refs property provides direct access to child component instances and DOM elements.
// Accessing DOM elements
console.log(this.$refs.mainHeading) // Vue-managed reference
console.log(this.$refs.description) // Alternative to document.getElementById
// Accessing child component data and methods
this.$refs.dataComponent.info = 'New value'
console.log(this.$refs.dataComponent.info)
this.$refs.dataComponent.childMethod()
Accessing Parent Components with $parent
Child components can access their parent's data and methods using $parent.
Child Component Example:
<template>
<div>
<button @click="retrieveParentInfo">Get Parent Component Data</button>
</div>
</template>
<script>
export default {
data() {
return {
childInfo: 'Data from child component'
}
},
methods: {
retrieveParentInfo() {
console.log(this.$parent.parentMessage)
this.$parent.parentMethod()
}
}
}
</script>
Slot-Based Content Distribution
Slots enable flexible content distribution between parent and child components.
Child Component with Named Slots:
<template>
<header class="navigation-header">
<ul>
<li>
<slot name="left-section">Default Left</slot>
</li>
<li>
<slot>Default Center</slot>
</li>
<li>
<slot name="right-section">Default Right</slot>
</li>
</ul>
</header>
</template>
<style scoped>
.navigation-header {
width: 100%;
height: 44px;
background-color: #f66;
margin-bottom: 10px;
}
.navigation-header ul {
width: 100%;
height: 100%;
display: flex;
}
.navigation-header li {
width: auto;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.navigation-header li:nth-child(1) {
width: 50px;
}
.navigation-header li:nth-child(2) {
flex: 1;
}
.navigation-header li:nth-child(3) {
width: 50px;
}
</style>
Parent Component Using Slots:
<NavigationBar>
<div slot="left-section">Custom Left Content</div>
<div>Main Content Area</div>
<div slot="right-section" @click="handleUserAction">Right Action</div>
</NavigationBar>