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 ?
Related
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
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"
>
So I have the following Vue app
App.vue
<template id="main-page">
<v-ons-page>
<l-map
ref="map"
v-if="showMap"
:zoom="zoom"
:center="center"
:options="mapOptions"
style="height: 100%"
#update:center="centerUpdate"
#update:zoom="zoomUpdate"
#update:bounds="boundUpdate"
#move="move"
>
<l-tile-layer
:url="url"
:attribution="attribution"
/>
<l-marker
v-if="addNewMarker"
:lat-lng="liveCenter"
>
<l-icon
:icon-size="dynamicSize"
:icon-anchor="dynamicAnchor"
icon-url="https://cdn3.iconfinder.com/data/icons/metro-explorer/512/my_location-512.png"
/>
</l-marker>
<l-marker
v-for="marker in markers"
:key="marker.id"
:visible="marker.visible"
:draggable="marker.draggable"
:lat-lng.sync="marker.position"
#click="alert(marker)"
>
</l-marker>
<l-control class="example-custom-control"
:position="'bottomright'">
<img
#click="showAddMarkerSetup"
src="https://cdn4.iconfinder.com/data/icons/iconsimple-places/512/pin_plus-512.png"
height="42" width="42"
>
</l-control>
</l-map>
<Cancel v-if="addNewMarker"/>
<Ok v-if="addNewMarker"/>
</v-ons-page>
</template>
<style>
.example-custom-control {
background: #fff;
padding: 0 0.5em;
border: 1px solid #aaa;
border-radius: 0.1em;
}
.ok {
position: absolute;
bottom: 20px;
right: 30%;
width: 100px;
height: 50px;
z-index:999;
background: #000;
color: white;
opacity: 0.5;
display: flex;
justify-content: center;
align-items: center;
}
</style>
<script>
import { latLng } from "leaflet";
import {
LMap,
LTileLayer,
LMarker,
LControl,
LIcon
} from "vue2-leaflet";
import Cancel from './components/add/Cancel'
import Ok from './components/add/Ok'
export default {
name: "Example",
components: {
LMap,
LTileLayer,
LMarker,
LControl,
LIcon,
Cancel,
Ok
},
data() {
return {
zoom: 18,
center: latLng(14.601205, 120.974780),
url: 'https://api.test.goxhere.com/place-geoserver/geoserver/gwc/service/gmaps?layers=postgis:goxhere&zoom={z}&y={y}&x={x}&format=image/png',
attribution:
'© GoXhere',
withPopup: latLng(14.601205, 120.974780),
withTooltip: latLng(14.601205, 120.974980),
currentZoom: 11.5,
currentCenter: latLng(14.5905, 120.9781),
liveCenter: latLng(14.601205, 120.974780),
showParagraph: false,
mapOptions: {
zoomSnap: 0.5,
zoomControl: false
},
showMap: true,
markers: [],
addNewMarker: false,
dynamicSize: [32, 32],
dynamicAnchor: [32, 32]
};
},
methods: {
zoomUpdate(zoom) {
this.currentZoom = zoom;
},
centerUpdate(center) {
this.currentCenter = center;
},
showLongText() {
this.showParagraph = !this.showParagraph;
},
innerClick() {
alert("Click!");
},
showAlert() {
alert("Click!");
},
showAddMarkerSetup() {
console.log('showAddMarkerSetup clicked')
console.log('adding a marker at the center')
this.addNewMarker = !this.addNewMarker
},
boundUpdate() {
console.log('bound update')
// check if
},
move(e) {
console.log('map moving')
if (this.addNewMarker) {
this.liveCenter = e.target.getCenter()
}
}
}
};
</script>
Here is my Cancel.vue component
<template>
<div class="cancel">Cancel</div>
</template>
<style scoped>
.cancel {
position: absolute;
bottom: 20px;
left: 30%;
width: 100px;
height: 50px;
z-index:999;
background: #000;
color: white;
opacity: 0.5;
display: flex;
justify-content: center;
align-items: center;
}
</style>
<script>
export default {
data() {
return {
"a": "sss"
}
},
methods: {
mounted() {
console.log('mounted from cancel')
}
}
}
</script>
If I set the addNewMarker field to true, the Cancel component does not appear in the UI (even though I can see its being added in Vue component console)
However, if I use v-show instead of v-if, I can see the Cancel component showing on and off if I toggle the addNewMarker. Is there anything I should configure so that v-if works correctly for single file templates?
Here is a video demo showing v-if (not working) and v-show (working)
I'm not sure how to set a default/initial selected option using vue-select, specifically when you use slots.
Here is the code: https://vue-select.org/guide/slots.html
I would want one of the options to initially display on page load.
Pass the option object you want as a default value into the v-model prop of the component.
Vue.component('v-select', VueSelect.VueSelect)
new Vue({
el: '#app',
data: {
selectedOption: {
title: 'Read the Docs',
icon: 'fa-book',
url: 'https://codeclimate.com/github/sagalbot/vue-select'
},
options: [
{
title: 'Read the Docs',
icon: 'fa-book',
url: 'https://codeclimate.com/github/sagalbot/vue-select'
},
{
title: 'View on GitHub',
icon: 'fa-github',
url: 'https://codeclimate.com/github/sagalbot/vue-select'
},
{
title: 'View on NPM',
icon: 'fa-database',
url: 'https://codeclimate.com/github/sagalbot/vue-select'
},
{
title: 'View Codepen Examples',
icon: 'fa-pencil',
url: 'https://codeclimate.com/github/sagalbot/vue-select'
}
]
}
})
body {
font-family: "Source Sans Pro", "Helvetica Neue", Arial, sans-serif;
}
h1,.muted {
color: #2c3e5099;
}
h1 {
font-size: 26px;
font-weight: 600;
text-rendering: optimizelegibility;
-moz-osx-font-smoothing: grayscale;
-moz-text-size-adjust: none;
}
#app {
max-width: 30em;
margin: 1em auto;
}
#app .dropdown li {
border-bottom: 1px solid rgba(112, 128, 144, 0.1)
}
#app .dropdown li:last-child {
border-bottom: none;
}
#app .dropdown li a {
padding: 10px 20px;
display: flex;
width: 100%;
align-items: center;
font-size: 1.25em;
}
#app .dropdown li a .fa {
padding-right: 0.5em;
}
<script src="https://unpkg.com/vue-select#3.2.0/dist/vue-select.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h1>Vue Select - Custom Option Templating</h1>
<v-select :options="options" v-model="selectedOption" label="title">
<template slot="option" slot-scope="option">
<span class="fa" :class="option.icon"></span>
{{ option.title }}
</template>
</v-select>
</div>
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?