Vue search customer detail based on phone number input and auto fill address - laravel

I try to take customer (name, address) based on phone number input. if customer is there then I want the name and address to auto-filled based on customer data we got. below are my code.
my form
<v-row>
<v-col cols="12">
<v-text-field :rules="contactRules" v-model="form.contact" label="Contact" type="number" #input="searchCustomerContact"></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field :rules="nameRules" v-model="form.name" label="Name"></v-text-field>
</v-col>
<v-col cols="12">
<v-textarea rows="1" :rules="address1Rules" v-model="form.address_line_1" label="Address" auto-grow clearable clear-icon="cancel"></v-textarea>
</v-col>
</v-row>
data()
data() {
return {
valid: false,
form: {},
nameRules: [v => !!v || "Name is required"],
contactRules: [v => !!v || "Contact is required"],
address1Rules: [v => !!v || "Address is required"]
};
},
search Customer ()
searchCustomerContact(val) {
if (val.length == 10) {
this.$axios
.get("customers?contact=" + val)
.then(res => {
if (res.data != null) {
this.form.name = res.data.name;
this.form.address_line_1 = res.data.address_line_1;
} else {
this.form.name = null;
this.form.address_line_1 = null;
}
})
.catch(err => {
throw err;
});
}
}
My controller
public function getCustomerByContact()
{
$data = Order::where('contact', request()->contact)->first();
return response()->json($data, 200);
}
Route
Route::get('customers', 'OrderController#getCustomerByContact');
My problem is when data is found, it cannot auto-filled the name and address field. I'm new in vue. If contact is not there then the (name, contact) field is always empty so I think no need to do that part (maybe)
thanks in advance

For those who have this kind of problem, I solved by editing like below
<v-text-field :rules="nameRules" v-model="form.name" label="Name" :value="form.name"></v-text-field>
<v-textarea rows="1" :rules="address1Rules" v-model="form.address_line_1" label="Address" auto-grow clearable clear-icon="cancel" :value="form.address_line_1"></v-textarea>
data() {
return {
form: {
name: "",
address_line_1: ""
},
};
},
add :value in form text-field and name & address in data()->form

Related

Cannot save multiple Image using Form Data

