Apply changes in nested class during disabled state in Vue 3 - javascript

I have implemented radio buttons using Oruga Library in Vue 3, I want to check for the disabled state of the radio button and apply class accordingly.
The code I am using is given below.
<template>
<o-radio v-bind="$props" v-model="model">
<slot />
</o-radio>
</template>
<script lang="ts">
import { defineComponent } from "#vue/runtime-core";
import Radio from '../mixins/radio-mixins';
export default defineComponent({
name: "BaseRadio",
computed: {
model: {
get() {
return this.$props.nativeValue;
},
set(value: any) {
this.$emit("input", value);
},
},
},
emits: ["input"],
props: {
...Radio.props,
},
});
</script>
<style>
.b-radio.radio .check:before {
background : #A2A9AD;
}
.b-radio.radio .check:checked {
border-color: #A2A9AD;
}
</style>
I want to apply the two changes present in style tags during radio is disabled. How can i achieve that ?.
I want to check if the radio button is disabled and apply the styles when it is disabled.

Use the class prop .o-radio--disabled :
.b-radio.radio .o-radio--disabled {
...
}

Related

Vue 3 pass data in <slot>

What I am trying to achieve:
Display an image from dynamic link in Post.vue, which follows the layout of PostLayout.vue
In PostLayout.vue, I have a <slot> named postFeaturedImage, and inside the slot, there is a <div>, I want to use the image as the background of it.
What I am using:
Laravel, InertiaJS, Vue 3
My codes are:
Post.vue:
<template>
<PostLayout>
<template #postfeaturedImage>
<!-- Here I want to display the image -->
</template>
</PostLayout>
</template>
<script>
import PostLayout from '#/Layouts/PostLayout'
export default {
data() {
return {
featured_image: ''
}
},
components: {
PostLayout,
},
props: {
post: Object /* Passed the prop from Controller */
},
mounted () {
this.featured_image = this.post.featured_image
}
}
</script>
PostLayout.vue:
<template>
<slot name="postfeaturedImage" :bgImage="bgImage">
<div :style="`background-image:url(${bgImage}); height: 75vh;`"></div>
</slot>
</template>
<script>
export default {
}
</script>
I've removed all irrelevant codes. I am a beginner in Vue 3 and Inertia and in need of help!
An alternative approach will be creating a FeaturedImage component. Also, you can reference the post image directly from the props you receiving. There's no need for the data method and the mounted in this case.
<template>
<PostLayout>
<template #postfeaturedImage>
<FeaturedImage :src="post.featured_image" />
</template>
</PostLayout>
</template>
<script>
import PostLayout from '#/Layouts/PostLayout'
import FeaturedImage from '#/Layouts/FeaturedImage'
export default {
components: {
PostLayout,
FeaturedImage
},
props: {
post: Object
}
}
</script>
Add a props to your PostLayout.vue
<script>
export default {
props: {
bgImage: { type: String },
},
};
</script>
And give a value to that props in your Post.vue
<template>
<PostLayout :bgImage="featured_image"> </PostLayout>
</template>
And if you ever want to have a post without an image and a different layout you should do :
<template>
<PostLayout>
<template #postfeaturedImage> post without background image</template>
</PostLayout>
</template>

How to 2-way bind props with local data of a component in Vue 3?

Can anyone tell me how I can bind the prop of a component to a data property of its own? For example, consider I have a component called ModalComponent
<template> // ModalComponent.vue
<div v-if="showModal">
...
<button #click="showModal = !showModal">close the modal internally</button>
</div>
</template>
<script>
export default {
props: {
show: {
type: Boolean,
default: false
},
},
data() {
return {
showModal: false,
}
}
}
</script>
<style>
</style>
Now consider I am using this modal as a reusable component from inside a parent component using an external button to open up the pop up for the modal.
<template>
<button #click="showChild = !showChild">click to open modal</button>
<ModalComponent :show="showChild" />
</template>
<script>
export default {
components: {ModalComponent},
data() {
return {
showChild: false,
}
}
}
</script>
<style>
</style>
How do I make it so that every time the parent clicks on the button, the modal pops up by binding the local showModal to the prop show ? And when the modal is closed internally by the local close button, if I click on the parent button again it will re-pop up? (I am using Vue 3, just in case)
Any help would be appreciated. Thanks.
The perfect solution for this case is using v-model instead of passing a prop :
in child component define modelValue as prop and emit its value to the parent using $emit function:
<template> // ModalComponent.vue
<div v-if="modelValue">
...
<button #click="$emit('update:modelValue',!modelValue)">close the modal internally</button>
</div>
</template>
<script>
export default {
props: {
modelValue: {
type: Boolean,
default: false
},
},
emits: ['update:modelValue'],
}
</script>
in parent component just use v-model to bind the value :
<template>
<button #click="showChild = !showChild">click to open modal</button>
<ModalComponent v-model="showChild" />
</template>
<script>
export default {
components: {ModalComponent},
data() {
return {
showChild: false,
}
}
}
</script>

