Two Mixins with same name function Vuejs - vue.js

Hello I have this problem with vuejs and mixin.
I have a component that has 2 Mixin:
export default {
...
mixins:[Mixin1, Mixin2],
..
}
Both Mixins have a function named "delete", so If in my component I have a method like:
methods:{
deleteObj(){
this.delete()
}
}
I don't know which one function I call.
I know the simplest way is call with a different name the functions but is there a way to specify wich mixin to use?

If you duplicated definitions in methods in mixins, the last mixin will override the previous definitions. In your case this.delete() must called from Mixin2.
But if have lifecycle hooks like mounted, created ... those will be executed one by one in vuejs. There are some strategies followed for merging, vuejs itself you can found more at https://v2.vuejs.org/v2/guide/mixins.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;
....
}

Vuejs:Why is render method returning dynamic `<component>` giving errors?

I am trying to return vue's builtin <component/> from the render method, but it is not recognizing the component. what could be the possible mistake?
Vue.component('comp1',{
template:'<h1>Component1</h1>'
});
Vue.component('comp2',{
template:'<h1>Component2</h1>'
});
let app=new Vue({
el:'#app',
data:function(){
return {
comp:'comp1'
}
},
mounted:function(){
setInterval(()=>{
if(this.comp=='comp1'){
this.comp="comp2"
}else{
this.comp="comp1"
}
},1000);
},
render (h) {
return h('component', this.comp)
}
})
linkto js bin: https://jsbin.com/wakivet/edit?html,js,console,output
Replace:
render(h){
return h('component',this.comp);
}
with
template: '<component :is="comp" />'
There is no built-in component called component in Vue.
Vue needed a syntax for creating dynamic components in a template. It also needed a way to solve the problems caused by in-DOM templates requiring specific elements as children of other elements. Both of these problems could be solved the same way, with the introduction of the is attribute.
But even though the desired tag name is specified via the is attribute we still need to include a tag name in the template. Any tag will work, but the convention is to use the tag <component>.
<component :is="comp">
Using this convention allows other developers to know that the tag is dynamic. It also makes it easier for the Vue template compiler to optimise the template.
Vue will log a warning if anyone tries to register a global component called component, just like it would for other reserved tag names. This helps to ensure there's no ambiguity when those tags are used.
However, it is just a convention. Using other tags will work just fine and with in-DOM templates it is sometimes necessary, see https://v2.vuejs.org/v2/guide/components.html#DOM-Template-Parsing-Caveats.
But what about render functions?
The first argument passed to the function h is the tag name. We don't need to use tricks like the is attribute to make that dynamic, we can just pass it directly:
h(this.comp)
In fact, if you write a template containing <component :is="comp"> then Vue will compile it down to something very similar to this. The compiled render function doesn't keep the is attribute, it throws that away and just passes its value to the h function.
You can see this for yourself if you inspect a compiled template. For example, you can use the tool at https://v2.vuejs.org/v2/guide/render-function.html#Template-Compilation to see how templates are compiled to render functions. The function _c is what you called h.
So to reiterate, there is no such component as <component>. It is merely a placeholder in template syntax for some other component. When you're in a render function you should just use the desired component directly.

Vuejs how to use repeated methods in single components

How would I use the same method across different components without rewriting the same method for reach component. I looked into mixins but the documentation says 'Use global mixins sparsely and carefully'. So I'm wondering if there is a more ideal way for this approach. Same with global computed.
<template>
<div class="wrapper">
...
Link on many templates
...
</div>
</template>
<script>
export default {
data() {
return {}
},
methods: {
goToPage(page) {
return this.$store.commit('page/push', {page:page});
}
}
}
</script>
Thanks
Global mixins are not the only type of mixin. See https://v2.vuejs.org/v2/guide/mixins.html
If you want to add a method or computed property to every component then you'd use a global mixin. This would affect all components, including those from third party libraries. You'd need to be careful when choosing a name to ensure you don't collide with anything else. There's also a small performance overhead from using a global mixin. As an example, Vuex uses a global mixin to ensure that the $store property is present on all components.
If you only need to add the method/property to a few components then you'd be much better off with a normal mixin. Typically that would have its own file and look something like this:
// my-mixin.js
export default {
methods: {
goToPage(page) {
return this.$store.commit('page/push', {page:page});
}
}
}
and then within your .vue files:
<script>
import myMixin from 'my-mixin'
export default {
mixins: [myMixin],
// ... all the other options
}
</script>
Given the example in the question seems to be a navigational link, an alternative to using a mixin might be to introduce a suitable component to handle those links. Rather than sharing code between components you'd just use the link component. It would depend on whether the method has uses beyond those links.
There are alternatives, such as sharing things globally across components using Vue.prototype, but for the example given in the question that doesn't seem a good fit.
I would also note that Vue 3 introduces some new alternatives to mixins via the composition API. However, it isn't immediately obvious that using composition would actually be an improvement in your specific use case. Vue 3 is also still in beta.