First of all this is the error that I get.
This is my first time working with Multiple Image with other Inputs.
as you can see in my FormData Headers the picture File is an Empty Array.
But inside the console it returns a file.
my question for this one that is this good? because the picture that I'm sending is a PNG one but it only says FILE.
This is my Vue Code.
<q-dialog
v-model="uploadForm"
transition-show="slide-up"
transition-hide="slide-down"
persistent
>
<q-card style="width: 700px; max-width: 50vw;">
<q-card-section>
<div class="text-h6">Add Product</div>
</q-card-section>
<div class="q-pa-md">
<form
action="http://127.0.0.1:8000/api/createProduct"
class="q-gutter-md"
method="POST"
enctype="multipart/form-data"
>
<q-input outlined label="Product name" v-model="data.productName" />
<q-input
multiple="multiple"
outlined
type="file"
accept="image/png,jpg/jpeg"
#change="onFilePicked"
ref="file"
>
<template v-slot:prepend>
<q-icon name="attach_file" />
</template>
</q-input>
<div>
<div class="image-category">
<div v-for="(image, key) in data.picture" :key="key">
<div class="image-item">
<img
class="grid"
:src="image.src"
width="300"
height="300"
/>
</div>
</div>
</div>
</div>
<q-input outlined label="Description" v-model="data.description" />
<q-input
prefix="₱ "
type="number"
outlined
label="Price"
v-model="data.price"
/>
<q-select
square
outlined
v-model="data.category_id"
:options="categories"
:option-value="'id'"
:option-label="'categoryName'"
label="Category"
/>
<div class="q-ma-md float-right">
<q-btn label="Submit" color="primary" #click="createProduct" />
<q-btn
label="Cancel"
color="primary"
flat
class="q-ml-sm"
#click="closeCreateModal"
/>
</div>
</form>
</div> </q-card
></q-dialog>
My returning Data()
data: {
picture: [],
productName: "Grizzly Bear",
description: "Machaba.",
price: "260000",
category_id: []
},
my #Change in accepting multiple Images.
onFilePicked(e) {
let selectedFiles = e.target.files;
for (let i = 0; i < selectedFiles.length; i++) {
let img = {
src: URL.createObjectURL(selectedFiles[i]),
file: selectedFiles[i]
};
this.data.picture.push(img);
console.log(this.data.picture, "inside");
}
console.log(this.data.picture, "outside");
},
My CreatingProduct method.
createProduct() {
let t = this.data;
if (
t.picture == "" ||
t.productName.trim() == "" ||
t.description.trim() == "" ||
t.price == "" ||
t.categories == ""
) {
this.uploadForm = false;
this.$q
.dialog({
title: "Incomplete Details",
message: "Please fill up all the fields in the Product",
persistent: true,
color: "negative"
})
.onOk(() => {
this.uploadForm = true;
});
} else {
let formData = new FormData();
const picture = JSON.stringify(this.data.picture); // returns [object, object] so I needed to do
//this.
const category_id = JSON.stringify(this.data.category_id);
formData.append("picture", picture);
formData.append("productName", this.data.productName);
formData.append("description", this.data.description);
formData.append("price", this.data.price);
formData.append("category_id", category_id);
let config = {
headers: {
"Content-Type": "multipart/form-data"
}
};
this.$axios
.post("http://127.0.0.1:8000/api/createProduct", formData, config)
.then(response => {
this.products.unshift(response.data);
this.uploadForm = false;
(this.data = ""),
this.$q.notify({
icon: "info",
message: "Product Added Successfully",
color: "positive"
});
})
.catch(() => {
this.$q.notify({
color: "negative",
position: "top",
message: "Unable to save Product",
icon: "report_problem"
});
});
}
}},
my Backend in laravel
public function createProduct(Request $request)
{
$this->validate($request,[
'productName' => 'required',
'description' => 'required',
'picture' => 'required|image|mimes:jpg,png,jpeg|max:2048',
'price' => 'required',
'category_id' => 'required'
]);
$product = new Product($request->input());
if($request->hasFile('picture')){
foreach($request->file('picture') as $file){
$name = $file->getClientOriginalName();
$file->move(public_path().'/uploads/',$name);
$product->picture = $name;
}
}
$product->save();
return response()->json($product);
}
Can anyone explain to me what is wrong? I made my research and it doesn't work. and also how do you edit a multiple Image? How would you select a specific image in the Index to make that one being edit.
this is my first time working with Quasar + Laravel in creating a Product with Multiple Image.
I think you are doing some things wrong, if you use a framework try to use it as it was intended either the validations or components they have, I detail an example
new Vue({
el: '#q-app',
data: function() {
return {
uploadForm: true,
data: {
picture: [],
productName: "Grizzly Bear",
description: "Machaba.",
price: "260000",
category_id: null
},
categories: [
{ id: 1, categoryName: 'categoria 1' }
]
}
},
methods: {
createProduct() {
this.$q.loading.show()
let formData = new FormData()
formData.append("picture", this.data.picture);
formData.append("productName", this.data.productName);
formData.append("description", this.data.description);
formData.append("price", this.data.price);
formData.append("category_id", this.data.category_id.id);
axios.post('http://localhost:8000/', formData, {
'headers': {
'Content-Type': 'multipart/form-data;'
}
}).then((response) => {
alert(response)
}).catch(error => {
if (error) {
console.log('error', error)
}
}).finally(() => {
this.$q.loading.hide()
})
},
closeCreateModal() {
alert('close')
},
}
})
<link rel="stylesheet"
type="text/css"
href="https://cdn.jsdelivr.net/npm/#quasar/extras/material-icons/material-icons.css">
<link rel="stylesheet"
type="text/css"
href="https://cdn.jsdelivr.net/npm/quasar/dist/quasar.min.css">
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://cdn.jsdelivr.net/npm/quasar/dist/quasar.umd.min.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div id="q-app">
<q-dialog v-model="uploadForm"
transition-show="slide-up"
transition-hide="slide-down"
persistent>
<q-card style="width: 700px; max-width: 50vw;">
<q-card-section>
<div class="text-h6">Add Product</div>
</q-card-section>
<q-card-section class="q-pt-none">
<div class="q-pa-md">
<q-form #submit="createProduct"
class="q-gutter-md">
<q-input outlined
label="Product name"
v-model="data.productName"
:rules="[val => !!val || 'Field is required']"></q-input>
<q-file multiple outlined v-model="data.picture" label="Outlined" accept="image/png,jpg/jpeg"
:rules="[val => !!val || 'Field is required']">
<template v-slot:prepend>
<q-icon name="attach_file" ></q-icon>
</template>
</q-file>
<q-input outlined
label="Description"
v-model="data.description"
:rules="[val => !!val || 'Field is required']"></q-input>
<q-input prefix="₱ "
type="number"
outlined
label="Price"
v-model="data.price"
:rules="[val => !!val || 'Field is required']"></q-input>
<q-select square
outlined
v-model="data.category_id"
:options="categories"
option-value="id"
option-label="categoryName"
label="Category"
:rules="[val => !!val || 'Field is required']"
></q-select>
<div>
<q-btn label="Submit"
color="primary"
type="submit"></q-btn>
<q-btn label="Cancel"
#click="closeCreateModal"
flat class="q-ml-sm"></q-btn>
</div>
</q-form>
</div>
</q-card-section>
</q-card>
</q-dialog>
</div>
if you see the log the "picture" attribute has an array of Object File
I leave the backend processing (laravel) at your discretion
I think it would be easier if you share a link with your problem for future reference
https://jsfiddle.net/idkc/L8xn0puq/52/

