5

I try to find a solution to a problem of circular dependency. In my Vuejs application, I want a function makeUrl(url) which computes an absolute url of the given parameter by adding the $router.base value at the beginning.

So I put this in my modules routes.js :

const router = new VueRouter({
    base: '/subdirectory',
    //...
});

function makeUrl(url){
    return router.base + url;
}

export {makeUrl};
export default router;

routes.js is imported in main.js, the entry point of my application, where I create my Vue main instance.

In routes.js I import my page components, which imports all other components. In some of them, I need to use the makeUrl() function I defined. But I can't import routes.js because it will create a cyclic import.

I can't move my makeUrl() function in another module because I need the access the Vue-router instance, so I'll have to import routes.js in this another modules => circular import again.

So, I heard of $router variable, so I tried to build a utility component which contains a makeUrl() function :

//util-component.js
'use strict';

import Vue from 'vue/dist/vue';

const UtilComponent = Vue.component('util-component', {
  methods: {
      makeUrl(url){
          return this.$router.base + url;
      }
  }
});

export default UtilComponent;

And in my personal component :

//my-component.vue
<template>
    <img class="logo" :src="util.makeUrl('/assets/img/logo-transp.svg')" alt=""/>        
</template>

<script>

import util from 'utils/util-component';

export default {
  data () { return {};}
}
</script>

But with this it end with the same TypeError: e.makeUrl is not a function... :(

How can I deal with it ? Thanks for your help !

Thaledric
  • 539
  • 2
  • 8
  • 17

1 Answers1

3

For your utility functions you should use a mixin instead:

// mixins/Utils.js
export default {
  methods: {
    makeUrl(url) {
      return this.$router.options.base + url;
    }
  }
}

You can add the mixin to your component like this:

<script>
import Utils from 'mixins/Utils';

export default {
  mixins: [ Utils ],
}
</script>

Now, your component has a makeUrl method which will be called within its scope, meaning its reference to this.$router will be the VueRouter instance you want.

You can use this method in your template like any other component method:

<template>
  <img class="logo" :src="makeUrl('/assets/img/logo-transp.svg')" alt=""/>        
</template>
tony19
  • 125,647
  • 18
  • 229
  • 307
thanksd
  • 54,176
  • 22
  • 157
  • 150
  • Oh yes it works well ! Thank you ! PS : I must do `return this.$router.options.base + url;` in my mixin – Thaledric Jun 02 '17 at 14:00