Getting different - vue.js

I have a problem related to Vue.js probs (I guess). I have a chart which fetches data in the created() from an API which looks like this:
<template>
<div>
<highcharts if="data.length > 0" :options="chartOptions" ></highcharts>
</div>
</template>
<script>
import { Chart } from "highcharts-vue";
import Highcharts from "highcharts";
import exportingInit from "highcharts/modules/exporting";
exportingInit(Highcharts);
export default {
props: {
partsdata: {
type: Array
}
},
created() {
this.$http.get('http://127.0.0.1:5000/data/')
.then(response => {
var result = JSON.parse(response.data)
return result
}).then(data => {
var result = data.Fare
console.log(result) // eslint-disable-line no-console
this.chartOptions.series[0].data = [] // Array wieder zurücksetzen
for(var key in result) {
this.chartOptions.series[0].data.push(result[key]) // eslint-disable-line no-console
}
})
},
components: {
highcharts: Chart
},
data() {
return {
data: [],
chartOptions: {
title: {
text: 'Title aligned left',
align: 'left',
x: 0
},
series: [{
type: "column",
data: [] // sample data
}]
}
}
}
};
</script>
<style scoped>
.btn-primary {
padding: 10px 20px;
background: white;
color: black;
margin-top: 15px;
margin-bottom: 15px;
border-radius: 5px;
}
</style>
This is my parent component, where I use my Charts, which works fine.
<template>
<v-container grid-list-md text-xs-center>
<v-layout row wrap>
<v-flex xs6>
<v-card dark color="white">
<v-card-text class="px-0">
<Highcharts></Highcharts>
</v-card-text>
</v-card>
</v-flex>
<v-flex xs6>
<v-card dark color="white">
<v-card-text class="px-0">
<Highcharts></Highcharts>
</v-card-text>
</v-card>
</v-flex>
<v-flex xs6>
<v-card dark color="white">
<v-card-text class="px-0">
<Highcharts></Highcharts>
</v-card-text>
</v-card>
</v-flex>
<v-flex xs6>
<v-card dark color="white">
<v-card-text class="px-0">
<Highcharts></Highcharts>
</v-card-text>
</v-card>
</v-flex>
</v-layout>
</v-container>
</template>
<script>
import Highcharts from "./Header.vue"
export default {
components: {
Highcharts: Highcharts
}
}
</script>
<style scoped>
</style>
However, what I want is to fetch the data from different Endpoints without creating a ton of new components. Is there a way to use the created() lifecycle hook as props or are there any other clever solutions how to archieve this?

Related

How do I capture the value of the prop in the text field?

