How to change element hint dynamically with Vuetify 3? - javascript

This is my component.vue:
<template>
<v-text-field
name="Foo"
:label="$t('foo')"
type="text"
hint="This is a hint"
persistent-hint
></v-text-field>
<v-btn color="primary" #click="onButtonClick()">Press</v-btn>
</template>
And this is component.ts
import { defineComponent, reactive, ref, Ref} from 'vue';
export default defineComponent({
setup() {
function onButtonClick() {
}
return { onButtonClick }
}
});
I want to change hint on button click, for example to This is a new hint. Could anyone say how to do in Vuetify 3 using Composition API?

Just create a ref property called hint inside the setup hook then bind it to the hint prop and update it when you click on the button:
import { defineComponent, reactive, ref, Ref} from 'vue';
export default defineComponent({
setup() {
const hint=ref('This is a hint')
function onButtonClick() {
hint.value="new hint"
}
return { onButtonClick, hint }
}
});
in template :
<template>
<v-text-field
name="Foo"
:label="$t('foo')"
type="text"
:hint="hint"
persistent-hint
></v-text-field>
<v-btn color="primary" #click="onButtonClick()">Press</v-btn>
</template>

Related

List isn't dynamically displayed in vue.js

I'm new to vue.js and learning on my own with the vue doc, youtube videos and such. I've been searching for a while and looking at youtube tutorials and haven't found an answer so far, hope you guys will be able to help me.
So here's my issue, I'm building a web app and I need to display a list of objects dynamically but it doesn't show the first time I'm loading that page. I have to go to some other route and come back to see it, so I guess I'm misunderstanding some life cycle or something from that field of expertise...
I'm using the vuex to store and retrieve my data as seen below :
import Vue from 'vue';
const state = {
journees: {},
};
const getters = {
getJourneeList(state) {
return state.journees;
}
};
const mutations = {
GET_LIST(state, journees) {
state.journees = journees;
}
};
const actions = {
getJourneesUser({commit}) {
Vue.axios.get('/journee/')
.then( res => {
commit('GET_LIST', res.data)
})
.catch((err) => console.log(err))
}
};
export default {
state,
getters,
mutations,
actions
};
And then I'm getting it in my vue like this:
<template>
<v-container>
<v-card v-for="heure in heures" :key="heure._id">
<v-card-title>{{ heure }}</v-card-title>
</v-card>
</v-container>
</template>
<script>
export default {
name: "TimeList",
data() {
return {
heures: this.$store.getters.getJourneeList,
}
},
created() {
this.$store.dispatch('getJourneesUser');
}
}
</script>
You need to use mapState and use it inside computed value because then computed value will response to change in state. You do not need getter but if you want here is the version with getter. It should be like this if your store module called journees:
without getter
<template>
<v-container>
<v-card v-for="heure in journees" :key="heure._id">
<v-card-title>{{ heure }}</v-card-title>
</v-card>
</v-container>
</template>
<script>
import { mapState } from "vuex";
export default {
name: "TimeList",
computed: {
...mapState(["journees"])
},
created() {
this.$store.dispatch("getJourneesUser");
},
};
</script>
with getter
<template>
<v-container>
<v-card v-for="heure in getJourneeList" :key="heure._id">
<v-card-title>{{ heure }}</v-card-title>
</v-card>
</v-container>
</template>
<script>
import { mapGetters } from "vuex";
export default {
name: "TimeList",
computed: {
...mapGetters(["getJourneeList"])
},
created() {
this.$store.dispatch("getJourneesUser");
},
};
</script>

How to respond to a promise resolved inside a Vue event handler

