How to store a value from another component's data? - javascript

I have two components, is there a way to store value from another component's data?
Here is Create.vue
<template>
<div id="main">
<Editor />
//some codes here
</div>
</template>
<script>
import Editor from './_Create_Editor.vue'
export default {
components: { Editor },
data: () => ({
text: ''
}),
}
</script>
And here is the _Create_Editor.vue.
<template>
//sample input for demonstration purposes
<input type="text" class="form-control" v-model="text"/>
</template>
The code above returns an error:
Property or method "text" is not defined on the instance but referenced during render
I want everytime I type the data: text from Create.vue has the value of it.
How can I possibly make this? Please help.

You can do this by using $emit.
Create.vue
<template>
<div id="main">
<Editor
#edit={onChangeText}
/>
//some codes here
</div>
</template>
<script>
import Editor from './_Create_Editor.vue'
export default {
components: { Editor },
data: () => ({
text: ''
}),
methods: {
onChangeText: function (value) {
this.text = value
}
}
}
</script>
_Create_Editor.vue
<template>
//sample input for demonstration purposes
<input
type="text"
class="form-control"
#change="onChange"
/>
</template>
<script>
export default {
methods: {
onChange: function (event) {
this.$emit('edit', event.target.value)
}
}
}
</script>

Related

How to hide content when clicked checkbox from different components in vuejs?

//inputtwo.vue
<template>
<div><input type="checkbox" v-model="checked" />one</div>
</template>
<script>
export default {
name: "inputtwo",
components: {},
data() {
return {};
},
};
</script>
//maincontent.vue
<template>
<div>
<div class="container" id="app-container" v-if="!checked">
<p>Text is visible</p>
</div>
<common />
</div>
</template>
<script>
export default {
name: "maincontent",
components: {},
data() {
return {
checked: false,
};
},
methods: {
hidecont() {
this.checked = !this.checked;
},
},
};
</script>
//inputone.vue
<template>
<div><input type="checkbox" v-model="checked" />one</div>
</template>
<script>
export default {
name: "inputone",
components: {},
data() {
return {};
},
};
</script>
How to hide content of checkbox from different components in Vuejs
I have three components called inputone(contains checkbox with v-model),inputtwo (contains checkbox with v-model),maincontent.(having some content and logic), So when user click on checkboxes from either one checckbox(one,two). i schould hide the content.
Codesanfdbox link https://codesandbox.io/s/crimson-fog-wx9uo?file=/src/components/maincontent/maincontent.vue
reference code:- https://codepen.io/dhanunjayt/pen/mdBeVMK
You are actually not syncing the data between components. The main content checked never changes. You have to communicate data between parent and child components or this won't work. And try using reusable components like instead of creating inputone and inputtwo for same checkbox create a generic checkbox component and pass props to it. It is a good practice and keeps the codebase more manageable in the longer run.
App.vue
<template>
<div id="app">
<maincontent :showContent="showContent" />
<inputcheckbox text="one" v-model="checkedOne" />
<inputcheckbox text="two" v-model="checkedTwo" />
</div>
</template>
<script>
import maincontent from "./components/maincontent/maincontent.vue";
import inputcheckbox from "./components/a/inputcheckbox.vue";
export default {
name: "App",
components: {
maincontent,
inputcheckbox,
},
computed: {
showContent() {
return !(this.checkedOne || this.checkedTwo);
},
},
data() {
return {
checkedOne: false,
checkedTwo: false,
};
},
};
</script>
checkbox component:
<template>
<div>
<input
type="checkbox"
:checked="value"
#change="$emit('input', $event.target.checked)"
/>
{{ text }}
</div>
</template>
<script>
export default {
name: "inputcheckbox",
props: ["value", "text"],
};
</script>
Content:
<template>
<div class="container" id="app-container" v-if="showContent">
<p>Text is visible</p>
</div>
</template>
<script>
export default {
name: "maincontent",
props: ["showContent"]
}
</script>
https://codesandbox.io/embed/confident-buck-kith5?fontsize=14&hidenavigation=1&theme=dark
Hope this helps and you can learn about passing data between parent and child components in Vue documentation: https://v2.vuejs.org/v2/guide/components.html
Consider using Vuex to store and maintain the state of the checkbox. If you're not familiar with Vuex, it's a reactive datastore. The information in the datastore is accessible across your entire application.

Input values not resetting - vuejs

