Can't I use the mixins function of parent component in child component? - vue.js

I am using the mixins function in the vuejs to code efficiently.
And then, I had a question.
I have imported mixins 'TTS' in the parent component.
And then the child component called the function of the tts.
However, the function was not called.
Is the parent component mixtns function not available in the child component?
import { tts } from "../components/mixins/tts/tts";
export default {
mixins: [tts]
}
This is importing mixins in the parent component.
<ion-row
class="drawer_middle_menu ion-align-items-center ion-justify-content-center"
#click="trySpeak($t('timeOut'))"
>{{$t('timeOut')}}</ion-row>
And this is a child component.
The 'trySpeak' function is a function in TTS that was imported by the parent component.

No, you would need to either pass as a prop or import directly into child component. With that said there are not recommended ways such as $parent but I would stay away from that.
See here for more info:
https://v2.vuejs.org/v2/guide/components-edge-cases.html

Related

While using composition API, is there any way to re use props that are common for multiple components?

I am trying to migrate a mixin in Vue 2 to composable in vue 3. This mixin was created using class component syntax and all the form UI components (around 30 ) use this mixin. We defined all the common props in this mixin and as a result of that, all those common props were available for all the components that are using the mixin. Can we declare props within composable as well? If not, is there any other way to share reusable props from one commonplace? So that later if we need to change any one prop, we can change from one place instead of making the same change in every component that is using the prop.
import { Prop } from "vue-property-decorator";
import { Inject } from "inversify-props";
// 1: Can we use generic type in composable?
abstract class BaseForm<T> extends Vue{
// 1: This is a common property that all the form components will use
// Also some of the methods defined in this class would use this property
protected item: T = {} as T;
// 2: Common props for all the forms are defined
// Can we declare props composable as well?
// If not, is there any other way to enforce that all my components that are created using composition API
// get this prop from a commonplace?
#prop([required: true, type: Boolean])
protected edit!: boolean;
....
}

Ref not working on custom component in Vue3

I'm using Vue3 with the composition API. In a form-component I put ref's on each field (child-component).
For some reason the ref's of the custom components are different from ref's for Quasar components.
When I console.log a ref to a custom component I get this in DevTools:
Proxy {__v_skip: true}
(without any properties in Target)
while a ref to a Quasar components gives this :
Proxy {…}
(with all properties of the component in Target)
For this reason I can't use the ref to access properties or methods of these child components.
I have no idea what __v_skip even means.
My custom components are defined with script setup, could that be a reason?
Any idea how to fix this?
UPDATE
If I use defineExpose in the child components for the properties and methods I want to access from outside with a ref, it does work. Not really handy though, since these components have lots of props.
Seem likes currently you cannot access the custom component by ref, if your component is written by Composition API (<script setup>). But you can try the way I mention underneath.
In the Vue 3 doc, there are some lines mentioned this behavior:
An exception here is that components using <script setup> are private
by default: a parent component referencing a child component using
<script setup> won't be able to access anything unless the child
component chooses to expose a public interface using the defineExpose
macro
Read more here: Vue 3 - Ref on Component
That means if you want to access anything from the custom component, your component has to expose that information. I think it's because in Vue 3 you don't need to have root component anymore, so if you define a ref, Vue does not know what the component you want to ref to.
But...
You can try to use yourRef.value.$el, maybe it will help.
Example:
// Parent.vue
<template>
<Child ref="childRef">
</template>
<script setup lang="ts">
// Import things...
const childRef = ref<InstanceType<typeof Child> | null>(null);
onMounted(() => {
console.log(childRef.value.$el);
});
</script>

Call grandchild function from a child - vue.js

I have 4 components in vue, I want to call a grandchild function('refreshArtifact') from a child component, any idea how can I do it?
So here is my component hierarchy:
Parent : TeamManagment.vue
Children :TeamPlatform.vue & ManagementArtifcts.vue
GrandChild : TeamAction.vue (TeamPlatform.vue child)
i want to call the 'refreshArtifact' function in TeamAction.vue from the ManagmentArtifact.vue component.
In my opinion, you can't right now directly call a child function of a brother. So, with your code, you can't directly call a function of a component A, from a component B which is the brother of the A one.
But, you can do that with the grandparent component.
So, when the ManagmentArtifact.vue component need to call refreshArtifact function, you can emit an event. The TeamManagment.vue listen that event, and then pass use ref of TeamPlatform.vue component to call the function.
ManagmentArtifact.vue: this.$emit('callRefresh')
TeamManagment.vue: <ManagmentArtifact #callRefresh='refreshArtifact' />
<TeamPlatform ref='team' />
methods: { refreshArtifact(){ this.$ref.team.refreshArtifact() } }
You can read the doc here.

Any way to make a React presentational component react to MobX store changes

I have a React table component that gets its data via a prop called TableStore. This prop is a high-level abstraction for getting row data:
interface TableStore<RowType> {
getRowIds: () => Array<RowId>;
getRow: (rowId: RowId) => RowType | undefined;
}
interface MaterialTableProps<RowType> {
tableStore: TableStore<RowType>;
}
function MaterialTable<RowType>(props: MaterialTableProps<RowType>) {
...
}
As you can see MaterialTable is not a MobX observer. It is part of a component library that is not dependent on MobX.
When I use this component in my app, I supply it a MobX-based TableStore. I would like the table component to re-render whenever the MobX-based store changes:
<MaterialTable tableStore={orderStore} />
However that does not happen because the table component is not a MobX observer. Is there any way to force the table component to re-render? For example, I am able to force a re-render by dereferencing the store in the parent component (using a simple console.log()). But this feels like a hack. Is there a better way?
Answering my own question....
I looked at several options but all of them were kludgy. I finally decided to rework the props of the table component to pass in an array instead of an abstract TableStore interface (which the table component can't react to). This allowed me to refrain from adding MobX as a dependency to the table component library while still leverage MobX in the parent component. In summary, the parent component now watches the MobX store, reacts to changes by creating a new array and passing it to the table component.
Here's the new interface for the table component:
export interface MaterialTableProps<T extends Entity> extends TableProps {
entityList: Array<T>;
}
export function MaterialTable<T extends Entity>(props: MaterialTableProps<T>) {
...
}

Vue transparently wrap component, modify some props

I have a Vue component that's used multiple times with identical props. I'd like to keep the code DRY by always adding these props in a single place.
Example:
<wrapped-foo bar=1 />
should be extended to
<real-foo bar=1 spam=eggs />
I'm trying to solve this using a wrapper component that takes the props given, modifies them, and passes them to the wrapped component. There are multiple tutorials on how to do this, e.g.
vue wrap another component, passing props and events
https://v2.vuejs.org/v2/guide/render-function.html#Functional-Components
It looks like all of the solutions don't pass at least one of props, class, style, event listeners, other attributes, etc. to the wrapped component. Is there a solution that keeps all of these intact?
You can do it with Vue Mixins: https://v2.vuejs.org/v2/guide/mixins.html
Or simply with inheritance:
Example:
const wrappedFoo = Vue.component('real-foo').extend({
props: {
spam: ...
}
})
Vue.component('wrapped-foo', wrappedFoo)