Given the following component
<template>
<div class="text-center">
<v-dialog
v-model="dialog"
width="500"
>
<template v-slot:activator="{ on, attrs }">
<v-btn
color="red lighten-2"
dark
v-bind="attrs"
v-on="on"
>
Click Me
</v-btn>
</template>
<v-card>
<v-card-title class="headline grey lighten-2">
Privacy Policy
</v-card-title>
<v-card-text>
Some text
</v-card-text>
<v-divider></v-divider>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="primary"
text
#click="handleAsyncAction"
>
I accept
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>
<script lang="ts">
import Vue from "vue";
import Component from "vue-class-component";
#Component()
export class MyDialog extends Vue {
dialog: booolean = false;
async handleAsyncAction() {
const value = await this.$emit('click'); // you can't really do that
if(value === 'x') {
dialog = false; //<--- then close
} else {
alert('error!')
}
}
}
</script>
Used by some parent like this:
<template>
<div>
<MyDialog #click="makeSomeAjaxRequest($event)"
</div>
</template>
<script type="ts">
import Vue from "vue";
import Component from "vue-class-component";
import MyDialog from "./MyDialog"
#Component({
components: { MyDialog }
})
export default class ParentComponent extends Vue {
async makeSomeAjaxRequest() {
const data = await fetch('http://example.com');
return data.toString();
}
}
</script>
Using React you'll be just able to pass some function from the parent and wrap the whole thing up, but from my understanding, this is not the Vue way of doing things.
How should I approach making the child component 'await' for the call to be back?
Vue stores all of the relevant event listeners inside the component under this.$listeners
By leveraging that, you'll be able to invoke the function without emitting an actual event:
// MyDialog
async handleAsyncAction() {
//#ts-ignore since Vue 2s' TS definitions condone such behavior
const value = await this.$listeners.click();
if(value === 'x') {
dialog = false; //<--- then close
} else {
alert('error!')
}
}
}
You can see a complete example in an article named Reacting to Promises from event listeners in Vue.js

Vue not able to call external function on button click

