Nuxt component variable not updated - vue.js

I wrote the following code for my navbar:
<template>
<div>
<div v-if="!$auth.loggedIn" data-tip="Login" class="tooltip tooltip-bottom">
<nuxt-link to="/login" class="btn btn-square btn-ghost">
<solid-login-icon class="w-6 h-6" />
</nuxt-link>
</div>
<div v-else class="flex items-stretch">
<a class="pr-2 btn btn-ghost rounded-btn"> Welcome, {{ this.$auth.user.username }}! 👋 </a>
<div data-tip="Logout" class="tooltip tooltip-bottom">
<button class="pr-2 btn btn-square btn-ghost" #click="logout()">
<solid-login-icon class="w-6 h-6" />
</button>
</div>
</div>
</div>
</template>
Which is include in the following login page:
<template>
<div class="h-screen shadow bg-base-200 drawer drawer-mobile">
<input id="my-drawer-2" type="checkbox" class="drawer-toggle" />
<div class="drawer-content">
<NavBar />
<div class="grid grid-cols-1 p-5 md:grid-cols-6">
<div class="col-span-1 md:col-span-2 md:col-start-3">
<div class="bg-white shadow card">
<div class="card-body">
<h2 class="text-left card-title">Login</h2>
<form #submit.prevent="userLogin">
<div class="form-control">
<label class="label">
<span class="label-text">Username</span>
</label>
<input
v-model="login.username"
type="text"
placeholder="Username"
class="input input-bordered"
/>
</div>
<div class="form-control">
<label class="label">
<span class="label-text">Username</span>
</label>
<input
v-model="login.password"
type="password"
placeholder="Password"
class="input input-bordered"
/>
</div>
<div class="mt-4">
<button type="submit" class="btn btn-primary btn-md">Login</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<SideBar />
</div>
</template>
<script>
export default {
data() {
return {
login: {
username: '',
password: '',
},
}
},
methods: {
async userLogin() {
try {
const response = await this.$auth.loginWith('local', { data: this.login })
} catch (err) {}
},
},
}
</script>
Upon loggin in with correct credentials the page keeps dispalying the "Login"-icon instead of the Welcome message.
I've tried to replace !$auth.loggedIn with loggedIn (coming from the data function) and with !this.$auth.loggedIn" but both don't seem to solve the issue

Related

laravel 9 vue 3 edit multiple checked checkbox value

when editing a checkbox array, I cannot select (checked) that are in the database
how to select those that exist in the checkbox database (checked) ?
please, help
Edit.vue
<template>
<div>
<admin-layout>
<template #header>
<div class="row">
<div class="col-md-12">
<h4>Емделуші</h4>
</div>
</div>
</template>
<div class="row">
<div class="col-md-12 mb-3">
<div class="card">
<div class="card-header">
<span><i class="bi bi-table me-2"></i></span> Емделушіні өзгерту
<div class="card-header-pills float-end">
<inertia-link :href="route('admin.schedules.index')" class="btn btn-primary text-white text-uppercase" style="letter-spacing: 0.1em;">
Кері қайту
</inertia-link>
</div>
</div>
<form #submit.prevent="updateSchedule">
<div class="card-body">
<div class="mb-3">
<label for="name" class="form-label">Аты-жөні</label>
<input type="text" class="form-control" id="name" v-model="form.name" :class="{'is-invalid' : form.errors.name }" autofocus="autofocus" autocomplete="off">
</div>
<div class="invalid-feedback mb-3" :class="{ 'd-block' : form.errors.name }">
{{ form.errors.name }}
</div>
<div class="mb-3">
<label class="form-label" for="email">Email</label>
<input type="text" class="form-control" id="email" v-model="form.email" :class="{'is-invalid' : form.errors.email }" autofocus="autofocus" autocomplete="off">
</div>
<div class="invalid-feedback mb-3" :class="{ 'd-block' : form.errors.email }">
{{ form.errors.email }}
</div>
<div class="mb-3">
<label class="form-label" for="phone">Телефон</label>
<input type="text" class="form-control" id="phone" v-model="form.phone" :class="{'is-invalid' : form.errors.phone }" autofocus="autofocus" autocomplete="off">
</div>
<div class="invalid-feedback mb-3" :class="{ 'd-block' : form.errors.phone }">
{{ form.errors.phone }}
</div>
<div class="form-check form-check-inline" v-for="(time, index) in times" :key="index">
<input class="form-check-input" type="checkbox" id="inlineCheckbox1" :value="time.time" v-model="form.times" :class="{'is-invalid' : form.errors.times }">
<label class="form-check-label" for="inlineCheckbox1">{{ time.time }}</label>
</div>
<div class="invalid-feedback mb-3" :class="{ 'd-block' : form.errors.times }">
{{ form.errors.times }}
</div>
</div>
<div class="card-footer clearfix">
<div class="float-end">
<jet-button class="ms-4 btn-primary text-white" :class="{ 'text-white-50': form.processing }" :disabled="form.processing">
<div v-show="form.processing" class="spinner-border spinner-border-sm" role="status">
<span class="visually-hidden">Өзгертілуде...</span>
</div>
Өзгерту
</jet-button>
</div>
</div>
</form>
</div>
</div>
</div>
</admin-layout>
</div>
</template>
<script>
import AdminLayout from '#/Layouts/AdminLayout';
import JetButton from '#/Jetstream/Button.vue'
import { useForm } from '#inertiajs/inertia-vue3';
import InertiaLink from "#inertiajs/inertia-vue3/src/link";
export default {
name: "Edit",
components: {
AdminLayout,
JetButton,
InertiaLink,
},
props: {
appointment: {},
times: {},
},
setup (props) {
const form = useForm({
name: props.appointment.name,
email: props.appointment.email,
phone: props.appointment.phone,
times: props.times,
});
return {
form,
}
},
methods: {
},
}
}
</script>
when editing a checkbox array, I cannot select (checked) that are in the database how to select those that exist in the checkbox database (checked) ? please, help

