Custom js library(scrollMonitor) inside main Vue instance to be shared with inner components - vuejs2

This is Vue.js question, generally I'm trying to use 'scrollMonitor' function inside of my .vue instance(imported via main.js) but it gives me a typical 'this.scrollMonitor is not a function' error
mounted () {
let watcher = this.$scrollMonitor(this.$refs.nicer)
}
In main.js ScrollMonitor library seems to be properly imported(console shows what's expected):
import scrollMonitor from 'scrollmonitor'
Vue.use(scrollMonitor)
console.log(scrollMonitor)
Again main goal is using scrollMonitor functionality inside of .vue file(in vue component instance). Sorry if I'm missing something silly here - I'm already using some other libraries like Vue-Resource in that file so issue is not in 'filepath' but rather in the way I'm using scrollMonitor functionality, any help is much appreciated, thank you !

For those who are still looking: there is a way of adding plain js libraries to the main.js and then using them with ease globally in inner components(this is not about mixins):
import scrollmonitor from 'scrollmonitor'
Object.defineProperty(Vue.prototype, '$scrollmonitor', {
get() {return this.$root.scrollmonitor}
})
also it should be added to main Vue data object:
data () {
return { scrollmonitor }
},
And then it can be used within mounted() callback (not created() one) inside of the component itself, with scrollmonitor it may look like this(in my specific case the template had a div with ref="nicer" attribute, 'create' is a method specific to the library api):
mounted () {
this.$scrollmonitor.create(this.$refs.nicer)
}
Hooray, I hope someone may find this useful as I did!

Are you using a plain javascript library and trying to Vue.use it? That won't really work. Vue.use will only work with plugins designed to work with Vue. Import the library into the component that needs and and just use it there.
scrollMonitor(this.$refs.nicer)

Related

import pdfjslib into vuejs component

I would like to create a viewer PDF files into electron/vuejs application.
I need to use the pdfjs librarie.
For that I installed this package : "pdfjs-dist": "2.6.347"
and in my component vuejs I try to used this by doing this :
import pdfjsLib from "pdfjs-dist/webpack";
This import instruction seeems to be running good. But If a start used this like this :
created()
{
pdfjsLib.getDocument()
}
I throw this error :
Cannot read property 'getDocument' of undefined"
I try lot of tricks but I don't find any solution for use this library in my component.
Anyone have a vuejs project with pdfjslib for viewing pdf ?
This seems to work:
import("pdfjs-dist").then((pdfjsLib) => {
pdfjsLib.getDocument();
});
It can be used inside either created() or mounted(). I'd personally use it in mounted.
Working demo here.
Also note calling getDocument() with no arguments seems to trigger some lib error (but that's outside the scope of current question):
Invalid parameter in getDocument, need either Uint8Array, string or a parameter object

How to acced to google object in vue 2?

I'm trying to use the google maps API at my vue2 project and I have tried some ways that have failed. After using the vue2googlemaps module and the node module from google I have decided to use the CDN directly and add it to the index page. My problem now is that to acced to the google object, for example, to create a Marker or something like that, I need to use this.marker = new window.google.maps.Marker() for example, but in the tutorials I have seen, everyone uses directly the google object and never uses that window. I can`t understand why it happens. It would be appreciated if someone shows me the correct way to import or use this library on google.
It's because your template's code is compiled and executed in your component instance (a.k.a vm) 's scope, not in the global (a.k.a. window) scope.
To use google directly in your template you could add the following computed:
computed: {
google: () => window.google
}
If your problem is not having google defined in the component's <script>, a simple solution is to add it as a const at the top:
import Vue from 'vue';
const google = window.google;
export default Vue.extend({
computed: {
google: () => google // also make it available in template, as `google`
}
})
An even more elegant solution is to teach webpack to get google from the window object whenever it's imported in any of your components:
vue.config.js:
module.exports = {
configureWebpack: {
externals: {
google: 'window.google'
}
}
}
This creates a google namespace in your webpack configuration so you can import from it in any of your components:
import google from 'google';
//...
computed: {
google: () => google // provide it to template, as `google`
}
Why do I say it's more elegant?
Because it decouples the component from the context and now you don't need to modify the component when used in different contexts (i.e: in a testing environment, which might not even use a browser, so it might not have a window object, but a global instead; all you'd have to do in this case is to define a google namespace in that environment and that's where your component will get its google object from; but you wouldn't have to tweak or mock any of the component's methods/properties).

Where to import file js in vue/nuxt

Usually I use a js code with functions to run on some events.
Now I am using nuxt.js and I wonder where to put this file or how to create a global method to use these functions in every component.
I could write the methods that I need inside every a specific component but after it wouldn't be usable outsite of it.
How to do that in vue/nuxt?
So one way to do it in vue.js is by using mixins, in nuxt you can also use mixins, then you should register them as plugins, but first:
Non global mixins
Create an extra folder for your mixins. For example in a /mixins/myMixin.js
export default {
methods: {
commonMethod() {
console.log('Hello')
}
}
}
Then import in a layout, page or component and add it via the mixins object:
<script>
import myMixin from '~/mixins/myMixin.js'
export default {
mixins: [myMixin]
}
</script>
Global mixins
For example in a new file plugins/mixinCommon.js:
import Vue from 'vue'
Vue.mixin({
methods: {
commonMethod() {}
}
})
Include the file in nuxt.config.js like that:
plugins: ['~/plugins/mixinCommon']
After that you would have the method everywhere available and call it there with this.commonMethod(). But here an advice from the vue.js docs:
Use global mixins sparsely and carefully, because it affects every
single Vue instance created, including third party components. In most
cases, you should only use it for custom option handling like
demonstrated in the example above. It’s also a good idea to ship them
as Plugins to avoid duplicate application.

Vuepress - Add component to each page

The documentation in regards to this is quite short. I want to add a Vue component to each page in the app, without having to manually declare it in each template.
I managed to add a enhanceApp.js file and add this to it:
import MyComponent from './components/my-component'
export default ({
Vue,
options,
router,
siteData
}) => {
Vue.component('MyComponent', MyComponent)
}
The app runs but I don't see the component anywhere. Any tips or other ways I can achieve this? Thanks!
You do not need to put it in enhanceApp.js, just having the component in /.vuepress/components is sufficient.
Although, if you want to keep them outside that folder, that might be the way to get Vuepress to know about them.
Use it in an md file as you would do in a Vue template,
<MyComponent></MyComponent>
This is an old question and might only apply to V1 but this is simple to accomplish.
Add your Vue component to .vuepress/components as usual
In .vuepress/config.js add the following:
module.exports = {
// rest of config...
globalUIComponents: [
'YourComponent'
]
}
Don't even need to import your component.
See docs for more info.

Access Vue.js plugin from main.js

I'm creating a plugin and I just wonder why I can't access it in main.js file. Here's how Auth.js looks like:
const Auth = {
install(Vue) {
Vue.prototype.$isGuest = function () {
console.log('This user is a guest.');
}
Vue.prototype.$getAuthToken = function () {
console.log('Auth token will be returned.');
}
}
}
export default Auth
This is main.js:
import Auth from '#/helper/Auth'
Vue.use(Auth)
However, when I execute console.log(this.$isGuest()), it doesn't work. It actually returns the following:
main.js?1c90:25 Uncaught TypeError: this.$isGuest is not a function
The problem is that this method works when I call it in components such as Dashboard.vue and things like that.
I have a way to avoid calling isGuest method within main.js (I can call it in Layout.vue), but I'm more curious why it doesn't work in main.js.
Maybe because Vue hasn't been initialized yet, but even if I put the console.log() line at the end of the file, still doesn't work.
Thanks,
N.
If you are calling this.$isGuest() outside of Vue, you will get the error you describe. That's because this is not a Vue object. What this is depends on how you are building your code, but given you are using import it's probably the module.
Also, you are adding $isGuest to the prototype of Vue. That means that the function is only going to be available on actual instances of Vue objects. That is why it is available in your components.
If you want to use it in the main script, the only place you will be able to get to it is inside the Vue object in a lifecycle handler, method, or computed. For example:
new Vue({
mounted(){
console.log(this.$isGuest()) // this should work
}
})