I have a level 2 input field component that i am using. I want to reset on button click from the parent component. I am trying to pass the data to base initial input field and then emitting back to the parent.
My question is that when i try to reset the data on button click the value from the parent component its not working.
Data is not set to null and the values remain as 123.
What wrong I am doing in the following code.
Any help would be appreciated.
Base Input
<template>
<input
v-model="myValue"
type="number"
inputmode="numeric"
#input="$emit( 'input', $event.target.value )"
/>
</template>
<script>
export default {
data () {
return {
myValue: undefined
};
}
}
};
</script>
Level 01
<template>
<div class="c-floating-label">
<input-number #input="passValue" />
</div>
</template>
<script>
import InputNumber from '../../atoms/form-controls/BaseInput';
export default {
components: {
InputNumber
}
methods: {
passValue: function (value) {
this.$emit('input', value);
}
}
};
</script>
Main Component
<div>
<level-01
:required="true"
:v-model="datax.cardNumber"
value="datax.cardNumber"
/>
<button #click="reset">click me</button>
</div>
<script>
data () {
return {
datax: {
cardNumber: undefined
}
};
},
created() {
this.datax.cardNumber = 123;
},
methods: {
reset () {
this.datax.cardNumber = null;
},
</script>
You missed binding on MainComponent
<level-01
:required="true"
:v-model="datax.cardNumber"
:value="datax.cardNumber"
/>
Note :value="datax.cardNumber" is correct
Second, in level-01 you do not bind value prop (not defined at all)
<template>
<div class="c-floating-label">
<input-number #input="passValue" :value="$attrs.value"/>
</div>
</template>
<script>
import InputNumber from '../../atoms/form-controls/BaseInput';
export default {
components: {
InputNumber
},
methods: {
passValue: function (value) {
this.$emit('input', value);
}
}
};
</script>
And finally BaseComponent:
<template>
<input
:value="$attrs.value"
type="number"
inputmode="numeric"
#input="$emit( 'input', $event )"
/>
</template>
<script>
export default {
data () {
return {
// myValue: undefined
};
}
}
};
</script>

Data passed as undefined from child to parent component

I am making a file selection in the child component and once file is selected I want to pass the selected file to the parent component. I am not able to figure out how to do that. Please help out. If I try to get the print the value inside the onDocumentSelected(value) it comes out to be undefined.
Error message
Property or method "value" is not defined on the instance but referenced during render
Parent Component
<template>
<v-form :model='agency'>
<DocumentSelect
type="file"
ref="file"
:required="true"
name="vue-file-input"
#change="onDocumentSelected(value)"
/>
</v-form>
</template>
<script>
import DocumentSelect from 'views/document-selection.vue';
export default {
components: {
DocumentSelect
},
props: ['agency'],
methods: {
onDocumentSelected(value) {
console.log(value); //undefined
},
}
};
</script>
Child Component
<template>
<div class="input-group input-group--select primary--text" :class="{'input-group--required': required, 'input-group--error': hasError, 'error--text': hasError}" >
<div class="input-group__input">
<input
type="file"
name="name"
ref="file"
#change="onDocumentSelected" />
</div>
<div class="input-group__details">
<div class="input-group__messages input-group__error" v-for="error in errorBucket">
{{error}}
</div>
</div>
</div>
</template>
<script>
import Validatable from 'vuetify/es5/mixins/validatable.js'
export default {
mixins: [Validatable],
props: ['type', 'name', 'required'],
data: function () {
return {
inputValue: ''
};
},
watch: {
inputValue: function(value) {
this.validate();
console.log(value); // *Event {isTrusted: true, type: "change", target: input, currentTarget: null, eventPhase: 0, …}*
this.$emit('change', {value});
},
},
methods: {
onFileSelected(event) {
this.inputValue = event
},
},
};
</script>
Get rid of your watch method and move the logic inside onFileSelected:
#change="onFileSelected($event)"
onFileSelected(e) {
this.validate();
this.$emit('document-selected', e);
}
Then, in the parent, listen for the document-selected event:
<DocumentSelect
type="file"
ref="file"
:required="true"
name="vue-file-input"
#document-selected="onDocumentSelected($event)"
/>
You then have access to that value to do what you want with.

Automatically update the input field within a form, vue.js