I'm currently learning Vue, Vuetify and other parts of the ecosystem
Now I'm trying to call a function defined in a different .js file when clicking a button. It's probably something stupid again, but errors keep being thrown.
Ladder.vue shows the buttons and binds the methods to them.
test.js contains an exported function that is called in previewSell
// Ladder.vue
<template>
<div class="ladder">
<v-container fluid>
<v-row align="start" justify="center">
<v-col align="right" sm="4">
<v-btn #click="previewBuy" color="#78b63f" width="125"
>Preview Buy<BR /> Entries</v-btn
>
</v-col>
<v-col align="center" sm="4">
<v-btn #click="resetForm" color="grey darken-2">reset</v-btn>
</v-col>
<v-col align="left" sm="4">
<v-btn #click="previewSell" color="#ba4967" width="125"
>Preview Sell<BR /> Entries</v-btn
>
</v-col>
</v-row>
</v-container>
</div>
</template>
<script>
import Test from "../components/test";
export default {
name: "Ladder",
components: {
},
methods: {
resetForm() {
this.$refs.form.reset();
},
previewBuy() {
console.log('This works')
},
previewSell() {
console.log(Test())
},
},
};
</script>
// test.js
const Test = () => {
return 'Test'
}
export {Test};
Below the error messages:
If you are exporting some variable without default param, you need to import it with {} for found it in file exports. If you`re using export default someFunc, u can use import without bracers
// test.js
export const Test = () => {
return 'Test'
}
import {Test} from "../components/test";
or
const Test = () => {
return 'Test'
}
export default Test
import Test from "../components/test";
// You can change the name of Test to anything else, it will work
Components { test },
is missing.
and
console.log(this.test())

how to send object to child component in Vue elementui

I am new to vue.
so here is my vue template
<template>
<div class="app-container">
<el-dialog :visible="dialogVisible"
title="View order"
:before-close="() => dialogVisible = false">
<order-form :oneorder="oneorderdata" #success="handleAdd" #cancel="dialogVisible = false" />
</el-dialog>
<el-table v-loading="loading" :data="orders" border>
<el-table-column prop="order.id" label="Id" />
<el-table-column prop="order.fullName" label="Full Name" />
<el-table-column prop="order.address.name" label="Address" />
<el-table-column prop="order.status" label="Status" />
<el-table-column label="View" prop="order.id" min-width="150">
<template slot-scope="{row}">
<el-col style="flex: 0">
<el-button icon="el-icon-plus" type="primary" #click="senddata(row.order)">
View Order
</el-button>
</el-col>
</template>
</el-table-column>
</el-table>
</div>
</template>
when i click the button the dialog is true so i call the order-form component
and i want to pass data to it. component is opening normally but error said that oneorderview is not found although i am showing it in console normally in senddata method.
i tried
v-bind:oneorder="oneorderview"
but it didn't work , it it shows no error.
thanks in advance.
this is my script
<script lang="ts">
import Vue from "vue";
import Component from "vue-class-component";
import { getOrders } from "#/api/store";
import dataStore from "#/store/modules/data";
import { OrderView } from "../../../models";
import { OrderInput } from "#/models";
import DataModule from "#/store/modules/data";
import OrderForm from "./form.vue";
type _OrderInput = OrderInput;
interface TableRowData {
editMode: boolean;
order: OrderView;
editedOrder: _OrderInput;
}
#Component({
components: {
OrderForm,
},
})
export default class Orders extends Vue {
orders: TableRowData[] = [];
oneorderview: any;
loading = false;
dialogVisible = false;
searchKey = "";
async created() {
await DataModule.ensureLoaded();
this.fetchData();
}
async fetchData() {
this.loading = true;
await dataStore.loadorders();
if (dataStore.orders.hasLoaded) {
this.orders = dataStore.orders.data.map(order => ({
editMode: false,
order,
editedOrder: { ...order }
}));
}
this.loading = false;
}
handleAdd() {
this.dialogVisible = false;
}
senddata(selectedorder: any) {
this.oneorderview = selectedorder;
this.dialogVisible = true;
console.log('hahahaha', this.oneorderview);
}
}
</script>
and how to handle data in child component.
You're using class components in Vue typescript. To pass props you need to either use the classic Vue properties or by annotating your class members:
import { Component, Prop } from 'vue-property-decorator'
#Component
export default class App extends Vue {
// Makes a "exampleProperty" a component prop with the default value of 'Example'
#Prop({default: 'Example'})
exampleProperty: string
}

Bind drawer state in Vuetify when nav-drawer and app-bar is different components

now i have two components in my Dashboard:
Dashboard
<template>
<v-app>
<Toolbar :drawer="app.drawer"></Toolbar>
<Sidebar :drawer="app.drawer"></Sidebar>
</v-app>
</template>
<script>
import Sidebar from './components/layouts/Sidebar'
import Toolbar from './components/layouts/Toolbar'
import {eventBus} from "./main";
import './main'
export default {
components: {
Sidebar,
Toolbar,
},
data() {
return {
app: {
drawer: null
},
}
},
created() {
eventBus.$on('updateAppDrawer', () => {
this.app.drawer = !this.app.drawer;
});
},
}
</script>
Sidebar
<template>
<div>
<v-navigation-drawer class="app--drawer" app fixed
v-model="drawer"
:clipped="$vuetify.breakpoint.lgAndUp">
</v-navigation-drawer>
</div>
</template>
<script>
import {eventBus} from "../../main";
export default {
props: ['drawer'],
watch: {
drawer(newValue, oldValue) {
eventBus.$emit('updateAppDrawer');
}
},
}
</script>
Toolbar
<template>
<v-app-bar app>
<v-app-bar-nav-icon v-if="$vuetify.breakpoint.mdAndDown"
#click="updateAppDrawer">
</v-app-bar-nav-icon>
</v-app-bar>
</template>
<script>
import {eventBus} from "../../main";
export default {
props: ['drawer'],
methods: {
updateAppDrawer() {
eventBus.$emit('updateAppDrawer');
}
}
}
</script>
So now i have an infinite loop because when i press on icon in app-bar - watch in Sidebar, Sidebar understanding it like changes and starts a loop, updating drawer value in Dashboard, then Sidebar
catching changes in watch and starts new loop.
Also i have this warning, but it is another question.
[Vue warn]: Avoid mutating a prop
directly since the value will be overwritten whenever the parent
component re-renders. Instead, use a data or computed property based
on the prop's value. Prop being mutated: "drawer"
Thanks.
I have similar issue and able to solve by following this link
https://www.oipapio.com/question-33116
Dashboard
<template>
<v-app>
<Toolbar #toggle-drawer="$refs.drawer.drawer = !$refs.drawer.drawer"></Toolbar>
<Sidebar ref="drawer"></Sidebar>
</v-app>
</template>
Sidebar
<template>
<v-navigation-drawer class="app--drawer" app fixed v-model="drawer" clipped></v-navigation-drawer>
</template>
<script>
export default {
data: () => ({
drawer: true
})
}
</script>
Toolbar
<template>
<v-app-bar app>
<v-app-bar-nav-icon #click.stop="$emit('toggle-drawer')">
</v-app-bar-nav-icon>
</v-app-bar>
</template>

Categories

Resources