<div id="app">
<div class="root">
<div class="title">
<h1>Transparent Wrapping example</h1>
</div>
<div style="max-width:400px; margin: auto">
<my-input v-model="text" icon="user"></my-input>
<br>
{{text}}
</div>
<div>
</div>
</div>
</div>
@import url("//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css");
div.root {
text-align: center;
padding: 10px;
}
div.title {
text-align: center;
background-color: yellow;
border-style: solid;
margin-bottom: 2rem;
}
.container {
position: relative;
}
.container input {
padding-left: 30px;
}
input {
width: 100%;
}
/* style icon */
.container .glyphicon {
position: absolute;
top: 50%;
transform: translateY(-50%);
pointer-events: none;
left: 7px;
}
Vue.component('MyInput', {
name: "MyInput",
props: {
icon: String,
value: String,
},
computed: {
listeners() {
const listeners = { this.$listeners };
delete listeners["input"];
return listeners;
},
attrs() {
const attrs = { this.$attrs };
delete attrs["value"];
return attrs;
},
iconClass() {
return {
[`glyphicon-${this.icon}`]: this.hasIcon,
};
},
hasIcon() {
return !!this.icon;
},
},
methods: {
emitInput(event) {
this.$emit("input", event.target.value);
},
},
template: `
<div :class="{ container: hasIcon }">
<i class="glyphicon" :class="iconClass"></i>
<input
v-on="listeners"
v-bind="attrs"
v-on:input="emitInput"
v-bind:value="value"
/>
</div>
`,
})
var app = new Vue({
el: '#app',
data: {
text: 'hello'
},
})
This Pen doesn't use any external CSS resources.