Submit Vuetify form with the enter button

Thought this would be straight forward but it isn't. With vuetify forms how do I bind a form to the enter button so that it's submit function is invoked with the enter button?
Figures I'd find a work around as soon as I posted the question. I found the answer here:
https://github.com/vuetifyjs/vuetify/issues/1545
Basically I had to add an event listener to the component to attach the enter key press to my authenticate method. Here is the component in questions:
<template>
<v-card>
<v-card-title>
<span class="headline">Login</span>
</v-card-title>
<v-form v-model="isValid">
<v-card-text>
<v-container>
<v-row>
<v-col cols="12">
<v-text-field
v-model="username"
label="User Name"
prepend-icon="mdi-account circle"
:rules="userNameRequired"
required
></v-text-field>
</v-col>
<v-col cols="12">
<v-text-field
v-model="password"
label="Password"
:type="showPassword ? 'text' : 'password'"
prepend-icon="mdi-lock"
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
#click:append="showPassword = !showPassword"
:rules="passwordRequired"
required
></v-text-field>
</v-col>
</v-row>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" text #click="close"> Close </v-btn>
<v-btn color="blue darken-1" text #click="authenticate" :disabled="!isValid">
Login
</v-btn>
</v-card-actions>
</v-form>
</v-card>
</template>
<script>
import { authenticationService } from "../services/authenticationService/authentication.service";
import User from "../models/user";
export default {
name: "LoginForm",
props: ["userForAuthentication"],
data: () => ({
username: "",
password: "",
user: {},
isValid: true,
showPassword: false,
userNameRequired: [(v) => !!v || "User Name is required"],
passwordRequired: [(v) => !!v || "Password is required"],
}),
methods: {
async authenticate() {
try {
const response = await authenticationService.authenticateUser(
this.$data.username,
this.$data.password
);
if (response.status === 200) {
this.$data.user.shallowClone(response.data.user);
await this.resetData();
this.$emit(
"user-logging-in-event",
this.$data.user,
response.data.token
);
this.$toasted.success(`${this.$data.user.fullName} is logged in.`, {
duration: 3000,
});
} else if (response.status === 400) {
this.$toasted.error("Username or Password is incorrect.", {
duration: 3000,
});
} else {
this.$toasted.error(
"An error occurred while trying to authenticate the user",
{
duration: 3000,
}
);
}
} catch (error) {
this.$toasted.error(error, {
duration: 3000,
});
}
},
close() {
this.$emit("user-logging-in-event", null, null);
},
async resetData() {
this.$data.username = "";
this.$data.password = "";
},
},
mounted() {
let self = this;
window.addEventListener("keyup", function (event) {
if (event.keyCode === 13) {
self.authenticate();
}
});
this.$data.user = new User();
this.$data.user.shallowClone(this.$props.userForAuthentication);
},
};
</script>

Call to undefined method Person::id()

