How to pass an imported function(not method) as a prop - vue.js

when passing dynamic props, we use : or v-bind. However, any variables within these v-binds refers to the data stored within the component rather than within the script (passes on data in the component that can be referenced using "this.data".
However, that is not what I want to do in this case, I want to pass down an imported function into a prop, which is referenced within the component without a "this." in front of the function. When I try to pass it on as a prop, it says "functionName" is defined but never used", how do you go about passing on imported functions as dynamic props? See the code below for more details.
<template>
<componentName
:propName="functionName"
/>
</template>
<script>
import {functionName} from "./helperFunctions.js"
export default {
components: {componentName}
}

why not passing as an event? however you can pass this function as a prop via getters:
<template>
<componentName
:propName="myFuncProp"
/>
</template>
<script>
import {functionName} from "./helperFunctions.js"
export default {
components: {componentName},
computed: {
myFuncProp () {
return functionName
}
}
}
</script>

Related

why this.$t('hello') vue i18n not work at data property until i refresh page but when in use in normal template works

**i have placed image below of my components i need to translate title and content form the array in home component and bind props to info component as u said $t does not work with data method how can i achieve with computed
pls help **
[home component][1]
[info component][2]
[1]: https://i.stack.imgur.com/fKRXq.png
[2]: https://i.stack.imgur.com/tWbt2.png
$t is a computed property and is not accessible from within the data method. To work around, make content a computed property.
It looks like you're rendering the result of some query, so make that a prop that's passed into your component, then consume the prop in your computed property:
<template>
<div>
<span>{{infonew.id}}</span>
<heading>{{infonew.title}}</heading>
<section>{{content}}</section>
</div>
</template>
<script>
export default {
name: 'InfoNews',
props: ['infonew'],
computed: {
content () {
return this.$t(this.infonew.content);
}
}
}
</script>

Dynamically update props

As simplified below, my app has a template with a custom component.
The data is passed from Template A to custom component as props (":list")
Template A:
<template>
...
<custom-component
v-for="list in listGroup"
:key="list.id_list"
:list="list"
/>
</template>
<script>
export default {
data() {
return {
listGroup: []
};
},
components: {
'custom-component':require("...").default
}
</script>
The custom component
<template>
...
</template>
<script>
export default {
props:["list];
...
}
</script>
Problem to solve:
A new item is added to the list sent as props.
I need the list (:list="list") to be dynamically updated so that the props in the custom component automatically reflect that update.
Thanks.
There are two ways to achieve that one way is to use a state management library(Vuex is recommended) the other is to use events.
Here is an example of using events:
create a file event-bus.js with the following content
import Vue from "vue";
export const EventBus = new Vue();
then in your component where you want to update list use this EventBus.$emit('eventName', data);
remember to import event-bus file
the listen to the event in the other component
EventBus.$on('eventName', function (details) {
//update list here
});

Dynamic component inside a component that is rendered with render() function

I saw in the docs that you can have a dynamic component inside your VueComponent like this :
<component :is="componentName" v-bind="componentProps" #custom-event="doSomething" />
I am trying to have one of these dynamic components inside a dynamically rendered component (with the render() function, not with an HTML template). Without too much hope, I've tried this :
render(createElement: CreateElement) {
return createElement('component', props: {
'is': 'TestComponent'
});
}
but I got
[Vue warn]: Unknown custom element: <component> - did you register the component correctly?
So again, not hoping too much for a miracle, I tried to import Component and declare it as a component :
#Component({
components: {
Component,
TestComponent
}
})
export default class DynamicThingy extends Vue {
render(createElement: CreateElement): VNode {
return createElement('Component', {
props: {
'is': 'TestComponent'
}
});
}
}
But then I get
[Vue warn]: Do not use built-in or reserved HTML elements as component id: Component
Any idea how that could be possible ?
The first parameter of createElement() must be either
An HTML tag name,
component options,
or async function resolving to one of these.
https://v2.vuejs.org/v2/guide/render-function.html#createElement-Arguments
So in a render function, you can simply create a function* that returns one or another component's options based on your desired criteria, and let that be your first argument. *This function is identical to the function you'd write to determine what goes into the :is prop)
You only need the dynamic component <component /> and :is prop in a template where you don't have the possibility to do it programmatically.
You can use this smart-list component from the vue docs as an example.