I want to search for elements using an input field within a form. I am passing a value from a component to another and the content changes but only after pressing enter. Is there a way to automatically update the list, after every new letter is typed?
Here is my code:
Parent(App):
<template>
<div id="app">
<Header v-on:phrase-search="passPhrase" />
</div>
</template>
<script>
import Header from ...
export default {
name: "App",
components: {
Header,
},
data() {
return {
posts: [],
searchedPhrase: ""
};
}
computed: {
filteredPosts() {
let temp_text = this.searchedPhrase;
temp_text.trim().toLowerCase();
return this.posts.filter(post => {
return post.name.toLowerCase().match(temp_text);
});
}
},
methods: {
passPhrase(phrase) {
this.searchedPhrase = phrase;
}
}
};
</script>
Child(Header):
<template>
<div class="child">
<p>Search:</p>
<form #submit.prevent="phrasePassed">
<input type="text" v-model="phrase" />
</form>
</div>
</template>
<script>
export default {
name: "search",
data() {
return {
phrase: ""
};
},
methods: {
phrasePassed() {
this.$emit("phrase-search", this.phrase);
}
}
};
</script>
passPhrase() brings the value from the child to the parent and then filteredPosts() find appropriate elements. I suspect that the form might be guilty of this issue but I do not know precisely how to get rid of it and still be able to pass the value to the parent.
Thanks
in the child you use submit event which called on enter. you should use #input on the input itself. and btw you didnt need even to declare pharse in the data because you didnt use it in the child. you just pass it up
you it like so
<template>
<div class="child">
<p>Search:</p>
<form>
<input type="text" #input="phrasePassed">
</form>
</div>
</template>
<script>
export default {
name: "search",
methods: {
phrasePassed(e) {
this.$emit("phrase-search", e.target.value);
}
}
};
</script>

How to test if a component emits an event in Vue?

I have two components. Child component emits an 'input' event when it's value changed and parent component takes this value with v-model. I'm testing ChildComponent. I need to write a test with Vue-test-utils to verify it works.
ParentComponent.vue:
<template>
<div>
<child-component v-model="search"></child-component>
<other-component></other-component>
...
</div>
</template>
ChildComponent.vue:
<template>
<input :value="value" #change="notifyChange($event.target.value)"></input>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'
#Component
export default class ChildComponent extends Vue {
#Prop({ default: '' }) readonly value!: string
notifyChange(value: string) {
this.$emit('input', value)
}
}
</script>
child-component.spec.ts:
describe('ChildComponent', () => {
let wrapper: any
before(() => {
wrapper = VueTestUtils.shallowMount(ChildComponent, {})
})
it(`Should emit 'input' event when value change`, () => {
const rootWrapper = VueTestUtils.shallowMount(ParentComponent)
wrapper.vm.value = 'Value'
wrapper.findAll('input').at(0).trigger('change')
assert.isTrue(!!rootWrapper.vm.search)
})
})
I didn't write the exact same code but the logic is like this.
My components work properly. 'child-component.spec.ts' doesn't work. I need to write a test for it.
TESTED.
This is a simple way of testing an emit, if someone is looking for this.
in your test describe write this.
describe('Close Button method', () => {
it('emits return false if button is clicked', (done) => {
wrapper.find('button').trigger('click')
wrapper.vm.$nextTick(() => {
wrapper.vm.closeModal() //closeModal is my method
expect(wrapper.emitted().input[0]).toEqual([false]) //test if it changes
done()
})
})
})
my vue comp
<div v-if="closeButton == true">
<button
#click="closeModal()"
>
...
</button>
</div>
my props in vue comp
props: {
value: {
type: Boolean,
default: false
},
my methods in vue comp
methods: {
closeModal() {
this.$emit('input', !this.value)
}
}
Here's an example that will help you:
Child Component.vue
<template>
<div>
<h2>{{ numbers }}</h2>
<input v-model="number" type="number" />
<button #click="$emit('number-added', Number(number))">
Add new number
</button>
</div>
</template>
<script>
export default {
name: "ChildComponent",
props: {
numbers: Array
},
data() {
return {
number: 0
};
}
};
</script>
Parent Component.vue
<template>
<div>
<ChildComponent
:numbers="numbers"
#number-added="numbers.push($event)"
/>
</div>
</template>
<script>
import ChildComponent from "./ChildComponent";
export default {
name: "ParentComponent",
data() {
return {
numbers: [1, 2, 3]
};
},
components: {
ChildComponent
}
};
</script>
Follow this article: https://medium.com/fullstackio/managing-state-in-vue-js-23a0352b1c87
I hope this will help you.
in your parent component listen to the emitted event "input"
<template>
<div>
<child-component #input="get_input_value" v-model="search"></child-component>
<other-component></other-component>
...
</div>
</template>
and in your script add method get_input_value()
<script>
...
methods:
get_input_value(value){
console.log(value)
}
</script>

Categories

Resources