Something really weird is happening, when I don't upload any image in my form it doesn't throw any error, but when I do it throws this: Call to undefined method App\Models\User_Management\Person::id()
Front-End Code
<template>
<div>
<div class="container-2 mx-8 mt-10">
<v-row>
<v-col xs="12" sm="12" md="8">
<v-card>
<v-form enctype="multipart/form-data">
<div class="container-2 mx-2">
<!-- Personal information -->
<v-divider></v-divider>
<p class="mt-2">Personal information</p>
<v-row>
<v-col cols="12" sm="12" md="4">
<v-text-field v-model="person.first_name" counter="150" :rules="id="first_name" name="first_name" label="First Name" color="black"></v-text-field>
</v-col>
<v-col cols="12" sm="12" md="4">
<v-text-field label="Last Name" v-model="person.last_name" counter="150" name="last_name" color="black"></v-text-field>
</v-col>
</v-row>
<v-divider></v-divider>
<p class="mt-2">Profile Picture</p>
<v-row>
<v-col cols="12" sm="12" md="6">
<input type="file" id="avatar" ref="avatar" v-on:change="fileUpload()"/>
</v-col>
</v-row>
<div class="right-align">
<v-btn color="yellow" class="black-text" #click="update()">Submit</v-btn>
<v-btn color="red accent-3" class="black-text">Back</v-btn>
</div>
<br>
</div>
</v-form>
</v-card>
</v-col>
</v-row>
</div>
</div>
</template>
<script>
export default {
data() {
return {
//Data
person: {
first_name: '',
last_name: '',
},
userAvatar: undefined,
person_id: 1,
}
}
},
methods: {
fileUpload(){
this.userAvatar = this.$refs.avatar.files[0];
},
update() {
let formData = new FormData();
formData.append('first_name', this.person.first_name);
formData.append('last_name', this.person.last_name);
formData.append('profile_picture', this.userAvatar);
formData.append('_method', 'PUT');
axios.post(`/profile/${this.person_id}`, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then(res => {
console.log(res.data);
}).catch(e => {
console.log(e);
})
},
}
}
}
</script>
Back-End Code
public function update(Request $request, $id)
{
//Person
$person = Person::find($id);
//Avatar
$name = null;
$image = null;
if ($request->hasFile('profile_picture')){
$file = $request->file('image');
$name = $person->id();
$file->move(public_path().'/img/uploads/avatars', $name);
//Image
$image = new Image();
$image->path = $name;
$image->save();
}
//Profile
$person->first_name = $request->first_name;
$person->last_name = $request->last_name;
if ($image)
$person->image_id = $image->id;
$person->save();
}
My import for the Model is written like this
use App\Models\User_Management\Person;
For some reason it seems like it doesn't recognize the ::find($id) method when I upload an image but I have no idea why, is there any fix for this? I tried to log the $request variable and it's throwing the following
[2020-04-13 19:41:23] local.INFO: array (
'first_name' => 'John',
'last_name' => 'Smith',
'_method' => 'PUT',
'profile_picture' =>
Illuminate\Http\UploadedFile::__set_state(array(
'test' => false,
'originalName' => 'kekas.jpg',
'mimeType' => 'image/jpeg',
'error' => 0,
'hashName' => NULL,
)),
)
It doesn't seem like there's something wrong with the front-end code but I left it here just in case it gives a hint about this weird error.
There's no method $person->id(); in Person Instanse. You need do get a property like this: $person->id. Hope it helps.
You're error in this code line: $name = $person->id();

How show server's error in vee-validate with different name?