I have a prop and currently am able to get the data of the prop, Am trying a way to capture the item of the prop when saving the form.
Is there a way where i can take the value and pass if in a hidden text-area and bind the data to the vmodel?
Any help I appreciate.
<v-dialog v-model="dialog" persistent max-width="800">
<template v-slot:activator="{ on }">
<v-btn dark v-on="on" color="primary" round> Make payment </v-btn>
</template>
<v-card>
<v-card-title class="headline primary">
<span class="white--text">Add a new Doctor Payment Record {{ queueId }}</span>
<v-btn icon dark #click.native="dialog = false" absolute right>
<v-icon>mdi-close</v-icon>
</v-btn>
</v-card-title>
<v-card-text>
<users-search
:leave-selected="true"
idOnly
label="Select Doctor"
#results="setDoctor"
>
</users-search>
<div class="row px-3">
<v-autocomplete
class="px-3 col-sm-8"
v-model="expense.bank"
v-if="banks.data"
:items="banks.data"
outline
chips
label="Select bank"
item-text="name"
item-value="id"
>
</v-autocomplete>
<v-text-field
class="px-3 col-sm-8"
outline
flat
v-model="expense.amount"
type="number"
#input="expense.percentage()"
required
label="Amount *"
persistent-hint
/>
</div>
<v-text-field
class="px-3"
outline
flat
v-model="expense.total_paid"
required
label="amount paid"
persistent-hint
/>
<v-text-field
class="px-3"
outline
flat
:value="setQueue"
v-model="expense.queueId"
required
:label=queueId
persistent-hint
/>
<v-alert :value="true" type="error" v-if="errors.any()">
<div v-html="errors.display()"></div>
</v-alert>
<v-layout row wrap>
<v-flex xs12>
<v-btn
color="success"
:loading="saveLoader"
#click="recordExpense()"
>save</v-btn
>
</v-flex>
</v-layout>
</v-card-text>
</v-card>
</v-dialog>
</template>
<script>
import NewUser from "#finance/libs/users/NewUser";
import {mapActions, mapGetters} from "vuex";
export default {
props: [
'queueId'
],
data: () => ({
dialog: false,
expense: new NewUser(),
saveLoader: false,
}),
computed: {
...mapGetters({
banks: "getBanks",
}),
balance: function () {
return parseFloat(10);
},
submitted() {
return this.expense.form.submitted;
},
contaminated() {
return this.expense.form.errorDetected;
},
errors() {
return this.expense.form.errors;
},
},
watch: {
submitted(v) {
if (v) {
this.saveLoader = false;
}
},
contaminated() {
this.saveLoader = false;
},
},
methods: {
...mapActions({
fetchBanks: "setBanks",
}),
setDoctor(user) {
this.expense.doctor_id = user.id;
},
setQueue(){
console.log(this.queueId);
this.expense.queueId = this.queueId;
},
async recordExpense() {
this.saveLoader = true;
let response = await this.expense.saveExpense();
this.saveLoader = false;
if (response) {
this.dialog = false;
this.$emit("expenseCreated");
}
},
},
mounted() {
this.fetchBanks();
}
};
</script>
The prop queueId i also want to store it along with the user information from the form.
Try this one, it should work:
<template>
<textarea v-model="hiddenValue" :style="{ display: 'none' }"></textarea>
</template>
<script>
export default {
props: [ 'queueId' ],
data() {
return {
hiddenValue: this.queueId
}
}
}
</script>
In case you will no need the prop to be modified, please bind the texarea value to the prop directly:
<textarea hidden v-model="queueId" :style="{ display: 'none' }></textarea>

How to debug outline is not working in Vuetify?

