Use the mask Vue 3 - javascript

I have a phone mask. More precisely, an error instead of a mask.
I really can't figure out why the error occurs because it is completely uninformative!!!
<template>
<input type="text" v-model="value" v-mask="'#-#-#'" />
</template>
<script>
import { ref, defineComponent } from "vue";
export default defineComponent({
setup() {
const value = ref("");
return { value };
},
watch: {
value(n) {
this.$emit("input", n);
},
},
});
</script>
https://codesandbox.io/s/musing-resonance-dyl63c?file=/src/App.vue
If you remove the v-mask directive, then everything works as it should. How can I solve the error??
Thank you!

Try to register it locally, it should work :
<template>
<input type="text" v-model="value" v-maska="'#-#-#'" />
</template>
<script>
import { ref, defineComponent } from "vue";
import { maska } from "maska";
export default defineComponent({
setup() {
const value = ref("");
return { value };
},
directives: { maska },
watch: {
value(n) {
this.$emit("input", n);
},
},
});
</script>

Try this way:
in your main.js instead app.directive("v-mask", maska) go with app.use(maska)
in phone.vue instead v-mask="'#-#-#'" go with v-maska="'#-#-#'"
codesandbox

Related

Vue Component Event triggers but doesnt do anything

This is my code:
Tablecomponent:
<template>
<rowcomponent #reloadTable="fetchData(pagination.current_page)" :item_data="item" :isDOMadd="false" :workflowoffer_id="workflowoffer_id"></rowcomponent >
</template
<script>
import rowcomponent from "./rowcomponent";
export default{
methods :{
fetchData(url){
console.log('test');
},
components: {
rowcomponent,
},
}
}
</script>
Rowcomponent:
<script>
export default{
methods :{
safeData(){
console.log('safe');
this.$emit('reloadTable');
}
},
}
</script>
Console Output:
safe
The Vue Event gets triggered (vue-devtool) but it doesnt do anything
i Know it should work, but it doesnt. Has anyone some solutions or tips what it could be.
UPDATE: So i found the error, but i cant explain it ^^
I add this line in the Tablecomponent in export default {...}:
name: "TableComponent",
and now it works**
Since you didn't share your row-component completely I made a working example. Can you please look at this and compare with yours ?
Parent component:
<template>
<div id="app">
<rowcomponent #reloadTable="reloadTable" />
</div>
</template>
<script>
import rowcomponent from "./components/rowcomponent";
export default {
name: "App",
methods: {
reloadTable () {
console.log("test")
}
},
components: {
rowcomponent
}
};
</script>
rowcomponent
<template>
<div class="hello">
click me to see the results
<button #click="safeData"> click me </button>
</div>
</template>
<script>
export default {
name: "rowcomponent",
methods :{
safeData(){
console.log('safe');
this.$emit('reloadTable');
}
}
};
</script>
Output will be : safe and test

Vue, dynamically import template