How can a Vue component button color be changed using a function?

How can a Vue component button color be changed using a function? Bootstrap-vue is being used. In the code below, the tooltip is changed using a function, how can the same idea be applied to the button? Any help would be greatly appreciated.
Here is the Vue component:
<template>
<div class="text-center">
<b-button v-b-tooltip.hover.right="tooltipText" variant="outline-primary" #click="userHandler(username)">
<div v-bind:class="{ active: checkbox1 }">
{{ username }}
</div>
</b-button>
</div>
</template>
<script>
import EventBus from '../eventBus.js'
export default {
props: ['username', 'checkbox1'],
data() {
return {
show: true,
tooltipTextContent: 'block',
}
},
methods: {
userHandler(username) {
EventBus.$emit('handleUser', username);
},
tooltipText() {
if (!this.checkbox1) {
return this.tooltipTextContent
} else {
return `un${this.tooltipTextContent}`
}
}
},
}
</script>
<style scoped>
.active {
color: red;
}
</style>
Using Object Syntax
If you want to change the colour of the button based on checkbox1 prop, you can do this like:
<b-button
v-b-tooltip.hover.right="tooltipText"
:variant="{ 'outline-primary': checkbox1, 'outline-secondary': !checkbox1 }"
#click="userHandler(username)">
This will set button colour to outline-primary if checkbox1 is true, else set it to outline-secondary colour. You can change the colour and logic based on your requirement.
Also, note that here :variant is simply a shortcut for v-bind:variant.
Using Computed Property
We can also bind to a computed property that returns an object. This is a common and powerful pattern:
<b-button
v-b-tooltip.hover.right="tooltipText"
:variant="getVariant"
#click="userHandler(username)">
and then create a computed property named getVariant like:
computed: {
getVariant: function () {
return {
'outline-primary': this.checkbox1,
'outline-secondary': !this.checkbox1
}
}
}

Vuejs change prop value in component after select option component

I have 2 components, one creates an Editor using vue2-ace-editor, the other component is a select Option component. I Need to Change the theme of the Editor if I select another value in my select Option, so far my Editor component Looks like this:
<template>
<editor v-model="content" #init="editorInit" lang="javascript" theme="monokai"></editor> <!-- the default theme is monokai currently -->
</template>
<script>
export default {
props: [],
data () {
return {
language: 'javascript',
content: 'test',
}
},
components: {
editor: require('vue2-ace-editor'),
},
methods: {
editorInit () {
require('brace/ext/language_tools');
require('brace/mode/html');
require('brace/mode/javascript');
require('brace/mode/less');
require('brace/theme/clouds_midnight');
require('brace/theme/chrome');
require('brace/theme/ambiance');
}
},
}
</script>
And my select Option Looks like this:
<template>
<div>
<v-select
:items="themes"
v-model="themeSelection"
label="Select"
single-line
></v-select>
</div>
</template>
<script>
export default {
data () {
return {
themeSelection: null,
themes: [
{ text: 'ambiance' },
{ text: 'chrome' },
{ text: 'clouds_midnight' },
]
}
}
}
</script>
So basically if I select a different Option, I Need to Change the theme of the Editor, how do I manage this?

Change variable in component using vue.js

I have navbar blade, component with text and another components with page.
It works like I have component with text in navbar, and another component after navbar. That's three another components. How to change text from for example index.vue in text.vue?
That's what I have:
Text.vue:
<template>
<p class="title">{{msg}}</p>
</template>
<script>
export default {
props: [
'msg',
],
data() {
return {
}
},
mounted() {
},
methods: {
}
}
</script>
Component in navbar.blade.php:
<navbar-title></navbar-title>
And I try to change it in index.vue, that should work when we are on this page:
data() {
return {
msg: 'text',
}
But it doesn't work. How to do it correctly?
EDIT:
Vue.component('title', require('./components/Title.vue'));
To pass the message variable from your index.vue through navbar.vue to title.vue each needs to pass the property to the child and each child must pass the property on again all throughout the tree.
Something like this should work for your case: <title :msg="msg"></title>

Categories