On my first vue training. Maybe it is the most obvious question... how can i print the input text (the search term typed in the input field) over using the double curly braces {{}} in the App.vue file?
This is the APP.vue
<template>
<SearchBar #emitTermSearch="onTermSearch"></SearchBar>
</template>
<script>
import SearchBar from "./components/SearchBar";
export default {
name: "App",
components: {
SearchBar
},
methods: {
onTermSearch(emitTermSearch) {
console.log(emitTermSearch);
}
}
};
</script>
This is the SearchBar.vue
<div id="searchbar">
<input #input="onInput" />
</div>
</template>
<script>
export default {
name: "SearchBar",
methods: {
onInput(event) {
this.$emit("emitTermSearch", event.target.value);
}
}
};
</script>
you can store it as a variable
<template>
<SearchBar #emitTermSearch="onTermSearch"></SearchBar>
{{searchVal}}
</template>
<script>
import SearchBar from "./components/SearchBar";
export default {
name: "App",
components: {
SearchBar
},
data():{
return{
searchVal: null
}
},
methods: {
onTermSearch(emitTermSearch) {
this.searchVal = emitTermSearch;
}
}
};
</script>
Related
if i have component LogoutButton.vue
export default {
data()
{
return {
}
},
methods:
{
Logout()
{
console.log("something")
}
}
}
</script>
<template>
<button #click="Logout">Logout</button>
</template>
How can i use the LogoutButton component inside other component?
I mean how can i import the component and its click methods inside other component?
<script>
import LogoutButton from './LogoutButton.vue'
export default {
components: {
LogoutButton
},
data()
{
return {
}
},
methods:
{
// Your different methods
}
}
</script>
<template>
<div>
<!-- The template from LogoutButton component will display here -->
<LogoutButton />
</div>
</template>
Using Vue3, I've got a Datepicker component using the litepie-datepicker
<template>
<div class="flex">
<litepie-datepicker
as-single
v-model="dateValue"
></litepie-datepicker>
</div>
</template>
<script>
import { ref } from 'vue';
import LitepieDatepicker from 'litepie-datepicker';
export default {
components: {
LitepieDatepicker
},
setup() {
const dateValue = ref([]);
return {
dateValue
};
},
};
</script>
When I pick a date, and console.log dateValue in the component setup function, I can see the date I just picked.
But, when I use the component in another View, I cannot figure out how to capture the dateValue.
Here is my newView.vue code
<template>
<div>
<date-picker v-model="dateValue" />
<button #click="test">test</button>
</div>
</template>
<script>
import DatePicker from '../../components/DatePicker.vue'
export default {
components: {
DatePicker,
},
data(){
return{
dateValue: '',
}
},
methods: {
test(){
console.log(this.dateValue);
}
}
}
</script>
The test function is printing an empty variable. How can I get the dateValue value in this newView.vue ?
Thanks a lot for your help
I try to transfer data to my component using props
If I type the name in the parent, I see that the button is working properly, ie the problem is with the component.
Where am I wrong?
Thanks in advance
Parent:
HTML
<div><button #click="changeName" :name="name">Change my name</button></div>
Script:
import UserDetail from "./UserDetail.vue";
export default {
components: {
UserDetail,
UserEdit,
},
data() {
return {
name: "Eden",
};
},
methods: {
changeName() {
this.name = "EdenM";
},
},
};
Component
<template>
<div>
<p>{{ name }}</p>
</div>
</template>
<script>
export default {
props: ["name"],
};
</script>
Ooooooh!! I add the prop an wrong place!
Here is my ans:
<user-detail :name="name"></user-detail>
I have a 3rd party input component (a vuetify v-text-field).
For reasons of validation i prefer to wrap this component in my own.
my TextField.vue
<template>
<v-text-field
:label="label"
v-model="text"
#input="onInput"
#blur="onBlur"
:error-messages="this.getErrors(this.validation, this.errors)"
></v-text-field>
</template>
<script>
import VTextField from "vuetify/es5/components/VTextField";
import {vuelidateErrorsMixin} from '~/plugins/common.js';
export default {
name: "TextField",
props: ['label', 'value', 'validation', 'errors'],
mixins: [vuelidateErrorsMixin], //add vuelidate
data: function() {
return {
'text': this.value
}
},
components: {
VTextField
},
methods : {
onInput: function(value) {
this.$emit('input', value);
this.validation.$touch();
},
onBlur: function() {
this.validation.$touch();
}
},
watch: {
value: {
immediate: true,
handler: function (newValue) {
this.text = newValue
}
}
}
}
</script>
which is used in another component
<template>
...
<TextField v-model="personal.email" label="Email"
:validation="$v.personal.email" :errors="[]"/>
...
</template>
<script>
...imports etc.
export default { ...
data: function() {
return {
personal: {
email: '',
name: ''
}
}
},
components: [ TextField ]
}
</script>
This works fine but i wonder if there is a much more cleaner approach than to replicate the whole v-model approach again. As now my data is duplicated in 2 places + all the extra (non needed) event handling...
I just want to pass the reactive data directly through to the v-text-field from the original temlate. My TextField doesn't actually need access to that data at all - ONLY notified that the text has changed (done via the #input, #blur handlers). I do not wish to use VUEX as this has it's own problems dealing with input / forms...
Something more close to this...
<template>
<v-text-field
:label="label"
v-model="value" //?? SAME AS 'Mine'
#input="onNotify"
#blur="onNotify"
:error-messages="this.getErrors(this.validation, this.errors)"
></v-text-field>
</template>
<script>
import VTextField from "vuetify/es5/components/VTextField";
import {vuelidateErrorsMixin} from '~/plugins/common.js';
export default {
name: "TextField",
props: ['label', 'validation', 'errors'], //NO VALUE HERE as cannot use props...
mixins: [vuelidateErrorsMixin], //add vuelidate
components: {
VTextField
},
methods : {
onNotify: function() {
this.validation.$touch();
}
},
}
</script>
I cannot find anything that would do this.
Using props + v-model wrapping is what i do.
You need to forward the value prop down to the wrapped component, and forward the update event back up (see https://v2.vuejs.org/v2/guide/components.html#Using-v-model-on-Components for more details):
<template>
<wrapped-component
:value='value'
#input="update"
/>
</template>
<script>
import wrappedComponent from 'wrapped-component'
export default {
components: { 'wrapped-component': wrappedComponent },
props: ['value'],
methods: {
update(newValue) { this.$emit('input', newValue); }
}
}
</script>
Somewhere else:
<my-wrapping-component v-model='whatever'/>
I've create a mixin to simplify wrapping of a component.
You can see a sample here.
The mixin reuse the same pattern as you with "data" to pass the value and "watch" to update the value during a external change.
export default {
data: function() {
return {
dataValue: this.value
}
},
props: {
value: String
},
watch: {
value: {
immediate: true,
handler: function(newValue) {
this.dataValue = newValue
}
}
}
}
But on the wraping component, you can use "attrs" and "listeners" to passthrough all attributes and listener to your child component and override what you want.
<template>
<div>
<v-text-field
v-bind="$attrs"
solo
#blur="onBlur"
v-model="dataValue"
v-on="$listeners" />
</div>
</template>
<script>
import mixin from '../mixins/ComponentWrapper.js'
export default {
name: 'my-v-text-field',
mixins: [mixin],
methods: {
onBlur() {
console.log('onBlur')
}
}
}
</script>
Is it possible to bind a prop to a function?
In my example below I’m trying to get a value from a function in the main App.vue and pass it as a prop to the child component customComponent.
e.g. (this example doesn’t work)
App.vue
import customComponent from ‘./custom-component.vue'
<template>
<custom-component
v-bind:myValue="geMyValue()"
></custom-component>
</template>
<script>
export default {
name: "Item",
methods: {
getMyValue: function() {
return 1+3;
}
}
}
</script>
customComponent.vue
<template>
<h3 class="some-custom-layout">custom component</h3>
<input type="button" #click="sendMyValue()" />
</template>
<script>
export default {
name: “custom",
props: ['myValue']
methods: {
sendMyValue: function() {
console.log(this.myValue);
}
}
}
</script>
It's possible, but probably it would be better to use computed properties, if you are going to return value:
<template>
<custom-component
v-bind:myValue="myValue"
></custom-component>
</template>
<script>
export default {
name: "Item",
computed: {
myValue: function() {
return 1+3;
}
}
}
</script>
https://v2.vuejs.org/v2/guide/computed.html