vue-web-component-wrapper
Version:
A Vue 3 plugin that provides a web component wrapper with styles, seamlessly integrating with Vuex, Vue Router, Vue I18n, and supporting Tailwind CSS and Sass styles.
140 lines (127 loc) • 4.79 kB
HTML
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite 4 + Vue 3.3 + Typescript 5 + Web Component</title>
</head>
<body>
<div style="margin-bottom: 30px; display: flex; flex-direction: column; max-width: 70%; margin-left: auto; margin-right: auto;">
<h1 class="text-title" style="text-align:center;">Vite 4 + Vue 3.3 + Typescript 5 + Web Component</h1>
<div style="border: 1px solid rgb(78, 77, 77); border-radius: 10px; font-size:x-small;">
<pre >
<code><my-web-component
lang="de"
route="/route1"
class="my-web-component"
api-token="++++++++++++++++++++++++"
base-uri="https://my.base.uri"
model-value="v-model-value"
>
<!-- default slot -->
<h1>I am a default slot</h1>
<!-- named slot -->
<div slot="customName">I am a custom slot </div>
</my-web-component>
</code>
</pre>
</div>
<div style="display: flex; justify-content: space-between;">
<div style="max-width: 40%;">
<h2>2 Way binding(v-model)</h2>
<input id="myInput" type="text" />
</div>
<div>
<h2>Custom Event</h2>
<div id="color-changing-div" style="width: 140px; height: 30px;">event is fiered</div>
</div>
</div>
</div>
<hr>
<my-web-component
lang="de"
route="/route1"
class="my-web-component"
api-token="++++++++++++++++++++++++"
base-uri="https://my.base.uri"
model-value="v-model-value"
>
<!-- default slot -->
<my-child-component
lang="de"
route="/route1"
class="my-child-component"
></my-child-component>
<!-- named slot -->
<div class="customName" hidden slot="customName">I am a custom named slot </div>
<div class="customName" data-web-component-loader slot="customName">
<div class="spinner"></div>
</div>
</my-web-component>
<script type="module" src="./src/main.ts"></script>
<script >
const myWebComponent = document.querySelector('my-web-component');
const myInput = document.querySelector('#myInput');
myWebComponent.addEventListener('customEventTest', (event) => {
console.log('emit-event', event);
});
// v-model 2 way binding
myWebComponent.addEventListener('update:modelValue', (event) => {
console.log('v-model-event', event);
// update the vue component prop value of the v-model
myWebComponent.setAttribute('model-value', event.detail[0]);
// update the external input value
myInput.value = event.detail[0];
})
// update the vue component prop value of the v-model
myInput.addEventListener('input', (event) => {
myWebComponent.setAttribute('model-value', event.target.value);
})
const colorChangingDiv = document.querySelector('#color-changing-div');
let colors = ['blue', 'green', 'red', 'yellow', 'purple', 'orange'];
let currentColorIndex = 0;
myWebComponent.addEventListener('customEventTest', () => {
currentColorIndex = (currentColorIndex + 1) % colors.length;
colorChangingDiv.style.backgroundColor = colors[currentColorIndex];
});
</script>
</body>
<style>
.text-title {
color: #4a90e2; /* A more subtle shade of blue */
font-size: 1.5rem; /* Slightly larger size */
font-weight: 700; /* Bold font weight */
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); /* Soft shadow for depth */
margin-bottom: 20px; /* Space below the title */
font-family: 'Arial', sans-serif; /* A clean, modern font */
text-transform: uppercase; /* Capitalize all letters for emphasis */
letter-spacing: 1.5px; /* Slightly more space between letters */
}
#color-changing-div {
border: 3px solid #555;
border-radius: 15px;
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
transition: background-color 0.5s ease;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bold;
}
.spinner {
border: 4px solid rgba(0, 0, 0, 0.1);
border-left-color: #4a90e2; /* Customize spinner color if needed */
border-radius: 50%;
width: 30px;
height: 30px;
animation: spin 1s linear infinite;
margin: auto;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
</style>
</html>