Difference in Vue between data() and adding data in created()

Is there a difference between the following? I've seen examples doing both and am unsure why you would choose one over the other.
Vue.component('test', {
data() {
return { myDataA: 10 };
}
//vs
created() {
this.myDataB = 10;
}
}
Variables set in created() on this will not be reactive. In order for them to be reactive, you must define them in the object returned by data().
Example (note how the text does not change in the output):
https://jsfiddle.net/oyf4quyL/
in a component, there are three places where you can define you data:
data properties
computed properties
props
the created property is lifecycle hook in Vue. what this means, is that the Vue will run this function when the component is created. there are also other lifecycle hooks in Vue you can use, like mounted or beforeMount or beforeCreate and etc.
now with this in mind, let's answer your question.
when you define myDataA in data property, Vue will automatically create some "watchers" for this data property, so anytime that you set a new value to myDataA, anywhere that is using it, will be called again. but when you define a property directly on Vue instance (this), you will lose this "watchers" feature. (which by the way is just some getters and setters!)
so as i said, the best way and the correct way to define a data property is on any of the three places that i mentioned, based on your need. (because each of them has different use-cases that the others).

Pass Function as Property to Vue Component

I am trying to make my Vue Component reusable but there is a part in it which requires to run a function on button click which I have defined in the parent component.
The component's button will always run a parent function and the parameter it passes is always the same (its only other property).
Right now I am passing 2 properties to the component: 1) an object and 2) the parent function reference, which requires the object from 1) as a parameter.
The Child-Component looks like this (stripped unnecessary code):
<button v-on:click="parentMethod(placement)">Analyze</button>
Vue.component('reporting-placement', {
props: ['placement', 'method'],
template: '#reporting-placement',
methods: {
parentMethod: function(placement) {
this.method(placement);
}
}
});
The parent is making use of the child like this:
<reporting-placement v-bind:placement="placement" v-bind:method="analyzePlacement"></reporting-placement>
methods: {
analyzePlacement: function(placement) {
this.active_placement = placement;
},
}
As you can see, the child has only one property, placement, and the callback reference. The placement must be put in as a parameter to the reference function from the parent.
But since the parent defines the parameters, the child shouldn't concern itself with what it needs to pass to the parent function. Instead I would prefer to already pass the parameter along in the parent.
So instead of
<reporting-placement v-bind:placement="placement" v-bind:method="analyzePlacement"></reporting-placement>
I would prefer
<reporting-placement v-bind:placement="placement" v-bind:method="analyzePlacement(placement)"></reporting-placement>
(including appropriate changes in the child).
But passing the parameter along does not work that way.
Is it possible (maybe in other syntax) to 'bind' the variable to the function reference so that it is automatically passed along when the callback is called?
Info: I don't get an error message if I write it down as above but the whole Vue screws up when I pass the parameter along to the component.
Hope the issue is clear :-) Thanks a lot!
By reading your proposal I've found out that you are overusing the props passing.
Your concern that child component should not have any knowledge about the way that the parent component uses the data is completely acceptable.
To achieve this you can use Vue's event broadcasting system instead of passing the method as props.
So your code will become something like this:
Vue.component('reporting-placement', {
props: ['placement', 'method'],
template: '#reporting-placement',
methods: {
parentMethod: function(placement) {
this.$emit('reporting-placement-change', placement)
}
}
});
And you can use it like this:
<reporting-placement v-bind:placement="placement" #reporting-placement-change="analyzePlacement($event)"></reporting-placement>
But if you need the data which is provided by the method from parent it's better to consider using a state management system (which can be a simple EventBus or event the more complex Vuex)
And finally, if you really like/have to pass the method as a prop, You can put it in an object, and pass that object as prop.