I started a fresh vue3 project with vuetify3 via vue cli.
$ vue create playground-vuelidate
$ cd playground-vuelidate
$ code .
$ vue add vuetify
$ npm run serve
FormInput.vue
<template>
<v-form>
<v-container>
<v-row no-gutters>
<v-col cols="12" sm="12">
<v-combobox :items="select1" label="Select1" chips></v-combobox>
</v-col>
<v-col cols="12" sm="12">
<v-text-field
outline
v-model="input1"
:rules="rules"
label="Input1"
></v-text-field>
</v-col>
<v-col cols="12" sm="12">
<v-text-field
outline
v-model="input2"
:rules="rules"
label="Input2"
></v-text-field>
</v-col>
<v-col cols="12" sm="12">
<v-text-field outline v-model="input3" label="Input3"></v-text-field>
<v-textarea
v-model="v$.textarea1.$model"
:class="status(v$.textarea1)"
label="textarea1"
></v-textarea>
<pre>{{ $v }}</pre>
</v-col>
</v-row>
</v-container>
</v-form>
</template>
<script>
import { maxLength, required } from "#vuelidate/validators";
import { useVuelidate } from "#vuelidate/core";
export default {
name: "UsersPage",
data: () => ({
select1: ["Foo", "Bar", "Fizz", "Buzz"],
input1: "",
input2: "222",
input3: "333",
textarea1: "12345678910",
rules: [
(value) => !!value || "Required.",
(value) => (value || "").length <= 20 || "Max 20 characters",
],
}),
setup: () => ({ v$: useVuelidate() }),
validations() {
return {
textarea1: {
required,
minlength: maxLength(20),
},
};
},
methods: {
status(validation) {
return {
error: validation.$error,
dirty: validation.$dirty,
};
},
},
};
</script>
<style>
input {
border: 1px solid silver;
border-radius: 4px;
background: white;
padding: 5px 10px;
}
.dirty {
border-color: #5a5;
background: #efe;
}
.dirty:focus {
outline-color: #8e8;
}
.error {
border-color: red;
background: #fdd;
}
.error:focus {
outline-color: #f99;
}
</style>
App.vue
<template>
<v-card class="mx-auto" max-width="1000">
<FormInput />
<v-card-actions>
<v-btn text color="gray accent-4"> Cancel </v-btn>
<v-btn color="primary"> Submit </v-btn>
</v-card-actions>
</v-card>
</template>
<script>
import FormInput from "./components/FormInput.vue";
export default {
name: "App",
components: {
FormInput,
},
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
It yields this result
It supposes to look like this.
Official Doc
Notes
I have a select, inputs, and textarea all 3 of them the outline CSS doesn't seem to work or applied. Is it a known Vuetify bug ?
Should be
<v-text-field
outlined
></v-text-field>
not
<v-text-field
outline
></v-text-field>
This is based from vuetify for vue3
https://next.vuetifyjs.com/en/components/text-fields/

vue clicking on the action button's focus area breaks it

I'm trying to create a floating action button by using vuetify -vspeed dial. I created a logic to style my button whenever it's clicked and it's working perfect, it collapses and expands whenever i click on it. However, if i try to click the focus area of the action buttons, it breaks it and close the buttons. How can i prevent that? When I click on button, it's fine - I use click.stop to make it persistent but if i click to the area right next to button, it closes the buttons which breaks my logic for styling. Here's my code
Test.Vue
<template>
<v-card :class="{create: backgroundColor }">
<v-speed-dial
:bottom="true"
:right="true"
:direction="direction"
:transition="transition"
fixed
>
<template v-slot:activator>
<v-btn
:class="{is_active:isActive}"
color="#C6002B"
fab
dark
#click=toggleButton
x-large
>
<v-icon>{{isActive? 'mdi-close' : 'mdi-account-circle'}}</v-icon><span>{{isActive ? "EXPANDED" : ''}}</span>
</v-btn>
</template>
<v-btn
v-if="finalProp"
:class="{alignLeft:isActive}"
fab
dark
large
#click.stop="$emit('func1')"
color="white" >
<v-icon color="#F0BE85">mdi-pencil</v-icon>
</v-btn>
<v-btn
v-if="thirdProp"
:class="{alignLeft:isActive}"
fab
dark
large
#click.stop="$emit('func2')"
color="white">
>
<v-icon color="purple">mdi-delete</v-icon>
</v-btn>
<v-btn
:class="{alignLeft:isActive}"
v-if="secondProp"
fab
dark
large
#click.stop="$emit('func3')"
color="white">
>
<v-icon color="green">mdi-plus</v-icon>
</v-btn>
<v-btn
v-if="firstProp"
:class="{alignLeft:isActive}"
fab
dark
large
#click.stop="$emit('func4')"
color="white">
>
<v-icon color="red">home</v-icon>
</v-btn>
</v-speed-dial>
</v-card>
</template>
<script>
export default {
name: 'FloatingButton',
props: {
firstProp: Boolean,
secondProp: Boolean,
thirdProp: Boolean,
finalProp: Boolean
},
data: () => ({
direction: 'top',
fab: false,
right: true,
bottom: true,
transition: 'scale-transition',
isActive: false,
backgroundColor: false,
check:true
}),
methods: {
toggleButton:function() {
this.isActive = !this.isActive
this.backgroundColor = !this.backgroundColor
}
},
}
</script>
<style scoped>
.is_active {
min-width:120px
/* width: 380px;
height: 70px;
border-radius: 36px;
margin:5px; */
}
.is_active span {
font-size: 18px;
letter-spacing: 0px;
}
.create {
min-width: 100%;
min-height: 100%;
position: fixed;
top: 0;
left: 0;
z-index: 4;
background:rgba(0,0,0,0.4);
color:rgba(0,0,0,0.8);
}
}
</style>
App. vue
<template>
<v-app>
<Test :firstProp=a :secondProp=b :thirdProp=c :lastProp=d />
</v-app>
</template>
<script>
import Test from './components/Test'
export default {
name: 'App',
components: {
Test
},
data(){
return{
a:true,
b:true,
c:true,
d:true
}
}
};
</script>
I don't see what's wrong. Can you check this reproduction? I mostly only changed the casing of attributes on <Test> element.
Vue.component('Test', {
template: `
<v-card :class="{create: backgroundColor }">
<v-speed-dial
:bottom="true"
:right="true"
:direction="direction"
:transition="transition"
fixed
>
<template v-slot:activator>
<v-btn
:class="{is_active:isActive}"
color="#C6002B"
fab
dark
#click="toggleButton"
x-large
>
<v-icon>{{isActive? 'mdi-close' : 'mdi-account-circle'}}</v-icon>
</v-btn>
</template>
<v-btn
v-if="finalProp"
:class="{alignLeft:isActive}"
fab
dark
large
#click.stop="$emit('func1')"
color="white" >
<v-icon color="#F0BE85">mdi-pencil</v-icon>
</v-btn>
<v-btn
v-if="thirdProp"
:class="{alignLeft:isActive}"
fab
dark
large
#click.stop="$emit('func2')"
color="white">
>
<v-icon color="purple">mdi-delete</v-icon>
</v-btn>
<v-btn
:class="{alignLeft:isActive}"
v-if="secondProp"
fab
dark
large
#click.stop="$emit('func3')"
color="white">
>
<v-icon color="green">mdi-plus</v-icon>
</v-btn>
<v-btn
v-if="firstProp"
:class="{alignLeft:isActive}"
fab
dark
large
#click.stop="$emit('func4')"
color="white">
>
<v-icon color="red">home</v-icon>
</v-btn>
</v-speed-dial>
</v-card>
`,
props: {
firstProp: Boolean,
secondProp: Boolean,
thirdProp: Boolean,
finalProp: Boolean
},
data: () => ({
direction: 'top',
fab: false,
right: true,
bottom: true,
transition: 'scale-transition',
isActive: false,
backgroundColor: false,
check:true
}),
methods: {
toggleButton: function() {
this.isActive = !this.isActive
this.backgroundColor = !this.backgroundColor
}
},
})
Vue.config.productionTip = false
new Vue({
el: '#app',
vuetify: new Vuetify(),
data(){
return{
a:true,
b:true,
c:true,
d:true
}
}
});
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<style scoped>
.is_active {
/*min-width:120px
width: 380px;
height: 70px;
border-radius: 36px;
margin:5px; */
}
.is_active span {
font-size: 18px;
letter-spacing: 0px;
}
.create {
min-width: 100%;
min-height: 100%;
position: fixed;
top: 0;
left: 0;
z-index: 4;
background:rgba(0,0,0,0.4);
color:rgba(0,0,0,0.8);
}
}
</style>
</head>
<body>
<div id="app">
<v-app>
<Test :first-prop="a" :second-prop="b" :third-prop="c" :last-prop="d" />
</v-app>
</div>
</body>
</html>

