JSFiddle - React, Tailwind, and code Playground
by lid0
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.12/vue.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/css/bootstrap.min.css">
<div class="container">
<div id="app">
<my-comp1>Text in comp1 component</my-comp1>
<my-comp2>Text in comp2 component</my-comp2>
<my-comp1><my-comp2 style="margin-left:50px;">Text in comp1 component</my-comp2></my-comp1>
</div>
</div>
CSS
body {
margin-top: 1rem
}
*[data-component-name]{
position:relative;
}
*[data-component-name]:hover {
background:#e1dd99;
}
/* *[data-component-name]:hover::before { */
*[data-component-name]::before {
font-size:9px;
background: #b9b9b9;
position: absolute;
content: attr(data-component-name);
opacity: 0.7;
top: -13px;
left: -5px;
color: #000;
padding: 3px;
border-radius: 10px;
}
*[data-component-name] {
border:1px dashed #cfcfcf; /* outline components */
}
div {
margin-top:30px;
background:#fff;
}
JavaScript
/**
Add data-component-name attribute, with the name of the component,
to each of the components root element
mounted() mixin/hook used to inject attribute all componenets.
using css we then show a content box near each element.
we override componenet positioning to relative so content element can be absoluste positioned.
which may effect the styling of the page.
this can be less of a problem if we use :hover to only expose the content
so it will be temporary flow break
*/
let componentNameToAttributeMixin = {
mounted(){
this.$el.setAttribute("data-component-name",this.$options._componentTag)
}
}
Vue.component('my-comp1', {
template: '<div><slot/></div>',
mixins: [componentNameToAttributeMixin]
});
Vue.component('my-comp2', {
template: '<div><slot/></div>',
mixins: [componentNameToAttributeMixin]
});
new Vue({
el: '#app'
})