Can i render common using mixin in vue.js?
for example
<template>test: {{ test }}</template>
<script>
export default {
data() {
return {
test: 1,
}
},
}
</script>
// mixin
export default {
data() {
return {
mixinData: 10,
}
},
render() {
if (this.mixinData === 10) {
// mixin render, not component render
} else {
// component render, not mixin render
}
}
}
can i do this using mixin in vue.js?
i want to know way about common render using mixin.
I'm trying to extract a function for use across multiple components, but "this" is undefined and I'm unsure of the best practice approach of how to attach the scope so my function knows what "this" is. Can I just pass it as an argument?
Component:-
import goToEvent from "#/common";
export default {
name: "update",
methods: {
goToEvent
common function:-
let goToEvent = (event, upcoming=false) => {
this.$store.dispatch({
type: 'setEventsDay',
day: event.start_date
})
}
export default goToEvent
When I call goToEvent in my component, I get TypeError: Cannot read property '$store' of undefined. How do I avoid this?
In this situation I recommend to define eventable as a mixin :
const eventable= {
methods: {
goToEvent(event, upcoming=false) {
this.$store.dispatch({
type: 'setEventsDay',
day: event.start_date
})
}
}
}
export default eventable;
in your vue file :
import eventable from "#/eventable";
export default {
name: "update",
mixins:[eventable],
....
second solution :
export an object with the function as nested method then import it and spread it inside the methods option :
export default {
goToEvent(event, upcoming=false){
this.$store.dispatch({
type: 'setEventsDay',
day: event.start_date
})
}
}
then :
import goToEvent from "#/common";
export default {
name: "update",
methods: {
...goToEvent,
otherMethod(){},
}
//....
}
You're tagged with Typescript, so you need to tell TS that this actually has a value (note, I do not know VueJS, am using the generic Event types here, there is likely a more valid and correct type!)
First option, manually tell it what there is -
let goToEvent = (this:Event, event, upcoming=false) => {
Other option - tell it what type it is -
let goToEvent: EventHandler = (event, upcoming=false) => {
Of the two I personally prefer the second style for readability.
There are numerous ways to achieve this, here are some that I like to use in my projects:
Method 1: Mixins
Mixins are great for sharing a bunch of methods across components and also easy to implement, although one big con is that you will not be able to import specific methods that you need. Within the mixin, this follows the rules as in components.
File: #/mixins/eventable
import { mapActions } from 'vuex'
export default {
methods: {
...mapActions([])
goToEvent (event, upcoming = false) {
store.dispatch({
type: 'setEventsDay',
day: event.start_date
})
}
}
}
Usage in component:
import eventable from '#/mixins/eventable'
export default {
name: 'ComponentName',
mixins: [eventable],
methods: {
componentMethod () {
this.goToEvent()
}
}
...
Method 2: Static JavaScript files
In some cases, you might have a collection of helper functions kept in a file and want the ability to import as you need.
In your case, you seem to be using a store actions (assumed from the dispatch), hence I'll be including importing and using the store within the static JS file.
File: #/static/js/eventable.js
import store from 'path_to_store_file'
const goToEvent = () => {
store.dispatch('actionName', payload)
}
export default {
goToEvent
}
Note:
Although this is not entirely necessary, but only by declaring the imported function as a method within the component will it be bound to the component instance. This will allow you to access the function in the HTML portion.
Usage in component:
import { goToEvent } from '#/static/js/eventable.js'
export default {
name: 'ComponentName',
methods: {
// Read note before this code block
goToEvent,
componentMethod () {
// When declared as a method
this.goToEvent()
// When not declared, it can still be accessed in the js portion like this
goToEvent()
}
}
...
I've tried to override VueJS component method from another component.
Here I want to override checkForm method from another VueJS file.
inside ./src/components/auth_form.vue:
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
props: {...},
methods: {
checkForm: function(e: any) {
console.log('Please override this method!')
}
}
})
</script>
I want to override this method from ./src/views/signup.vue:
<script lang="ts">
import Vue from 'vue'
import authForm from '../components/auth_form.vue'
export default Vue.extend({
name: 'signup',
components: {
authForm
},
data: function() {...},
methods: {
// This does not override the method above!
checkForm: function(e: any) {
console.log("success")
// Reset the form
this.signupForm = {} as SignupForm
}
}
})
</script>
Yes they will not override because the 2 functions are in 2 different scopes. They can have same name and works independently. In order to do what you want, you have to put the checkForm function of auth_form inside its props.
So in auth_form:
props: {
checkForm: {
type: Function,
default(e) {
console.log('Please override this method!')
}
}
}
then when calling it in signup.vue
<auth-form :check-form="checkForm" /> //pass parent's method into children props
methods: {
checkForm() {
console.log("success") // this will override the default one
}
}
I have a simple component that uses mixin that's shared across multiple components with similar functionality.
When I run it I seem to be getting
Property or method "activeClass" is not defined on the instance but
referenced during render.
Here's my mixin
<script>
export default {
data() {
return {
opened: false,
identity: ''
}
},
computed: {
activeClass() {
return {
active: this.opened
};
}
},
created() {
window.EventHandler.listen(this.identity + '-toggled', opened => this.opened = opened);
},
methods: {
toggle() {
window.EventHandler.fire('toggle-' + this.identity);
}
}
}
</script>
and my component
<template>
<span class="pointer" :class="activeClass" #click="toggle"><i class="fas fa-search"></i></span>
</template>
<script>
import Trigger from '../../mixins/Trigger';
export default {
data() {
return {
mixins: [Trigger],
data() {
return {
identity: 'language'
}
}
}
}
}
</script>
For some reason I cannot seem to be able to access activeClass computed property from within the component. Any idea why is this happening?
Try to move mixin to components main scope. Not in data function rerurn
Here is an example :
mixin.js
export default {
methods : {
aFunction() { // Some functionality here }
}
}
component.vue
import mixin from './mixin'
export default {
mixins : [ mixin ]
created() {
// Call aFunction defined in the mixin here
}
}
I want to access the aFunction defined inside methods of mixin from the created() lifecycle method inside the component.
The mixin methods are merged with the current instance of the component, so it would just be:
created(){
this.aFunction()
}
Here is an example.
console.clear()
const mixin = {
methods:{
aFunction(){
console.log("called aFunction")
}
}
}
new Vue({
mixins:[mixin],
created(){
this.aFunction()
}
})
<script src="https://unpkg.com/vue#2.4.2"></script>