Render Component in loop, use Index in method of child component (VueJS)

I have two components where some exchange of props takes place. Props is the whole todo array, which is updated by a click on the button with the "addTodo" method. Passing the array down to the child works fine. I can display the props dynamically in my p-tags, but it seems to be not possible to use it my the methods of my child component.
<template>
<v-app>
<v-content>
<h2>Add a Todo</h2>
<v-col cols="12" sm="6" md="3">
<v-text-field label="Regular" v-model="text"></v-text-field>
</v-col>
<div class="my-3">
<v-btn medium #click="addTodo">Add Todo</v-btn>
</div>
<div v-for="(todo, index) in todos" v-bind:key="index">
<HelloWorld
v-bind:todos="todos"
v-bind:index="index"
v-bind:class="(todos[index].done)?'green':'red'"
/>
</div>
</v-content>
</v-app>
</template>
<script>
import HelloWorld from "./components/ToDo.vue";
export default {
components: {
HelloWorld
},
data: function() {
return {
text: "",
todos: []
};
},
methods: {
addTodo() {
this.todos.push({
text: this.text,
done: false
});
}
}
};
</script>
This is my child component
<template>
<v-card max-width="250">
<v-card-text>
<h2 class="text-center">{{todos[index].text}}</h2>
<p class="display-1 text--primary"></p>
<p>{{index}}</p>
</v-card-text>
<v-card-actions>
<v-btn text color="deep-purple accent-4" #click="done"></v-btn>
<v-btn text color="orange accent-4">Delete Task</v-btn>
</v-card-actions>
</v-card>
</template>
<script>
export default {
props: ["todos", "index"],
methods: {
done() {
this.todos[1].text = "bla";
}
}
};
</script>
<style scoped>
.seperator {
display: flex;
justify-content: space-between;
}
</style>
I pass a whole array with objects as props, and using the index inside the p-tag works fine, but I also want to use it like this:
methods: {
done() {
this.todos[index].text = "bla";
}
}
'index' is not defined
Everything works fine, but I am not able use the index value inside the method. What am I doing wrong here?
The way you write it out, there is nothing in scope defining index. Where is that value coming from?
Index is a prop and so it must be referenced with this.
done () {
this.todos[this.index].text = 'bla'
}

