Vue2 + JQuery library - preventing infinite loop, private property in the component needed - vuejs2

I'm making a component wrapper for jQuery library in Vue2.
In the component I have an input field set as v-model and main vue instance can update it and read it.
Vue2 Component can update it as well.
If Vue2 updated the field, I need to call init function in the library. If change has happened in library, then library sending callback where I'm updating the Vue2 model.
As a result, I have got an infinite loop where Vue2 receiving callback, updating model and receiving another callback...
Callback from the jQuery library is coming asynchronously, and I cannot set a flag for the time of update in Vue2.
I thought I can make a flag saying - something is pushed from Vue2, ignore the jQuery library callback this time. But, I don't know how to make a private property in the Vue2 component.

You can't have "private" variables without a function involved. Functions are the only way to introduce a new scope in javascript.

Related

Nuxt 2.14: wait until everything inside `fetch` will be done

I have a question. Inside Nuxt's fetch hook I have some asynchronous calls that are performed by Nuxt content API.
Some pieces of this data are then used inside mounted hook.
But while Nuxt handles first request inside fetch, the control flow passes to the mounted hook and hence there's no needed data.
Yes, I tried uses something like if (!this.$fetchState.pending) return; but obviously mounted is called only once. Does anybody knows how can I force Nuxt to wait? Btw, the app is using static site generation and the component has property fetchOnServer set to false.

compile Vue 3 component for HMR

vuejs/vue-hot-reload-api for Vue2 accept simple object with component options.
Vue3 have built-in HMR support and it needs a different approach. I can't figure out how properly update component.
What kind of data is need for __VUE_HMR_RUNTIME__.createRecord()?
And how to compile updated component again for __VUE_HMR_RUNTIME__.reload()
I think both functions need render function. But it is created when the component is loaded to dom or something.
When I use something like below, render() function is not present in cmp.
let cmp = defineComponent({template: '<div>test</div>})
let inst = Vue.component('test', cmp)
When I use component in parent component, render() is compiled and included in cmp.
But I cant register changed component same way because Vue3 show warn that this component is already registered.
How to compile updated component below and use it in __VUE_HMR_RUNTIME__.reload()?
let updatedCmp = defineComponent({template: '<div>test Me!</div>'})
I tried vue's compile() function, but it doesn't work for me...
I assume this is the only way to replace a component with a modified version in runtime? :)

How can I trigger a function inside 'methode' from external javascript in Vue js?

How can I trigger a function inside 'methode' from external javascript in Vue js ?
I want to trigger call() inside methodes from index.html in vue js
Can anyone help me sort out this ?
You could have your external javascript set a global variable, and then within your Vue component watch for changes on that global variable, and let that trigger the method call. That might not work reliably though because the global variable might already have been set before vue gets mounted.
Is there more going on in your document.ready than you've shown here? Your Vue component's Mounted hook could possibly serve just as well?

Vue Component - How to handle non-reactive data?

I'm losing track of reactivity overhead best practices in a Vue 2 Component. I need to generate a one time string with genId() and assign it to the component' id attribute. It seems like overkill to have any watching going on after that.
Is :id="myID" the right way to insert this into the html id?
And then when setting up the source where do I put the non-reactive data? I had 3 thoughts:
Add property myID: genId() to data. But doesn't that add it to the watchlist automatically even though it won't change? Causing overhead?
I read on Vue Forum from a year old answer that myID: genId() should go in the created hook. Are using hooks for this kind of thing a best practice? I thought hooks were discouraged.
Or I could put it in the component methods and then call it directly with :id="genId()
Is there a Vue way to do this?
Use method 2 for non-reactive data (and you use that component many many times on the page that the small overhead of adding the change listeners has any impact.)
created() {
this.myId = genId()
}
The 3 methods behave differently:
Method 1: data
This will call the genId() when the data object is created and add change listeners.
Method 2: created hook
This will call the genId() when the component object is created and doesn't add change listeners.
Method 3: method
This will call the genId() every time the template re-renders. Which happens every time a change is detected on a variable the view is listening to or a $forceUpdate() is called.
Ps. Vue objects already have a unique id: this._uid
but this is a private property and might change in a future version of Vue.

Does $destroy function removes the Vue Custom component from cache

I construct deep nested tree of parent and children Vue custom components using my top level component dynamically and then I am updating the data from which all tree is constructed. Which has an effect of rendering the entire tree (its a form with various custom components). I refresh/rebuild the whole form after fetching the data (which is what vue do for reactive data) that itself tell me how to regenerate the view (its like a JSON Schema from which I render the entire view).
This is related to my other issue here.
I am observing a very weird behavior in my Vue Application. When I destroy all my children components and rebuild the data to force rendering the form, it appears that even after I have called $destroy on every child component...Vue is not entirely removing them from cache?
Does vue remove the component from cache if a $destroy is called ?
Because I do not see multiple components of the same type in the Vue component list in the Chrome Vue DevTool extension panel. But I see that the same custom event is handled twice by the same component. Same function that handle the events is getting called twice even though there is only one component visible in Vue DevTools of this type.
This only happens after I render the form. When the page is loaded for the first time every thing works. Then after I reset the form by destroying the child component and resetting the data to re-render the form, magically this child component start handling the event twice.. and in 3rd render it handle the events thrice. But I see only one component in google chrome VueJS DevTool extension panel. So my guess is that vue is still keeping the previously destroyed component in cache. I am trying to figure out how should I destroy those components in the cache.
If anyone has observed something similar and found a solution please let me know.
At the moment I am going to dig little bit more on my component keys (this particular component does not have explicit key set by me).
First and foremost, the vue documentation states:
vm.$destroy
In normal use cases you shouldn’t have to call this method yourself.
Prefer controlling the lifecycle of child components in a data-driven
fashion using v-if and v-for.
So instead of destroying and rebuilding the components manually yourself, you should really letting vue handle that via v-if and v-for. If the components aren't updating to your changes, you might be dealing with a reactivity issue.
As you mentioned that this is a deeply nested structure, the reactivity is key to keeping the components up to data with the data.
Vue does not allow dynamically adding new root-level reactive properties to an already created instance. However, it’s possible to add reactive properties to a nested object using the Vue.set(object, key, value) method:
Vue.set(vm.someObject, 'b', 2)
Inside of a component:
this.$set(this.someObject, 'b', 2)
Also, keep in mind that Vue should be doing the heavy lifting in regards to component management, while you should define the parameters by which a component is rendered.