Vue Component Event triggers but doesnt do anything - javascript

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

Related

Vue 3 pass data in <slot>

What I am trying to achieve:
Display an image from dynamic link in Post.vue, which follows the layout of PostLayout.vue
In PostLayout.vue, I have a <slot> named postFeaturedImage, and inside the slot, there is a <div>, I want to use the image as the background of it.
What I am using:
Laravel, InertiaJS, Vue 3
My codes are:
Post.vue:
<template>
<PostLayout>
<template #postfeaturedImage>
<!-- Here I want to display the image -->
</template>
</PostLayout>
</template>
<script>
import PostLayout from '#/Layouts/PostLayout'
export default {
data() {
return {
featured_image: ''
}
},
components: {
PostLayout,
},
props: {
post: Object /* Passed the prop from Controller */
},
mounted () {
this.featured_image = this.post.featured_image
}
}
</script>
PostLayout.vue:
<template>
<slot name="postfeaturedImage" :bgImage="bgImage">
<div :style="`background-image:url(${bgImage}); height: 75vh;`"></div>
</slot>
</template>
<script>
export default {
}
</script>
I've removed all irrelevant codes. I am a beginner in Vue 3 and Inertia and in need of help!
An alternative approach will be creating a FeaturedImage component. Also, you can reference the post image directly from the props you receiving. There's no need for the data method and the mounted in this case.
<template>
<PostLayout>
<template #postfeaturedImage>
<FeaturedImage :src="post.featured_image" />
</template>
</PostLayout>
</template>
<script>
import PostLayout from '#/Layouts/PostLayout'
import FeaturedImage from '#/Layouts/FeaturedImage'
export default {
components: {
PostLayout,
FeaturedImage
},
props: {
post: Object
}
}
</script>
Add a props to your PostLayout.vue
<script>
export default {
props: {
bgImage: { type: String },
},
};
</script>
And give a value to that props in your Post.vue
<template>
<PostLayout :bgImage="featured_image"> </PostLayout>
</template>
And if you ever want to have a post without an image and a different layout you should do :
<template>
<PostLayout>
<template #postfeaturedImage> post without background image</template>
</PostLayout>
</template>

overriding child method with parent method in vue.js

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>

vue - How a normal link could act like <route-link>?

I have two pages routed:
Home > Results
Inside 'Home', I have a button/link which is not in <route-view/> and I want this button to redirect to Results.vue passing a parameter.
This parameter named activeTab, has to open the desired vue-tabs, which I can't accomplish, because it's getting nothing from variable:
code:
Home.vue
<div class="row">
<Notes refName="Relationship" />
<Notes refName="Support" />
</div>
...
<script>
import Notes from '#/components/Monthlynotes.vue'
export default {
name: 'home',
components: {
Notes
},
</script>
/components/Monthlynotes.vue
<b-card>
<p class="card-text">{{ refName }}</p>
<b-link class="right" :activeTab="refName" href="/results">More</b-link>
</b-card>
...
<script>
export default {
props: {
refName: String,
},
</script>
Results.vue
<vue-tabs type="pills" v-model="tabName">
<v-tab title="Relationship">
<RelDT msg="Results view"/>
</v-tab>
<v-tab title="Support">
<SupDT msg="Results view"/>
</v-tab>
</vue-tabs>
...
<script>
import RelDT from '#/components/DataTable.rel.vue'
import SupDT from '#/components/DataTable.sup.vue'
export default {
name: 'results',
props: {
activeTab: String
},
components:
{
RelDT,
SupDT,
},
data() {
return {
tabName: activeTab
}
}
}
</script>
App
<router-link :to="{name:'results', param:{activeTab}}">Results</router-link>
How can I make this <b-link> route if it was a <route-link />?
Even the b-link component supports the :to property. To be found here
The value of the property will be passed to router.push().
<b-link :to="{name:'results', param:{activeTab}}">Redirect me</b-link>

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.

Vue.js pass callback through a prop.

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

Categories