I'm trying to send data from the Pinia store to a child component's input field, using TypeScript. But I'm having the type error -
Property 'storeForm' does not exist on type '{ $: ComponentInternalInstance; $data: {}; $props: Partial<{}> & Omit<Readonly<ExtractPropTypes<{}>> & VNodeProps & AllowedComponentProps & ComponentCustomProps, never>; ... 10 more ...; $watch<T extends string | ((...args: any) => any)>(source: T, cb: T extends (...args: any) => infer R ? (args_0: R, args_1: R) => ...'.
Does is mean I need to type the store or other properties?
// Child component
<template>
<v-sheet width="300" class="mx-auto">
<v-form fast-fail @submit.prevent>
<!-- v-model="firstName" -->
<v-text-field
label="First name"
:rules="firstNameRules"
placeholder="Your Name"
>{{ storeForm.firstName }}</v-text-field> // the error goes this line
<!-- v-model="lastName" -->
<v-text-field
label="Last name"
:rules="lastNameRules"
>{{ storeForm.lastName }}</v-text-field>
<v-btn type="submit" block class="mt-2" @click="submit($event)">Submit</v-btn>
</v-form>
</v-sheet>
</template>
<script lang="ts">
import { ref } from 'vue'
import {useForm} from '@/stores/form'
import router from '../router'
import { defineComponent } from 'vue'
// export default {
export default defineComponent({
setup() {
const storeForm = useForm(); // getting the Store
const firstName = ref<string>('')
const lastName = ref<string>('')
const firstNameRules = ref<any>(
(value: String) => {
if (value?.length > 3) return true
return 'First name must be at least 3 characters.'
}
)
const lastNameRules = ref<any>(
(value: String) => {
if (/[^0-9]/.test(String(value))) return true
return 'Last name can not contain digits.'
}
)
const submit = (event: Event) => {
event.preventDefault();
let user = {
firstName: firstName.value,
lastName: lastName.value,
}
storeForm.login(user)
router.push('/');
firstName.value = '';
lastName.value = '';
}
return {firstName, lastName, firstNameRules, lastNameRules, submit};
}
})
</script>
// Store file
import { defineStore } from 'pinia'
export const useForm = defineStore('login',{
state: () => ({
firstName: <string>'', // defining the input string
lastName: <string>''
}),
getters: {
},
actions: {
login(data: any) {
this.firstName = data.firstName
this.lastName = data.lastName
}
}
})
You are not returning the "storeForm" object from your setup function.
Recommendations: to make your data reactive you should use the following syntax, as docs suggest.
https://pinia.vuejs.org/core-concepts/
<script setup>
import { storeToRefs } from 'pinia'
const store = useCounterStore()
// `name` and `doubleCount` are reactive refs
// This will also extract refs for properties added by plugins
// but skip any action or non reactive (non ref/reactive) property
const { name, doubleCount } = storeToRefs(store)
// the increment action can just be destructured
const { increment } = store
</script>