Vue.js: v-html not working as expected - vue.js

I am using keen-ui library which is a lightweight Vue.js UI library. I am using ui-select component from library. I am trying to use v-html attribute but it is somehow not working as expected. I have following code inside template:
<template>
<ui-select
label="Color"
placeholder="Color"
:options="SelectColors"
v-model="color"
v-html="red"
></ui-select>
</template>
<script>
import { UiSelect } from 'keen-ui'
export default {
data () {
red: '<div class="foo red"></div>',
SelectColours: [
{
label: this.red,
value: 'red'
}]
},
components: { UiSelect }
}
<style>
.foo {
float: left;
width: 20px;
height: 20px;
margin: 5px;
border: 1px solid rgba(0, 0, 0, .2);
}
.red {
background: red;
}
</style>
I am expecting it to show select option with only red color box. Any idea why it is not working as I expect?

Related

How can i change style of the body when my modal it will be open?

How can i change the body{overflow:hidden} when my modal it will be open?
for example it will be my modal, when its open, i would like to apply this style body{overflow:hidden}
<div v-if="dialogFoundation">
i am using vuejs3, i am using setup(){...}
The best performance would be to use javascript plain. You can add Eventlistener top the modal trigger Element. In my example i use a button. If it triggered then you can use classList and assign the body a class. In my example .dark.
Vue version
<!-- Use preprocessors via the lang attribute! e.g. <template lang="pug"> -->
<template>
<div id="app">
<h1>{{message}}</h1>
<p></p>
<button #click="doSomething">Modal</button>
</div>
</template>
<script>
export default {
data() {
return {
message: 'Welcome to Vue!'
};
},
methods: {
doSomething() {
const b = document.querySelector('body');
b.classList.toggle('dark');
}
}
};
</script>
<!-- Use preprocessors via the lang attribute! e.g. <style lang="scss"> -->
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
a,
button {
color: #4fc08d;
}
button {
background: none;
border: solid 1px;
border-radius: 2em;
font: inherit;
padding: 0.75em 2em;
}
.dark {
background: black;
opacity: 0.4;
}
</style>
Vanilla JS
const btn = document.querySelector('button');
btn.addEventListener('click', () => {
const b = document.querySelector('body');
b.classList.toggle('dark');
})
.dark {
background: black;
opacity: 0.4;
}
<body>
<div></div>
<button>click</button>
</body>
You can use watchers in Vue.js for solving this problem.
When variables changes you can check whether it is true or not, and if true change overflow of body to hidden.
{
watch: {
dialogFoundation(dialogFoundation) {
document.body.style.overflow = dialogFoundation ? "hidden" : "auto"
}
}
}
But I think this is not good solution. You can set this styles to your app element
#app {
width: 100%;
height: 100%;
overflow: auto;
}
and you can change style of app element using Vue directives.
<template>
<div id="app" :class="{ hidden: dialogFoundation }">
Long text....
</div>
</template>
<script>
import { ref } from "vue";
export default {
setup() {
const dialogFoundation = ref(true);
return { dialogFoundation };
},
};
</script>
<style>
html,
body,
#app {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
box-sizing: border-box;
}
#app {
overflow: auto;
}
#app.hidden {
overflow: hidden;
}
</style>
Code in codesandbox - https://codesandbox.io/s/immutable-glitter-rwc2iy?file=/src/App.vue

Custom switch component with v-model doesn't work

trying to do my custom Switch component in VueJS following these manuals Using v-model on Components, Adding v-model Support to Custom Vue.js Components but something wrong and it doesn't work.
My SwitchTest component:
<template>
<div>
<input type="checkbox" :id="_uid"
:value="value"
#input="updateData"
class="checkbox">
<label :for="_uid" class="switch"></label>
</div>
</template>
<script>
export default {
props: ["value"],
data() {
return {};
},
methods: {
updateData($event) {
console.log($event.target.value);
this.$emit("input", $event.target.value);
}
}
};
</script>
<style scoped>
.switch {
position: relative;
display: inline-block;
width: 40px;
height: 20px;
background-color: rgba(0, 0, 0, 0.25);
border-radius: 20px;
transition: all 0.3s;
}
.switch::after {
content: "";
position: absolute;
width: 18px;
height: 18px;
border-radius: 50%;
background-color: white;
top: 1px;
left: 1px;
transition: all 0.3s;
}
.checkbox:checked + .switch::after {
left: 20px;
}
.checkbox:checked + .switch {
background-color: #7983ff;
}
.checkbox {
display: none;
}
</style>
And using SwitchTest component:
{{switch1}}
<SwitchTest v-model="switch1"/>
{{switch2}}
<SwitchTest v-model="switch2"/>
You can see the whole MVCE example here: https://codesandbox.io/s/ecstatic-meninsky-zx7w0?file=/src/App.vue:32-131
When I toggle checkbox, its value doesn't change.
Where am I wrong?
Thank you.
Checkboxes are a special case where they have two states (checked / unchecked) which can be translated to two values. Normally, this is simply true / false but since you've bound a single :value, you'll only ever get the same value each time.
Try binding the Boolean value prop to checked and emit a true / false value
<input
type="checkbox"
:checked="value"
:id="_uid"
#input="$emit('input', $event.target.checked)"
class="checkbox"
>

