I've got a component that looks like this:
<template>
<div>
<pagination class="center" :pagination="pagination" :callback="loadData" :options="paginationOptions"></pagination>
</div>
</template>
<script>
import Pagination from 'vue-bootstrap-pagination';
export default {
components: { Pagination },
props: ['pagination', 'loadData'],
data() {
return {
paginationOptions: {
offset: 5,
previousText: 'Terug',
nextText: 'Volgende',
alwaysShowPrevNext: false
}
}
}
}
</script>
In another component I use that ^:
<template>
<pagination :pagination="pagination" :callback="loadData" :options="paginationOptions"></pagination>
</template>
<script>
export default {
loadData() {
this.fetchMessages(this.pagination.current_page);
}
//fetchMessages
}
</script>
But I receive the error:
Invalid prop: type check failed for prop "callback". Expected Function, got Undefined.
(found in component <pagination>)
Is it not possible in Vue.js 2.0 to pass a callback?
I think your second component may not be written accurately, your loadData callback should be in methods:
<template>
<pagination :pagination="pagination" :callback="loadData" :options="paginationOptions"></pagination>
</template>
<script>
export default {
methods: {
loadData() {
this.fetchMessages(this.pagination.current_page);
}
}
}
</script>
App.vue
<template>
<div>
<pre>{{ request }}</pre>
<pagination #callback="loadData"></pagination>
</div>
</template>
<script>
import Pagination from './Pagination.vue'
export default {
name: 'App',
components: { Pagination },
data() {
return {
request: {}
}
},
methods: {
loadData(request) {
this.request = request
}
}
}
</script>
Pagination.vue:
<template>
<div>
<button #click="$emit('callback', { currentPage: 10, whatEver: 7 })">call it back</button>
</div>
</template>
<script>
export default {
name: 'Pagination'
}
</script>
https://codesandbox.io/embed/8xyy4m9kq8
Related
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
I have three components component-1, component-2, and an App component, I pass a Boolean props from component-1 to component-2 then using #click event I change the props value from true to false and vice versa
App.vue
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png" width="20%" />
<component1 />
</div>
</template>
component-1.vue
<template>
<div>
<component2 :have-banner="true" />
</div>
</template>
<script>
import component2 from "./component-2";
export default {
components: {
component2,
},
};
</script>
component-2.vue
<template>
<div>
<button #click="AssignBanner = !AssignBanner">Click me</button>
<p>{{ AssignBanner }}</p>
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
haveBanner: Boolean,
},
data() {
return {
AssignBanner: this.haveBanner,
};
},
};
</script>
I want to get the value of the props in component-1, that is, I want to track the changing value in component-1, since I want to write some logic, but I can’t keep track of the value in component-1.
You can see the given code in codesandbox
Looks like you want to achieve two-way binding for the prop haveBanner. You can achieve this with the .sync modifier if you are using Vue 2.3+.
component-1.vue
<template>
<div>
<component2 :have-banner.sync="haveBanner" />
</div>
</template>
<script>
import component2 from "./component-2";
export default {
components: {
component2,
},
data() {
return {
haveBanner: true,
}
},
};
</script>
component-2.vue
<template>
<div>
<button #click="assignBanner = !assignBanner">Click me</button>
<p>{{ assignBanner }}</p>
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
haveBanner: Boolean,
},
data() {
return {
assignBanner: this.haveBanner,
};
},
watch: {
assignBanner(value) {
// propagate to parent component
this.$emit('update:haveBanner', value)
},
},
};
</script>
suppose I have a child component
save-button.vue
<template>
<!--some code like label/div-->
<button #click="save">Save</button>
<!--some code like label/div-->
</template>
<script>
export default{
methods:{
save(){
//some code here
}
}
}
</script>
parent.vue
<save-button/>
...
<script>
export default{
methods:{
save(){
//some codes
}
}
}
</script>
Now in the parent component, I need to override the save function in save-button.vue with the save function in parent.vue. How should I do it? The save function in save-button.vue is shared by a lot of other components
You can pass the function as a non-required prop.
Parent
<template>
<div id="app">Using Parent:
<SaveButton :save="save"/>Using Default:
<SaveButton/>
</div>
</template>
<script>
import SaveButton from "./components/SaveButton";
export default {
components: {
SaveButton
},
methods: {
save() {
console.log("Save from Parent !");
}
}
};
</script>
Child
<template>
<div>
<button #click="saveClicked">Save</button>
</div>
</template>
<script>
export default {
props: {
save: {
type: Function,
default: null
}
},
methods: {
saveClicked() {
if (this.save) {
this.save();
return;
}
console.log("Save from the Child !");
}
}
};
</script>
I want to set the 'visualizacao' variable to true in a click of a button, but this button is in another component.
COMPONENT 1 with the visualizacao variable
<template>
<div>
<card-patrimonial v-if="!visualizacao"/>
<visualizacao-patrimonial v-else/>
</div>
</template>
<script>
import Patrimonial from '#/modules/Casos/Patrimonial/_components/Patrimonial.vue';
import VisualizacaoPatrimonial from '#/modules/Casos/Patrimonial/_components/VisualizacaoPatrimonial.vue';
export default {
name: "CasosPartes",
components: {
'card-patrimonial': Patrimonial,
'visualizacao-patrimonial': VisualizacaoPatrimonial,
},
data(){
return{
visualizacao: false
}
}
}
</script>
COMPONENT 2 with the button to change the variable visualizacao of component 1
<template>
<button>Change component</button
</template>
<script>
export default {
data() {
return {
}
}
}
</script>
How can I do this with emit?
In Component2:
<template>
<button #click="changeComponent()">Change component</button
</template>
<script>
export default {
data() {
return {
}
},
methods: {
changeComponent(){
this.$emit("listenButtonEvent");
}
}
}
</script>
In Component 1:
<template>
<div>
<card-patrimonial #changeComponent="changeVisualizacao" v-if="!visualizacao"/>
<visualizacao-patrimonial v-else/>
</div>
</template>
<script>
import Patrimonial from '#/modules/Casos/Patrimonial/_components/Patrimonial.vue';
import VisualizacaoPatrimonial from '#/modules/Casos/Patrimonial/_components/VisualizacaoPatrimonial.vue';
export default {
name: "CasosPartes",
components: {
'card-patrimonial': Patrimonial,
'visualizacao-patrimonial': VisualizacaoPatrimonial,
},
data(){
return{
visualizacao: false
}
},
methods: {
changeVisualizacao(){
this.visualizacao = true;
}
}
}
</script>
Here is an example: https://jsfiddle.net/z2v3nsuq/
const Clicker = {
template: `<button #click="$emit('clicked')">Click me</button>`,
};
new Vue({
el: '#app',
components: { Clicker },
data() {
return {
clickCount: 0,
};
},
});
I have two files named Recursive.vue and Value.vue.
In the first instance Recursive is the parent. Mounting Recursive in Recursive goes great, same for mounting Value in Recursive and after that Value in Value.
But when I've mounted Value in Recursive and trying to mount Recursive in Value after that I get the following error:
[Vue warn]: Failed to mount component: template or render function not defined.
(found in component <recursive>)
How can I make my problem work?
This is what my files are looking like:
Recursive
<template>
<div class="recursive">
<h1 #click="toggle">{{comps}}</h1>
<div v-if="isEven">
Hello
<value :comps="comps"></value>
</div>
</div>
</template>
<script>
import Value from './Value.vue'
export default {
name: 'recursive',
components: {
Value
},
props: {
comps: Number
},
computed: {
isEven () {
return this.comps % 2 == 0;
}
},
methods: {
toggle () {
this.comps++;
}
}
}
</script>
Value
<template>
<div class="value">
<h1 #click="toggle">{{comps}}</h1>
<div v-if="isEven">
<recursive :comps="comps"></recursive>
</div>
</div>
</template>
<script>
import Recursive from './Recursive.vue'
export default {
name: 'value',
components: {
Recursive
},
props: {
comps: Number
},
computed: {
isEven () {
return this.comps % 2 == 0;
}
},
methods: {
toggle () {
this.comps++;
}
}
}
</script>
Mounter
<template>
<div class="mounter">
<h1>HI</h1>
<recursive :comps="comps"></recursive>
</div>
</template>
<script>
import Recursive from './Recursive'
export default {
name: 'mounter',
components: {
Recursive
},
data () {
return {
comps: 0
}
}
}
</script>
I had a similar problem before. The only way out was declaring the component as "global", because importing it in the component which actually required it never worked.
new Vue({
...
})
Vue.component('recursive', require('./Recursive'))
Then you can just use without importing:
// Mounted
<template>
<div class="mounter">
<h1>HI</h1>
<recursive :comps="comps"></recursive>
</div>
</template>
<script>
export default {
name: 'mounter',
data () {
return {
comps: 0
}
}
}
</script>