using the v-modeled data in two variable in vue - javascript

I v-model a data in my vue html to validate it in my form , but i also want to use it in other variable too
this is my html
<input class="input-style px-3" :class="{'border-red-error':v$.categoryTitle.$errors.length>0}" type="text"
placeholder="title" :disabled="formIsSending" v-model="DataForValidating .categoryTitle">
this is my js code , but it does not work
const DataForValidating = reactive({
categoryTitle: '',
categorySlug: '',
})
const categoryFormData = {
categoryTitle: DataForValidating.categoryTitle,
categorySlug: DataForValidating.categorySlug,
}
i made categoryFormData reactive too , but it does not work

use #input event and pass a function then store "DataForValidating.categoryTitle"
in another variable
or you can directly use arrow function in #input event to assign that v-model variable to another

i got answer , i need to use watcher
watch:{
'newCategoryData.categoryTitle': function (newVal){
this.categoryFormData.categoryTitle=newVal
},
'newCategoryData.categorySlug': function (newVal){
this.categoryFormData.categorySlug=newVal
},
}

Related

VUE how to replace json variables

I have defined in data() JSON and url variable:
data() {
return {
url: '',
startsession: {
cmd: 'start',
width: 1024,
height: 800,
url: 'https://www.test.com',
token: '',
service_id: 1,
thumbnail_width: 100,
thumbnail_height: 100,
},
url is assigned to input:
<b-form-input v-model="url" />
I also have button:
<b-button
#click="sendMessage(startsession)"
>
Could you please help me, how to replace 'url' param in JSON with url variable from input, that when i click button, the 'sesstionstart' JSON will have value from input?
You can make use of methods. First, define a method with name sendMessage and then just access the variables using this and update the startsession.url with url.
methods: {
sendMessage () {
this.startsession.url = this.url
}
}
Make sure your b-form-input component has syntax like this :
https://v2.vuejs.org/v2/guide/components.html#Using-v-model-on-Components
in base, you will pass url as prop to b-form-input, and in this child component, you need emit a event to tell parent the value of url is changed. Then, just use sendMessage method like #Yash

Using v-bind and v-on instead of v-model vuejs

I was using v-model to handle inputs in a form, I had to change it to bind props values, at first input was like
<input type="text" class="form-control" placeholder="" v-model="username">
and now it looks like
<input type="text" class="form-control" placeholder="" v-bind:value="modelData.username" v-on:input="username = $event.target.value">
modelData is coming in props. and it has username.
when Using model, in data, i had defined
data: () => {
return {
username: ""
}
},
and It was working fine, but after changing it to v-bind and v-on,
My question is how I can now get the value of username in methods? as in past, I was getting it as this.username to get the value and also clear it as well but now how I can get username in
methods: {}
I have a button to save input
<button class="btn btn-secondary" type="button" #click="validateFormAndSave($event)">Save</button>
When validateFormAndSave get called I can have this.username right now I cannot get the value? But the Vue Doc says v-model and v-bind:value& v-on:input are the same?
UPDATE:
There can be and cannot be some value already there in username, as it being filled with props value, So v-on:input="username = $event.target.value" don't get the already written value but the only new one you entered? or edit it? Why is it so? is there any method for just to get what anyone typed in there or already been typed?
UPDATE:
This is getting very ambiguous. So for now.
1. I can set v-bind:value, But I cannot get it in methods without editing it.
2. I cannot set this.username = "" and it will not be removed from input as well.
3. #input only get what you newly typed not what already in there
v-model is just syntax sugar for =>
<input :value="modelValue" #input="modelValue = $event.target.value"/>
If you want something else, it's very easy to do. Just change the update side to onInput:
<input
class="form-control"
:value="username"
#input="username = $event.target.value"
>
Then
data: () => {
return {
username: ""
}
},
mounted()
{
this.username = this.modelData.username;
},
methods:{
consoleUsername() {
console.log(this.username);
}
}
The best possible solution can be when you are getting your data from props and also loading it a form for v-models.
Using watch feature of Vue component.
First I added props as
export default {
props: ["vendorModelData"],
and then I pass it through the watch to v-model
watch: {
vendorModelData() {
this.updatePropsValue(this.vendorModelData)
console.log("data updated")
}
},
in this way, it always loads differently when Props get changed. This way I got be using v-model as well as load data from props to it.
I found it useful for me.

Most efficient way to get the content from a tag and save it in a variable in vue

I have this code in vue
<ul>
<li v-for="exchange in finalExchanges"><button class="resultBtn"> {{exchange}} <hr></button></li>
</ul>
With the following js
export default {
name: 'exchange',
data () {
return {
exchanges,
msg: 'Exchange',
search: ''
}
},
computed: {
finalExchanges() {
return this.exchanges.filter(exchange => {
return exchange.includes(this.search)
})
}
}
}
I'm curious to know what is the most efficient way to get the {{exchange}} that user clicks on and save it in a variable. I presume that there are a lot of ways like using document.getElementById() and probably a vue way too but I'm looking for an efficient way to do this considering how future-proof it is. Any opinion is highly appreciated!
If you had some variable in your data like maybe "selectedExchange" and you wanted to assign the clicked exchange to that variable you could simply add to your button:
<button #click="selectedExchange = exchange"...>
If I understand the problem correctly this is certainly the most common and probably the most efficient way to get the clicked exchange.
If you wanted to use the clicked exchange as a variable in a method you would simply put:
<button #click="someFunction(exchange)"...>
And then you'd just get it in your method like:
...
methods: {
someFunction: function( ex ) {
... // ex will be the clicked exchange
}
}
I'd go with this solution.
At first add currentExchange variable in data if you need to store it
data () {
return {
exchanges,
msg: 'Exchange',
search: '',
currentExchange: null
}
}
Then add event handler, in your button where you pass current exchangeValue
<button class="resultBtn" v-on:click="handlerFunc(exchange)"> {{exchange}}<hr></button>
Please have in mind that v-on:click might be replaced as #click
Now in your handler do your logic
methods:{
handlerFunc(exchange) {
// assign it to data if needed
this.currentExchange = exchange
// do your stuff...
}

Vuejs set value of hidden input as route param

I am trying to set the value of a hidden input with a value of id so that when I submit my form, I have the id. I know that this value is being passed using a param as follows:
<td><router-link :to="{ name: 'editclient', params: { id: client.id }}">Edit</router-link></td>
Then in my EditClient component I have the following hidden input:
<input type="hidden" value="{{this.$route.params.id}}" v-model="id">
The issue is that this won't compile, is there another way to do this?
I can see that the value of my id is set to 1 which is what it should be in this case:
However the issue is that I can't bind this to my hidden input.
Any help is appreciated, thanks
In this case I would probably just use v-model
<input type="hidden" v-model="id">
And then set id either in data or when the route changes.
data(){
return {
id: this.$route.params.id
...
}
}
Just for reference incase someone else hits this issue, I managed to solve this by using a computed attribute in my component:
computed: {
id () {
return this.$route.params.id
}
},

Passing data to components in vue.js

I'm struggling to understand how to pass data between components in vue.js. I have read through the docs several times and looked at many vue related questions and tutorials, but I'm still not getting it.
To wrap my head around this, I am hoping for help completing a pretty simple example
display a list of users in one component (done)
send the user data to a new component when a link is clicked (done) - see update at bottom.
edit user data and send it back to original component (haven't gotten this far)
Here is a fiddle, which fails on step two: https://jsfiddle.net/retrogradeMT/d1a8hps0/
I understand that I need to use props to pass data to the new component, but I'm not sure how to functionally do it. How do I bind the data to the new component?
HTML:
<div id="page-content">
<router-view></router-view>
</div>
<template id="userBlock" >
<ul>
<li v-for="user in users">{{user.name}} - <a v-link="{ path: '/new' }"> Show new component</a>
</li>
</ul>
</template>
<template id="newtemp" :name ="{{user.name}}">
<form>
<label>Name: </label><input v-model="name">
<input type="submit" value="Submit">
</form>
</template>
js for main component:
Vue.component('app-page', {
template: '#userBlock',
data: function() {
return{
users: []
}
},
ready: function () {
this.fetchUsers();
},
methods: {
fetchUsers: function(){
var users = [
{
id: 1,
name: 'tom'
},
{
id: 2,
name: 'brian'
},
{
id: 3,
name: 'sam'
},
];
this.$set('users', users);
}
}
})
JS for second component:
Vue.component('newtemp', {
template: '#newtemp',
props: 'name',
data: function() {
return {
name: name,
}
},
})
UPDATE
Ok, I've got the second step figured out. Here is a new fiddle showing the progress: https://jsfiddle.net/retrogradeMT/9pffnmjp/
Because I'm using Vue-router, I don't use props to send the data to a new component. Instead, I need set params on the v-link and then use a transition hook to accept it.
V-link changes see named routes in vue-router docs:
<a v-link="{ name: 'new', params: { name: user.name }}"> Show new component</a>
Then on the component, add data to the route options see transition hooks:
Vue.component('newtemp', {
template: '#newtemp',
route: {
data: function(transition) {
transition.next({
// saving the id which is passed in url
name: transition.to.params.name
});
}
},
data: function() {
return {
name:name,
}
},
})
-------------Following is applicable only to Vue 1 --------------
Passing data can be done in multiple ways. The method depends on the type of use.
If you want to pass data from your html while you add a new component. That is done using props.
<my-component prop-name="value"></my-component>
This prop value will be available to your component only if you add the prop name prop-name to your props attribute.
When data is passed from a component to another component because of some dynamic or static event. That is done by using event dispatchers and broadcasters. So for example if you have a component structure like this:
<my-parent>
<my-child-A></my-child-A>
<my-child-B></my-child-B>
</my-parent>
And you want to send data from <my-child-A> to <my-child-B> then in <my-child-A> you will have to dispatch an event:
this.$dispatch('event_name', data);
This event will travel all the way up the parent chain. And from whichever parent you have a branch toward <my-child-B> you broadcast the event along with the data. So in the parent:
events:{
'event_name' : function(data){
this.$broadcast('event_name', data);
},
Now this broadcast will travel down the child chain. And at whichever child you want to grab the event, in our case <my-child-B> we will add another event:
events: {
'event_name' : function(data){
// Your code.
},
},
The third way to pass data is through parameters in v-links. This method is used when components chains are completely destroyed or in cases when the URI changes. And i can see you already understand them.
Decide what type of data communication you want, and choose appropriately.
The best way to send data from a parent component to a child is using props.
Passing data from parent to child via props
Declare props (array or object) in the child
Pass it to the child via <child :name="variableOnParent">
See demo below:
Vue.component('child-comp', {
props: ['message'], // declare the props
template: '<p>At child-comp, using props in the template: {{ message }}</p>',
mounted: function () {
console.log('The props are also available in JS:', this.message);
}
})
new Vue({
el: '#app',
data: {
variableAtParent: 'DATA FROM PARENT!'
}
})
<script src="https://unpkg.com/vue#2.5.13/dist/vue.min.js"></script>
<div id="app">
<p>At Parent: {{ variableAtParent }}<br>And is reactive (edit it) <input v-model="variableAtParent"></p>
<child-comp :message="variableAtParent"></child-comp>
</div>
I think the issue is here:
<template id="newtemp" :name ="{{user.name}}">
When you prefix the prop with : you are indicating to Vue that it is a variable, not a string. So you don't need the {{}} around user.name. Try:
<template id="newtemp" :name ="user.name">
EDIT-----
The above is true, but the bigger issue here is that when you change the URL and go to a new route, the original component disappears. In order to have the second component edit the parent data, the second component would need to be a child component of the first one, or just a part of the same component.
The above-mentioned responses work well but if you want to pass data between 2 sibling components, then the event bus can also be used.
Check out this blog which would help you understand better.
supppose for 2 components : CompA & CompB having same parent and main.js for setting up main vue app. For passing data from CompA to CompB without involving parent component you can do the following.
in main.js file, declare a separate global Vue instance, that will be event bus.
export const bus = new Vue();
In CompA, where the event is generated : you have to emit the event to bus.
methods: {
somethingHappened (){
bus.$emit('changedSomething', 'new data');
}
}
Now the task is to listen the emitted event, so, in CompB, you can listen like.
created (){
bus.$on('changedSomething', (newData) => {
console.log(newData);
})
}
Advantages:
Less & Clean code.
Parent should not involve in passing down data from 1 child comp to another ( as the number of children grows, it will become hard to maintain )
Follows pub-sub approach.
I've found a way to pass parent data to component scope in Vue, i think it's a little a bit of a hack but maybe this will help you.
1) Reference data in Vue Instance as an external object (data : dataObj)
2) Then in the data return function in the child component just return parentScope = dataObj and voila. Now you cann do things like {{ parentScope.prop }} and will work like a charm.
Good Luck!
I access main properties using $root.
Vue.component("example", {
template: `<div>$root.message</div>`
});
...
<example></example>
A global JS variable (object) can be used to pass data between components. Example: Passing data from Ammlogin.vue to Options.vue. In Ammlogin.vue rspData is set to the response from the server. In Options.vue the response from the server is made available via rspData.
index.html:
<script>
var rspData; // global - transfer data between components
</script>
Ammlogin.vue:
....
export default {
data: function() {return vueData},
methods: {
login: function(event){
event.preventDefault(); // otherwise the page is submitted...
vueData.errortxt = "";
axios.post('http://vueamm...../actions.php', { action: this.$data.action, user: this.$data.user, password: this.$data.password})
.then(function (response) {
vueData.user = '';
vueData.password = '';
// activate v-link via JS click...
// JSON.parse is not needed because it is already an object
if (response.data.result === "ok") {
rspData = response.data; // set global rspData
document.getElementById("loginid").click();
} else {
vueData.errortxt = "Felaktig avändare eller lösenord!"
}
})
.catch(function (error) {
// Wu oh! Something went wrong
vueData.errortxt = error.message;
});
},
....
Options.vue:
<template>
<main-layout>
<p>Alternativ</p>
<p>Resultat: {{rspData.result}}</p>
<p>Meddelande: {{rspData.data}}</p>
<v-link href='/'>Logga ut</v-link>
</main-layout>
</template>
<script>
import MainLayout from '../layouts/Main.vue'
import VLink from '../components/VLink.vue'
var optData = { rspData: rspData}; // rspData is global
export default {
data: function() {return optData},
components: {
MainLayout,
VLink
}
}
</script>

Categories

Resources