How to get images to automatically reload in a vue component

I'm pretty new to Vue, I have an app running with a few different pages. One of the pages I'm trying to have is one that displays all images that are found in a directory on my host and to have them auto reload whenever the image changes (a separate app updates these images every 10 seconds). I've been able to display all the images (although only by listing them) and I can't seem to figure out how to get the pictures to auto refresh. Below is the code, any help is much appreciated.
<template>
<div id="app" class="media-display">
<figure class="media-post" v-for="(image, index) in images" v-bind:key="image.id" >
<img :key="index" :src="getImage(index)" v-bind:alt="image" width="580" height="390" v-bind:key="index" />
</figure>
</div>
</template>
<script>
import moment from 'moment'
export default {
el: '#app',
data(){
return {
images: [
'/charts/chart1.png?rnd='+Math.random(),
'/charts/chart2.png?rnd='+Math.random(),
'/charts/chart3.png?rnd='+Math.random(),
],
id : 1,
}
},
methods: {
getImage(index) {
return this.images[index]
}
}
}
</script>
<style>
.media-post {
display: inline-block;
padding: 1vmin;
//border-radius: 2vmin;
box-shadow: 0 10px 5px rgba(0, 0, 0, 0.2);
margin: 0;
background: #FFF;
position: relative;
cursor: pointer;
}
.media-post img {
//border-radius: 1vmin;
display: block;
max-width: 100%;
height: auto;
}
.media-post figcaption {
color: #FFF;
position: absolute;
top: 0;
left: 0;
font-weight: bold;
padding: 1rem 1.5rem;
z-index: 2;
font-size: 2rem;
text-shadow: 0 1px 2px #000;
}
</style>
You just need to regenerate the random number suffix periodically. Untested:
<img
v-for="url of images"
:key="url"
:src="url + '?rnd=' + cacheKey"
/>
data() {
return {
images: [
'/charts/chart1.png',
'/charts/chart2.png',
'/charts/chart3.png',
],
cacheKey: +new Date(),
};
},
created() {
this.interval = setInterval(() => {
this.cacheKey = +new Date();
}, 60 * 1000);
},
destroyed() {
clearInterval(this.interval);
},
If it isn't clear, +new Date() returns the number of seconds since 1 January 1970 00:00:00 UTC (docs).

Customizing vuetify text fields and selects

I am trying to customize v-text-field with v-selecy, faced some issues.
I've managed to customize v-text-field - changed fonts, margines, madding etc. Which works nice, but when I've jumped into v-select it's not that easy as it looks.
Here is a code of v-select component:
<template>
<v-select
class="header-multi-select"
label="Chips"
hide-details="true"
height="16"
attach
chips
multiple
></v-select>
</template>
<script>
export default {
name: 'HeaderMultiSelect'
}
</script>
<style scoped>
.header-multi-select >>> i {
font-size: 16px;
}
.header-multi-select >>> label {
font: 500 12px "Inter UI";
color: #33373E;
line-height: 16px;
top: 16px;
}
</style>
Custom v-text-field
<template>
<v-text-field
class="header-text-field-input"
hideDetails="true"
:label="label"
:append-icon="icon"
></v-text-field>
</template>
<script>
export default {
name: "HeaderTextField",
props: {
label: {
type: String,
required: true
},
icon: {
type: String,
required: true
}
}
}
</script>
<style scoped>
.header-text-field-input >>> i {
font-size: 16px;
}
.header-text-field-input >>> label {
font: 500 12px "Inter UI";
color: #33373E;
line-height: 16px;
top: 3px;
}
.header-text-field-input >>> input {
height: 16px;
font: 500 12px "Inter UI";
color: #33373E;
line-height: 16px;
}
</style>
For select I have to move to the bottom, line and the right font icon. Is there any good and smooth way to style it ?

Vuejs carousel simple example not working

I am using Vuejs with Vue-carousel-3d for the carousel. I have the most basic simple carousel component from one of the examples:
<template>
<div id="carousel-wrapper">
<carousel-3d>
<slide v-for="(i, slide) in slides" :index="i" :key="i">
<img src="https://placehold.it/360x270">
</slide>
</carousel-3d>
</div>
</template>
<script>
import { Carousel3d, Slide } from 'vue-carousel-3d';
export default {
name: 'carousel-wrapper',
components: {
'carousel-3d': Carousel3d,
'slide': Slide
},
data: function () {
return {
slides: 7
}
}
}
</script>
<style scoped>
#carousel-wrapper {
outline: 5px solid red;
}
.carousel-3d-container figure {
margin: 0;
}
.carousel-3d-container figcaption {
position: absolute;
background-color: rgba(0, 0, 0, 0.5);
color: #fff;
bottom: 0;
padding: 15px;
font-size: 12px;
min-width: 100%;
box-sizing: border-box;
}
</style>
There was an error regarding passing a key in each slide in a for loop, but after correcting it by passing :key="i", now there's no error. But the carousel is not displaying in the browser. If I inspect in developer mode, there is the carousel divs, but in the browser, there's only the 2px solid red outline that I gave for testing purpose. Its working in their example page, but not in mine. I am new to Vuejs so I may be doing something wrong. What am I missing here?