Using vuetify card like bootstrap cards columns

I need a way to use list of v-card from Vuetify like Bootstrap Card Columns
Possible solution:
Pardon me, I couldn't plunkr the code :(
This is what I did.
Update: Unfortunately this messes up with the v-ripple directive
<template>
<v-container grid-list-md>
<div class="v-card-columns">
<v-card tile v-for="post in posts" :key="post.id">
<v-card-title primary-title>
<h3 headline>
{{post.title}}
</h3>
</v-card-title>
<v-card-text>
{{post.body}}
</v-card-text>
</v-card>
</div>
</v-container>
</template>
<script>
import axios from "axios";
export default {
name: "All",
data() {
return {
posts: []
}
},
mounted() {
axios
.get('https://jsonplaceholder.typicode.com/posts')
.then(res => {
this.posts = res.data
})
}
}
</script>
<style scoped>
.v-card-columns .v-card {
margin-bottom: 0.75rem;
}
#media (min-width: 576px) {
.v-card-columns {
-webkit-column-count: 3;
-moz-column-count: 3;
column-count: 3;
-webkit-column-gap: 1.25rem;
-moz-column-gap: 1.25rem;
column-gap: 1.25rem;
orphans: 1;
widows: 1;
}
.v-card-columns .v-card {
display: inline-block;
width: 100%;
}
}
</style>
Pardon me, I couldn't plunkr the code :(
This is what I did.
Update: Unfortunately this messes up with the v-ripple directive
<template>
<v-container grid-list-md>
<div class="v-card-columns">
<v-card tile v-for="post in posts" :key="post.id">
<v-card-title primary-title>
<h3 headline>
{{post.title}}
</h3>
</v-card-title>
<v-card-text>
{{post.body}}
</v-card-text>
</v-card>
</div>
</v-container>
</template>
<script>
import axios from "axios";
export default {
name: "All",
data() {
return {
posts: []
}
},
mounted() {
axios
.get('https://jsonplaceholder.typicode.com/posts')
.then(res => {
this.posts = res.data
})
}
}
</script>
<style scoped>
.v-card-columns .v-card {
margin-bottom: 0.75rem;
}
#media (min-width: 576px) {
.v-card-columns {
-webkit-column-count: 3;
-moz-column-count: 3;
column-count: 3;
-webkit-column-gap: 1.25rem;
-moz-column-gap: 1.25rem;
column-gap: 1.25rem;
orphans: 1;
widows: 1;
}
.v-card-columns .v-card {
display: inline-block;
width: 100%;
}
}
</style>