I want to be able to swap out a template for a component based on a data property, or a prop. Is this possible?
This is my idea, however this doesn't work of course.
./index.vue
export default {
props:{
},
template: import(`./Themes/Templates/${this.template}`),
data: function() {
return {
template: 'Default'
}
},
./Themes/Templates/Default.vue
<div>
<p>Default template</p>
</div>
Currently getting this error:
invalid template option:[object Module]
Use component that vue.js provide:
<template>
<component :is="myComp"></component>
</template>
...
// You need to import all the possible components
import CompOne from '/CompOne.vue';
import CompTwo from '/CompTwo.vue'
props:{
myComp: {
default: 'comp-one',
type: String,
},
},
...
Try require("./Themes/Templates/Default.vue")
Update:
In Default.vue:
...
export default {
name: "Default"
}
...
and in index.vue:
...
template: this.temp,
data() {
const { Default } = import("./Themes/Templates/Default.vue");
return {
temp: Default
}
}
...

How can I reactively update a value in a component from a store value?

I have two components and a basic store as per the docs here: https://v2.vuejs.org/v2/guide/state-management.html#Simple-State-Management-from-Scratch.
I want to make it so that when I type into an input the value in a different component is updated by using the store.
Basic example here.
App.vue
<template>
<div id="app">
<h1>Store Demo</h1>
<BaseInputText /> Value From Store: {{ test }}
</div>
</template>
<script>
import BaseInputText from "./components/BaseInputText.vue";
import { store } from "../store.js";
export default {
// This should reactively changed as per the input
computed: {
test: function() {
return store.state.test;
}
},
components: {
BaseInputText
}
};
</script>
BaseInput.vue
<template>
<input type="text" class="input" v-model="test" />
</template>
<script>
import { store } from "../store.js";
export default {
data() {
return {
test: store.state.test
};
},
// When the value changes update the store
watch: {
test: function(newValue) {
store.setTest(newValue);
}
}
};
</script>
store.js
export const store = {
debug: true,
state: {
test: "hi"
},
setTest(newValue) {
if (this.debug) console.log("Set the test field with:", newValue);
this.state.test = newValue;
}
};
I want to make it so that when I type a string into the input the test variable in App.vue is updated. I'm trying to understand how the store pattern works. I'm aware of how to use props.
I also have a working copy here: https://codesandbox.io/s/loz79jnoq?fontsize=14
Updated
2.6.0+
To make store reactive use Vue.observable (added in in 2.6.0+)
store.js
import Vue from 'vue'
export const store = Vue.observable({
debug: true,
state: {
test: 'hi'
}
})
BaseInputText.vue
<input type="text" class="input" v-model="state.test">
...
data() {
return {
state: store.state
};
},
before 2.6.0
store.js
import Vue from 'vue'
export const store = new Vue({
data: {
debug: true,
state: {
test: 'hi'
}
}
})
BaseInputText.vue
<input type="text" class="input" v-model="state.test">
...
data() {
return {
state: store.state
};
}
Old answer
From documentation However, the difference is that computed properties are cached based on their reactive dependencies.
The store is not reactive
Change to
App.vue
data() {
return {
state: store.state
};
},
computed: {
test: function() {
return this.state.test;
}
},
It looks bad but I don't see another way to make it work

Multiple forms with one submit() method by Vue

I have a few forms. Every of them have the same logic (validation, sending...) so, I want to create one method to control actions on my forms. For now my code is redundancy, because I have the same methods onSubmit() on every .vue file.
my HTML:
<div id="app">
<myform-one></myform-one>
<myform-two></myform-two>
</div>
my JavaScript (main.js - entry file in webpack):
import Vue from 'vue';
import Myform1 from './myform1.vue';
import Myform2 from './myform2.vue';
new Vue({
el: '#app',
components: {
myformOne: Myform1,
myformTwo: Myform2
}
});
and VUE components files:
myform1.vue:
<template>
<div>
<form #submit.prevent="onSubmit">
<input type="text" v-model="fields.fname11" />
<input type="text" v-model="fields.fname12" />
<button type="submit">submit</button>
</form>
</div>
</template>
<script>
let formfields = {
fname11: '',
fname12: ''
};
export default {
data() {
return {
fields: formfields
}
},
methods: {
onSubmit() {
// code responsible for reading, validating and sending data here
// ...
console.log(this.fields);
}
},
}
</script>
and myform2.vue:
<template>
<div>
<form #submit.prevent="onSubmit">
<input type="text" v-model="fields.fname21" />
<input type="text" v-model="fields.fname22" />
<input type="text" v-model="fields.fname23" />
<button type="submit">submit</button>
</form>
</div>
</template>
<script>
let formfields = {
fname21: '',
fname22: '',
fname23: '',
};
export default {
data() {
return {
fields: formfields
}
},
methods: {
onSubmit() {
// code responsible for reading, validating and sending data here
// ...
console.log(this.fields);
}
},
}
</script>
How can I create and use one, common method submitForm()? And where its code should be (good practice)?
Create a separate file which contains the logic:
// submitForm.js
export default function (fields) {
// code responsible for reading, validating and sending data here
// ...
}
Then use that logic inside the components
import submitForm from "../services/submitForm.js"
...
methods: {
onSubmit() {
submitForm(this.fields)
}
}
Vue3 (with Quasar for me but I'm sure it would work for any framework):
Say you have a parent which contains a number of forms <Forms />:
First create a composable function like so useForms.js:
import { ref } from 'vue'
const forms = ref([])
export function useForms(){
const checkForms = () => {
forms.value.forEach((form) => form.validate()
}
const addFormToFormsArray = (form) => {
forms.value.push(form)
}
return { forms, addFormToFormsArray, checkForms }
}
Then import it into <Forms />:
<template>
<Form />
<Form />
<Form />
<button #click="checkForms">Check Form</button>
</template>
<script setup>
import { useForms } from '../useForms';
const { checkForms } = useForms()
</script>
Finally, inside the <Form />:
<template>
<form ref="form">
.../stuff
</form>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { useForms } from '../useForms';
const form = ref(null)
onMounted(() => {
addFormToFormsArray(form.value)
})
const { checkForms, addFormToFormsArray } = useForms()
</script>
When performing the check function in the parent, it should go through each form and check for any issues.
There are some options. My favorite is creating a mixin vue docs mixins
export const form_functionality = {
methods: {
on_submit() {
//logic of submit
},
//here we can have other reusable methods
}
}
Then in your components use that mixin as follow:
import { form_functionality } from 'path_of_mixin'
export default {
mixins: [form_functionality]
}
In the end, what mixins has (created, methods, data etc) will be merged to the component
which uses that mixin.
So, practically you can access the mixin method like this.on_submit()

nuxt.js passing prop to component's inner element

I have a simple component:
<template>
<div id="search__index_search-form">
<input :foo-id="fooId" #keyup.enter="findFoos()" type="text" :value="keyword" #input="updateKeyword"
placeholder="Search for a foo">
<button #click="findFoos()">Search!</button>
{{fooId}}
</div>
</template>
<script>
import {mapState} from "vuex";
export default {
computed: mapState({
keyword: state => state.search.keyword
}),
data: function () {
return {fooId: "all"};
},
methods: {
updateKeyword(e) {
this.$store.commit("setSearchKeyword", e.target.value);
},
findFoos() {
this.$store.dispatch("findFoos");
}
}
};
</script>
I am calling it from nuxt page:
<template>
<searchbar v-bind:fooId="500"/>
</template>
<script>
import searchBar from "~/components/search-bar.vue";
export default {
components: {
'searchbar': searchBar
}
};
</script>
This results in:
<div id="search__index_search-form" fooid="500"><input shop-id="all" type="text" placeholder="Search for a foo"><button>Search!</button>
all
</div>
Question is, why is fooId bound to "div.search__index_search-form" and not to input? And how come {{fooId}} results in "all" (default state), and not "500"?
fooId is rendered on div#search__index_search-form because you do not declare fooId as a property of the component. Vue's default behavior is to render undeclared properties on the root element of the component.
You need to declare fooId as a property.
export default {
props: {
fooId: {type: String, default: "all"}
},
computed: mapState({
keyword: state => state.search.keyword
}),
methods: {
updateKeyword(e) {
this.$store.commit("setSearchKeyword", e.target.value);
},
findProducts() {
this.$store.dispatch("findFoos");
}
}
};
I'm not sure what you are really trying to accomplish though.
<input :foo-id="fooId" ... >
That bit of code doesn't seem to make any sense.

Categories