Overriding a props type in child component?

I'm using a third party component, and it expects a prop to be a particular type.
I wish to use a different type.
Is there a way to override the type of a child component prop?
Or would I have to use a computed property and modify the prop in the parent component to the type the child component requires?
In general i think the best way would be to do as you proposed: To "use a computed property and modify the prop in the parent component to the type the child component requires". If you have to do so in several places, you could outsource the logic into a mixin that will be imported whenever the given third-party component is used.
If modifying the type of the property in the parent component isn't an option, the best way to fulfill your needs would be creating your own component that extends from the third party component and overriding the needed property. (https://v2.vuejs.org/v2/api/#extends)
Keep in mind however that the dependency containing the third-party might get updated over time. You should probably stick to a fixed version if following this approach.
I created a simple example on how to extend and override components (You can check it out as CodeSandbox here: https://codesandbox.io/s/qq9y7nm8n4
App.vue:
<template>
<div id="app">
<h2>ExtendedComponent: </h2>
<extended-component :message="1" />
<h2>BaseComponent: </h2>
<base-component message="This shall be a string" />
</div>
</template>
<script>
import ExtendedComponent from "./components/ExtendedComponent";
import BaseComponent from "./components/BaseComponent";
export default {
name: "App",
components: {
ExtendedComponent,
BaseComponent
}
};
</script>
BaseComponent.vue:
<template>
<div>
<h3>prop type: {{ typeof message }}</h3>
</div>
</template>
<script>
export default {
name: "BaseComponent",
props: {
message: {
type: String,
required: false
}
}
};
</script>
ExtendedComponent.vue:
<script>
import BaseComponent from "./BaseComponent";
export default {
name: "ExtendedComponent",
extends: BaseComponent,
props: {
message: {
type: Number,
required: false
}
}
};
</script>

How to create a reusable component in VueJs?

I would like to create Side Panel as a reusable component in Framework7 with VueJS. Here is my code..
Card.vue
<f7-card>
<f7-card-header>Card header content</f7-card-header>
<f7-card-content><img src="https://wiki.videolan.org/images/Ubuntu-logo.png"></img></f7-card-content>
<f7-card-footer>Card footer content</f7-card-footer>
</f7-card>
Now i registered as a component like below,
import Vue from 'vue'
export default [
{
path: '/card/',
component: require('./Card')
},
]
In later vues i imported as,
import Card from './Card.vue'
and i try to access in another vues like,
Now i'm getting an error like
[Vue warn]: Unknown custom element: - did you register the
component correctly? For recursive components, make sure to provide
the "name" option.
Can anyone help me where have i mistaken?
Thanks,
It's not really clear from your code exactly what you are doing, but the error you are getting happens when you try to use a component as a child of another component without registering it in the parent's components setting like this:
<script>
import Card from './Card.vue'
export default {
data () {
return {
somedata: 'some value'
}
},
components: {Card: Card}, // <- you're missing this
// etc...
}
</script>
You can also register components globally. More here: https://v2.vuejs.org/v2/guide/components.html#Local-Registration
Are you showing us all of Card.vue? For a valid single-file vue component, I would expect to see <template>, <script> and <style> elements. The render function will be generated from whatever you put in the <template> element.
Make sure that the component that you want to reuse is wrapped inside a template tag
As follows
<template>
<div>
<component data/>
<div/>
<template/>
Then register it inside the parent
Like so
export default {
name: "Card",
components: {
Card
},
};