how to $emit in vuejs

VueJS emit doesn't work, I'm trying to change the value of a boolean, but it doesn't want to emit the change
here is the first component:
<template>
<div id="reg">
<div id="modal">
<edu></edu>
</div>
<div :plus="plus" v-if="plus" #open="plus = !plus">
abc
</div>
</div>
</template>
the script:
<script>
import edu from './education/edu.vue'
export default {
components: {
edu
},
data() {
return {
plus: false
}
}
}
</script>
the second component with the emit:
<template>
<div id="container">
<h2>Education</h2>
<form action="">
<input type="text" class="input" placeholder="preparatory/bachelor/engineering..">
<input type="text" class="input" placeholder="University..">
<input type="text" class="input" placeholder="Where?..">
<h6>Start date</h6>
<input type="date" class="input" value="2017-09-15" min="2017-09-15" max="2021-09-15">
<div class="end-date">
<h6>End date</h6>
<div class="flexend">
<h6>present</h6><input type="checkbox" name="" id="checkbox" #click="checked">
</div>
</div>
<input type="date" class="input" v-if="show" value="2017-09-15" min="2017-09-15">
<div class="flex-end">
<button class="btn-plus" #click="$emit('open')"><i class="fas fa-plus"></i></button>
</div>
<div class="flex-end">
<button class="btn">next <i class="fas fa-arrow-right"></i></button>
</div>
</form>
</div>
</template>
the script:
<script>
export default {
props:{
plus: Boolean
},
data(){
return{
show: true,
}
},
I thought this is working, but it seems like it's not
You should use the component name instead of the div element :
<edu :plus="plus" v-if="plus" #open="plus = !plus">
abc
</edu>

Dynamically add items from input with show vuejs

there was a point where I got stuck while trying to make invoice transactions with vue js, I can add a new item, it works fine, the problem starts here, when I want to show the "description" and "discount_value" that I have hidden, it adds it to all lines, not like this, whichever index button is clicked. add his item. Thank you in advance for your help.
const app = new Vue({
el: '#app',
data: {
addAciklama: false,
addIndirim: false,
faturasections: [
{
name: "",
unit_price: 0,
net_total: 0,
description: '',
discount_value: '',
}
],
},
methods: {
addNewFaturaSatiri() {
this.faturasections.push({
name: "",
unit_price: 0,
net_total: 0,
description: '',
discount_value: '',
});
},
removeFaturaSatiri(faturasectionIndex) {
this.faturasections.splice(faturasectionIndex, 1);
},
}
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
<div id="app">
<section>
<div class="card-body border-bottom-light" v-for="(fatura, faturasectionIndex) in faturasections" :key="faturasectionIndex">
<div class="row">
<div class="col-sm-4 col-12 mb-1 mb-sm-0 hizmet">
<div class="form-floating">
<input type="text" class="form-control" v-model="fatura.name" placeholder=" "/>
<label>HİZMET / ÜRÜN</label>
</div>
</div>
<div class="col-sm-2 col-12 mb-1 mb-sm-0 brfiyati">
<div class="form-floating">
<input type="number" class="form-control" v-model.number="fatura.unit_price" placeholder=" "/>
<label>BR.FİYAT</label>
</div>
</div>
<div class="col-sm-1 col-12 mb-1 mb-sm-0 toplam">
<div class="form-floating">
<input type="text" class="form-control" v-model="fatura.net_total" placeholder=" "/>
<label>TOPLAM</label>
</div>
</div>
<div class="col-sm-1 col-12 mb-1 mb-sm-0">
<div class="mb-1">
<div class="mb-1">
<button v-if="!addAciklama" #click="addAciklama = !addAciklama" class="dropdown-item">description</button>
<button v-if="!addIndirim" #click="addIndirim = !addIndirim" class="dropdown-item">discount_value</button>
</div>
</div>
<button class="btn btn-icon btn-secondary" #click="removeFaturaSatiri(faturasectionIndex)">DELETE</button>
</div>
</div>
<div id="aciklamalar" class="row mt-1">
<div class="col-12 d-flex">
<div class="col-sm-6 fatura-aciklama">
<div class="row" v-if="addAciklama">
<div class="f-a">
<div class="input-group">
<span class="input-group-text kdv">AÇIKLAMA</span>
<input type="text" class="form-control" v-model="fatura.description"/>
</div>
</div>
<div class="f-b">
<button class="btn btn-icon btn-outline-secondary" #click="addAciklama = !addAciklama">DELETE</button>
</div>
</div>
</div>
<div class="col-sm-5">
<div class="d-flex flex-column">
<div class="row row mb-1" v-if="addIndirim">
<div class="i-i">
<div class="input-group">
<span class="input-group-text kdv">İNDİRİM</span>
<input type="text" class="form-control" v-model="fatura.discount_value"/>
</div>
</div>
<div class="i-s">
<button class="btn btn-icon btn-outline-secondary" #click="addIndirim = !addIndirim">DELETE</button>
</div>
</div>
</div>
</div>
</div>
</div>
<hr>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-2">
<button type="button" class="btn btn-outline-secondary btn-sm"
data-repeater-create #click="addNewFaturaSatiri()">
<span class="align-middle">NEW INVOICE</span>
</button>
</div>
</div>
</div>
</section>
</div>
addAciklama and addIndirim are global variable which is defined in data property and it's obvious that if you change them, it applies to every iteration of your v-for block and not apply for each index separately.
In order to fix this, you can move addAciklama and addIndirim into each object in faturasections:
faturasections: [{
name: "",
unit_price: 0,
net_total: 0,
description: '',
discount_value: '',
addIndirim: false,
addAciklama: false,
}],
Then in your template section code, you should replace all addIndirim and addAciklama to fatura.addIndirim and fatura.addAciklama. this will fix your issue.

VUEJS: Model not changing in for loop

The V-model:"question.answer" is the same for each loop.
The content of rating_questions is:
rating_question = [
{
"id":1,
"question":"How did you like this?",
"amount_of_stars":8,
"answer":0
},
{
"id":2,
"question":"Second question?",
"amount_of_stars":3,
"answer":0
}]
When I select an answer for the first question, the answer is saved in rating_question[0].answer but if I select an answer for the second question, it is also saved in rating_question[0].answer and not in rating_questions[1].answer as I would expect.
<template>
<div class="ratings">
<div class="rating" v-for="(question, index) in rating_questions">
<div class="question">
{{ question.question }}
</div>
<div class="answer">
<div class="rating-stars">
<span v-for="i in question.amount_of_stars">
<input :id="i" name="rating" v-model="question.answer" type="radio" :value="i" class="radio-btn hide" />
<label :for="i" >☆</label>
</span>
{{ rating_questions[index]['answer'] }}
{{index}}
<div class="clear"></div>
</div>
</div>
</div>
<span class="input-group-btn">
<button class="btn btn-primary btn-sm" id="btn-chat" #click="sendRating">
Send
</button>
</span>
</div>
</template>
<script>
export default {
props: ['user', 'event', 'rating_questions'],
methods: {
sendRating() {
this.$emit('ratingsent', {
rating_questions: this.rating_questions
});
}
}
}
</script>
Your problem is not in Vue usage but how you use <input> and <label> HTML elements...
<input> id and <label> for attributes are assigned with simple number
1..question.amount_of_stars...which means first combo for every question will have id = 1, second 2 etc. Moreover you are using same name for every combo!
Now if you click on the label (star) in second question, browser just switch active combo on 1st question.
Try this:
<input :id="`rating-${question.id}-${i}`" :name="`rating-${question.id}`" v-model="question.answer" type="radio" :value="i" class="radio-btn hide" />
<label :for="`rating-${question.id}-${i}`" >☆</label>
Now:
every combo in the group (single question) will have same name (OK!)
every combo (and it's corresponding label) will have different id (OK!)
Also it's usually better to use :key together with v-for
new Vue({
data() {
return {
rating_questions: [
{
"id":1,
"question":"How did you like this?",
"amount_of_stars":8,
"answer":0
},
{
"id":2,
"question":"Second question?",
"amount_of_stars":3,
"answer":0
}]
}
}
}).$mount("#app")
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="ratings">
<div class="rating" v-for="(question, index) in rating_questions" :key="question.id">
<div class="question">
{{ question.question }}
</div>
<div class="answer">
<div class="rating-stars">
<span v-for="i in question.amount_of_stars">
<input :id="`rating-${question.id}-${i}`" :name="`rating-${question.id}`" v-model="question.answer" type="radio" :value="i" class="radio-btn hide" />
<label :for="`rating-${question.id}-${i}`" >☆</label>
</span>
{{ question.answer }}
<div class="clear"></div>
</div>
</div>
</div>
</div>
</div>
The error was in my input id's...
Each new question had the same id's.
<template>
<div class="ratings">
<div class="rating" v-for="(question, index) in rating_questions">
<div class="question">
{{ question.question }}
</div>
<div class="answer">
<div class="rating-stars">
<span v-for="i in question.amount_of_stars">
<input :id="'rating' + index + i" name="rating" v-model="question.answer" type="radio" :value="i" class="radio-btn hide" />
<label :for="'rating' + index + i" >☆</label>
</span>
<div class="clear"></div>
</div>
</div>
</div>
<span class="input-group-btn">
<button class="btn btn-primary btn-sm" id="btn-chat" #click="sendRating">
Send
</button>
</span>
</div>
</template>
<script>
export default {
props: ['user', 'event', 'rating_questions'],
methods: {
sendRating() {
this.$emit('ratingsent', {
rating_questions: this.rating_questions
});
}
}
}
</script>
There is very trivial fix of this problem.
See you are modifying the props. In vuejs, props are not supposed to be updated. I hope you might have encountered some error in the console (not sure though, as sometimes in my case also it doesn't appear)
Please use this SFC file
<template>
<div class="ratings">
<!-- using the data variable rather than props -->
<div class="rating" v-for="(question, index) in questions" :key="index">
<div class="question">
{{ question.question }}
</div>
<div class="answer">
<div class="rating-stars">
<span v-for="i in question.amount_of_stars" :key="i">
<input
:id="i"
name="rating"
v-model="question.answer"
type="radio"
:value="i"
class="radio-btn hide"
/>
<label :for="i">☆</label>
</span>
{{ questions[index]["answer"] }}
{{ index }}
<div class="clear"></div>
</div>
</div>
</div>
<span class="input-group-btn">
<button class="btn btn-primary btn-sm" id="btn-chat" #click="sendRating">
Send
</button>
</span>
</div>
</template>
<script>
export default {
props: ["user", "event", "rating_questions"],
data() {
return {
questions: this.rating_questions, // because you can not change props in vuejs
};
},
methods: {
sendRating() {
this.$emit("ratingsent", {
rating_questions: this.questions,
});
},
},
};
</script>

VueJS reusable component not updated data for second component

I am trying to create one component in VueJS and need to reuse that component.
below is code for me.
Vue.component("radio" , {
props: ['selectGender'],
data: function() {
return{
selected: 1
}
},
template : `
<div class="modal fade" :id="compId" style="background: rgb(0, 0, 0, 0.8);">
<div class="modal-dialog default-font" style="top: 30%;">
<div class="modal-content center">
<div class="modal-header base-bg center">
<div class="center">
<span class="validationHeadSpan">Select Gender</span><br/>
</div>
<button type="button" class="close modal-close" data-dismiss="modal" style="font-size:3rem">×</button>
</div>
<div class="modal-body t-left" id="printArea">
<div class="container">
<div class="row" style="padding: 0rem 1rem;">
<div class="col">
<div class="custom-control custom-radio" style="margin: 1rem 0rem;">
<input class="custom-control-input" type="radio" id="rdbMale" value="0" checked v-model="selected"/>
<label class="custom-control-label" for="rdbMale">
<div class="addr_header_1" style="margin-top: 0.8rem;">Male</div>
</label>
</div>
</div>
<div class="col">
<div class="custom-control custom-radio" style="margin: 1rem 0rem;">
<input class="custom-control-input" type="radio" id="rdbFemale" value="0" checked v-model="selected"/>
<label class="custom-control-label" for="rdbFemale">
<div class="addr_header_1" style="margin-top: 0.8rem;">Female</div>
</label>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer center">
<button type="button" class="button" data-dismiss="modal" v-on:click="selectGender(selected)"><span class="validationButtonContent">Select</span></button>
</div>
</div>
</div>
</div>
`,
mounted : function(){
},
methods : {
}
});
Here is my another component from where i am opening reusable component.
Vue.component("Component1" , {
data: function() {
return{
selected: 1
}
},
template : `
<div>
<radio ref="returnOpenFirst" :selectGender="selectGenderFirst"></radio>
<radio ref="returnOpenSecond" :selectGender="selectGenderSecond"></radio>
</div>
<div class="btn btn-primary formButton" v-on:click="openFirst">
<span>Open First</span>
</div>
<div class="btn btn-primary formButton" v-on:click="openSecond">
<span>Open First</span>
</div>
`,
mounted : function(){
},
methods : {
openFirst:function(){
jQuery(self.$refs.returnOpenFirst.$el).modal({
'backdrop' : false
}).modal('show');
},
openSecond:function(){
jQuery(self.$refs.returnOpenSecond.$el).modal({
'backdrop' : false
}).modal('show');
},
selectGenderFirst:function(gender){
console.log("First Gender", gender);
},
selectGenderSecond:function(gender){
console.log("Second Gender", gender);
},
}
});
While opening second component, data property is updated of first component only not for second component.
Any help is highly appreciated.
Thanks in advance.
Here i found solution.
Vue.component("radio" , {
props: ['selectGender','type'],
data: function() {
return{
selected: 1
}
},
template : `
<div class="modal fade" :id="compId" style="background: rgb(0, 0, 0, 0.8);">
<div class="modal-dialog default-font" style="top: 30%;">
<div class="modal-content center">
<div class="modal-header base-bg center">
<div class="center">
<span class="validationHeadSpan">Select Gender</span><br/>
</div>
<button type="button" class="close modal-close" data-dismiss="modal" style="font-size:3rem">×</button>
</div>
<div class="modal-body t-left" id="printArea">
<div class="container">
<div class="row" style="padding: 0rem 1rem;">
<div class="col">
<div class="custom-control custom-radio" style="margin: 1rem 0rem;">
<input class="custom-control-input" type="radio" :id="'rdbMale'+type" value="0" checked v-model="selected"/>
<label class="custom-control-label" :for="'rdbMale'+type">
<div class="addr_header_1" style="margin-top: 0.8rem;">Male</div>
</label>
</div>
</div>
<div class="col">
<div class="custom-control custom-radio" style="margin: 1rem 0rem;">
<input class="custom-control-input" type="radio" :id="'rdbFemale'+type" value="0" checked v-model="selected"/>
<label class="custom-control-label" :for="'rdbFemale'+type">
<div class="addr_header_1" style="margin-top: 0.8rem;">Female</div>
</label>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer center">
<button type="button" class="button" data-dismiss="modal" v-on:click="selectGender(selected)"><span class="validationButtonContent">Select</span></button>
</div>
</div>
</div>
</div>
`,
mounted : function(){
},
methods : {
}
});
Issue with same id created by VueJs, we need to pass one dynamic property and with the use of that we need to create id for radio.
Thank you guys.