In my vue/cli 4/vuex / bootstrap-vue project / "vue-router": "^3.1.3" /
"vee-validate": "^3.2.1" / "vue-resource": "^1.5.1",project I use backend rest for saving data and
I have a problem that getting errors from server like
{"message":"The given data was invalid.","errors":{"title":["The title has already been taken."]}}
I can not show it on my form as that is big form with many elements and modal form has more
complicated name , not “title” and I suppose that is why server's error is not shown:
<b-modal id="saveCurrentFilterModal" scrollable size="lg" style="min-width: 720px !important;">
<ValidationObserver
ref="saveCurrentFilterModalForm"
v-slot="{handleSubmit}"
>
<form ref="form" #submit.stop.prevent="handleSubmitOnSaveCurrentFilterOptionsSubmit">
<b-form-group
:state="nameState"
label="Name"
label-for="name-input"
invalid-feedback="Name is required"
>
<ValidationProvider
name="save_current_filter_title" // MORE COMPLICATED TITLE NAMW!
rules="required|max:100"
v-slot="{ errors }"
>
<b-form-input
id="save_current_filter_title"
v-model="save_current_filter_title"
placeholder="Edit saved filter title"
autocomplete="off"
></b-form-input>
<p class="validation_error">{{ clearErrorMessage(errors[0]) }}</p>
</ValidationProvider>
</b-form-group>
<b-button type="submit" size="sm" variant="outline-secondary" class="ml-4">
<i :class="'action_link '+getHeaderIcon('save')"></i>Save
</b-button>
</form>
</ValidationObserver>
handleSubmitOnSaveCurrentFilterOptionsSubmit() {
this.$refs.saveCurrentFilterModalForm.validate().then(success => {
console.log('handleSubmitOnSaveCurrentFilterOptionsSu success::')
console.log(success)
if (!success) {
return;
}
let filters = {
...
}
let self = this
self.$http.post(self.apiUrl + '/personal/ad-saved-filters', filters).then(({data}) => {
console.log(data)
self.showPopupMessage("Saved filter", 'Saved filter was successfully saved !', 'success');
self.$bvModal.hide('saveCurrentFilterModal')
}, error => {
console.error(error)
self.$refs.saveCurrentFilterModalForm.setErrors(error.body.errors); // TO GET ERRORS FROM
self.showPopupMessage("Saved filter", error.body.message, 'warn');
});
});
}, // handleSubmitOnSaveCurrentFilterOptionsSubmit(evt) {
Is there is a way to fix it ?
When you call setErrors you have to have the correct field names specified. So if the server returns title but you need save_current_filter_title, you'll have to have some sort of object that keeps track of the relationship between the server's field names and the client's. For instance, on the client side, you could have this:
let filters = {
...
}
let self = this
self.$http.post(self.apiUrl + '/personal/ad-saved-filters', filters).then(({data}) => {
...
}, error => {
//define this in data, but for example:
var sKey2cKey = {
title: 'save_current_filter_title',
name: 'complicated-client-name',
//etc
}, convertedErrors = {};
Object.keys(error.body.errors).forEach((key) => {
convertedErrors[sKey2cKey[key]] = error.body.errors[key];
});
self.$refs.saveCurrentFilterModalForm.setErrors(convertedErrors);
self.showPopupMessage("Saved filter", error.body.message, 'warn');
});

How to add password matching validation in vuetify?

I am trying to create a profile form which have two fields
password and rePassword. basically, Both of them should be the same.
I tried using different codes found on the web and different approaches. Some of them worked but. It did'nt actually fit in with the code.
Here is the piece of code:
Profile.vue:
<v-layout>
<v-flex xs12 sm6>
<v-text-field
v-model="password"
:append-icon="show ? 'visibility' : 'visibility_off'"
:rules="[rules.required, rules.min]"
:type="show ? 'text' : 'password'"
name="password"
label="Enter Password"
hint="At least 8 characters"
counter
#click:append="show = !show"
></v-text-field>
</v-flex>
<v-flex xs12 sm6>
<v-text-field
v-model="rePassword"
:append-icon="show1 ? 'visibility' : 'visibility_off'"
:rules="[rules.required, rules.min]"
:type="show1 ? 'text' : 'password'"
name="input-10-1"
label="Re-enter Password"
hint="At least 8 characters"
counter
#click:append="show1 = !show1"
></v-text-field>
</v-flex>
</v-layout>
This is how the script looks like:
Profile.vue (script):
data() {
return {
show: false,
show1: false,
password: 'Password',
rePassword: 'Password',
rules: {
required: value => !!value || 'Required.',
min: v => v.length >= 8 || 'Min 8 characters',
emailMatch: () => ('The email and password you entered don\'t match')
},
emailRules: [
v => !!v || 'E-mail is required',
v => /.+#.+/.test(v) || 'E-mail must be valid'
],
date: new Date().toISOString().substr(0, 10),
menu: false,
items: ['male', 'female'],
address: '',
title: "Image Upload",
dialog: false,
imageName: '',
imageUrl: '',
imageFile: ''
}
},
methods: {
pickFile() {
this.$refs.image.click()
},
onFilePicked(e) {
const files = e.target.files
if(files[0] !== undefined) {
this.imageName = files[0].name
if(this.imageName.lastIndexOf('.') <= 0) {
return
}
const fr = new FileReader ()
fr.readAsDataURL(files[0])
fr.addEventListener('load', () => {
this.imageUrl = fr.result
this.imageFile = files[0] // this is an image file that can be sent to server...
})
} else {
this.imageName = ''
this.imageFile = ''
this.imageUrl = ''
}
},
}
,
validate() {
if (this.$refs.form.validate()) {
this.snackbar = true
}
},
reset() {
this.$refs.form.reset()
}
How do I add a password matching feature in the validation using vuetify.
Thanks
You can define custom rules:
computed: {
passwordConfirmationRule() {
return () => (this.password === this.rePassword) || 'Password must match'
}
}
and use it
<v-flex xs12 sm6>
<v-text-field
v-model="rePassword"
:append-icon="show1 ? 'visibility' : 'visibility_off'"
:rules="[rules.required, rules.min, passwordConfirmationRule]"
:type="show1 ? 'text' : 'password'"
name="input-10-1"
label="Re-enter Password"
hint="At least 8 characters"
counter
#click:append="show1 = !show1"
/>
</v-flex>
very easiest way is
using v-model (password and confirm_password), no need to use computation
Rule
:rules="[v => !!v || 'field is required']"
Or
:rules="[(password!="") || 'field is required']"
in password
<v-text-field label="Password*" v-model="password" type="password" required :rules="[v => !!v || 'field is required']"></v-text-field>
confirm password field
Rule
:rules="[(password === confirm_password) || 'Password must match']"
code:
<v-text-field label="Confirm Password*" v-model="confirm_password" type="password" required :rules="[(password === confirm_password) || 'Password must match']"></v-text-field>
VeeValidate is great for form validation but in my opinion is overkill for resolving this question when it can be achieved in Vuetify alone.
Following on from #ittus answer, you need to remove the arrow function in passwordConfirmationRule to access this:
return this.password === this.rePassword || "Password must match";
See this codesandbox working example (also now using Vuetify 2.x)
Very simply using Vee-validate:
<div id="app">
<v-app id="inspire">
<form>
<v-text-field
ref="password"
type="password"
v-model="pass"
v-validate="'required'"
:error-messages="errors.collect('pass')"
label="Pass"
data-vv-name="pass"
required
></v-text-field>
<v-text-field
v-model="pass2"
type="password"
v-validate="'required|confirmed:password'"
:error-messages="errors.collect('pass2')"
label="Pass 2"
data-vv-name="pass"
required
></v-text-field>
<v-btn #click="submit">submit</v-btn>
<v-btn #click="clear">clear</v-btn>
</form>
</v-app>
</div>
Vue.use(VeeValidate)
new Vue({
el: '#app',
$_veeValidate: {
validator: 'new'
},
data: () => ({
pass: '',
pass2: "",
}),
methods: {
submit () {
this.$validator.validateAll()
.then(result => {
console.log(result)
})
},
clear () {
this.pass = ''
this.pass2 = ''
}
}
})
Remember to install vee-validate first and restart your local-server.
link to codepen
link to docs
This works right for me!
// template
<v-text-field v-model="password" label="password"></v-text-field>
<v-text-field v-model="confirmPassword" :rules="confirmPasswordRules" label="confirmPassword"></v-text-field>
// script
computed: {
confirmPasswordRules() {
const rules = [(this.password === this.confirmPassword) || "Password must match."];
return rules;
},
}
This is not a clean solution definitely, but works fine.
<v-text-field
type="password"
v-model="password"
:rules="passwordRules"
required
></v-text-field>
<v-text-field
type="password"
v-model="passwordConfirm"
:rules="passwordConfirmRules"
required
></v-text-field>
let globalPassword = "";
watch: {
password() {
globalPassword = this.password;
},
},
passwordConfirmRules = [
(v) => v === globalPassword || "Password must match",
];

Resources