How add simple Jquery and <script> in VueJS? - vue.js

I has simple <script> connect and jquery on page. Here is example: https://codepen.io/TidioSupport/pen/WNePeao
How i can add it correctly to my Vue component?
Because when i try add it, i received: Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as <script>, as they will not be parsed. or component not loading.
Hope for your help, thanks!

You should add it in the head of the html where you are calling your vue app

In your mounted lifecycle of Vuejs, you can append the script and then use its function.
Your variables for those scripts can be accessible by window global object.
mounted() {
let chatScript = document.createElement('script')
chatScript.setAttribute('src', 'https://code.tidio.co/fouwfr0cnygz4sj8kttyv0cz1rpaayva.js')
document.head.appendChild(chatScript)
}

Related

lifecycle hook diagram

Is this instance lifecycle hooks diagram also valid(the same) for a vue.js single file component or a global component(vue.componnet())? or is it only used for a Vue instance(new Vue)??
thanks.
Yes, these lifecycle hooks are there for all vue instances: SFCs, global components, explicit new Vue, vue-test-utils wrappers, and so on.
The only thing that SFC do are to write the .render method for you because it's way simpler to write it with an html-like syntax rather than write the render function manually.
In an SFC, you'd tap into them as such:
<script>
export default {
created() {
// do something on created
}
}
</script>
In an explicit new Vue, like this:
new Vue({
created() {
// do something on created
}
});
You get the point.

Vue/Nuxt: How to make a component be truly dynamic?

In order to use a dynamically-defined single page component, we use the component tag, thusly:
<component v-bind:is="componentName" :prop="someProperty"/>
...
import DynamicComponent from '#/components/DynamicComponent.vue';
...
components: {
DynamicComponent
},
props: {
componentName: String,
someProperty: null,
}
The problem is, this isn't really very dynamic at all, since every component we could ever possibly want to use here needs to be not only imported statically, but also registered in components.
We tried doing this, in order at least to avoid the need to import everything:
created() {
import(`#/components/${this.componentName}.vue`);
},
but of course this fails, as it seems that DynamicComponent must be defined before reaching created().
How can we use a component that is truly dynamic, i.e. imported and registered at runtime, given only its name?
From the documentation: Emphasis mine
<!-- Component changes when currentTabComponent changes -->
<component v-bind:is="currentTabComponent"></component>
In the example above, currentTabComponent can contain either:
the name of a registered component,
or a component’s options object
If currentTabComponent is a data property of your component you can simply import the component definition and directly pass it to the component tag without having to define it on the current template.
Here is an example where the component content will change if you click on the Vue logo.
Like this:
<component :is="dynamic" />
...
setComponentName() {
this.dynamic = () => import(`#/components/${this.componentName}.vue`);
},
Solution for Nuxt only
As of now its possible to auto-import components in Nuxt (nuxt/components). If you do so, you have a bunch of components ready to be registered whenever you use them in your vue template e.g.:
<MyComponent some-property="some-value" />
If you want to have truly dynamic components combined with nuxt/components you can make use of the way Nuxt prepares the components automagically. I created a package which enables dynamic components for auto-imported components (you can check it out here: #blokwise/dynamic).
Long story short: with the package you are able to dynamically import your components like this:
<NuxtDynamic :name="componentName" some-property="some-value" />
Where componentName might be 'MyComponent'. The name can either be statically stored in a variable or even be dynamically created through some API call to your backend / CMS.
If you are interested in how the underlying magic works you can checkout this article: Crank up auto import for dynamic Nuxt.js components
According to the official Documentation: Starting from v2.13, Nuxt can auto import your components when used in your templates, to activate this feature, set components: true in your configuration
you are talking about async components. You simply need to use the following syntax to return the component definition with a promise.
Vue.component('componentName', function (resolve, reject) {
requestTemplate().then(function (response) {
// Pass the component definition to the resolve callback
resolve({
template: response
})
});
})

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.

Vue instance inside another Vue instance

I’m integrating Vue with a CMS called AEM thats works basically as component base system like Vue works too. But instead of having a webpack and imports of .vue files, every component on this CMS is a new Vue instance (new Vue({…})). So on my page I have a lot of Veu instances that communicate with each other using the same store (vuex).
This is actually working fine, but I have a scenario when I need a CMS component inside another. Since both this components are a unique vue instance and the “el” property from the parent includes the “el” from the child, the child component doesn’t work.
I know that this is not the expected use of this lib, but is there any way that I can tell or share the same “context” on both vue instances or even another approach for this scenario.
Thx,
Alexandre.
There should be only one instance of Vue.
I suggest you to create single empty Vue instance inside the body tag
All your existent Vue instances transform into components
Register all components in the root Vue instance
With this approach it will be fine to nest one component into another
You should use only one Vue instance as #shrpne mentioned.
If you keep instantiating Vue instances for every component, you'll run into issues while debugging or with component communication and overall this becomes very missy and you miss out on parent-child communication and inheritance provided by Vue.
I don't know about your Vue architecture, but I am currently working on a manual for working with Vue in AEM.
The basic premise is to use Vue's inline-template and vanilla-js, No typescript, nodeJS build, jsx or anything else at build time, just vanilla-js so that when your page is loaded and even before your js bundle is present, the DOM is already there, you just need to mount components by instantiating one Vue instance that will mount all components. This is also great for SEO (unless you plan to server-side render Vue components in java... which is possible theoretically, but good luck!)
Here is a sample AEM/Vue component:
<simple-counter inline-template>
<button v-bind:style="style" v-on:click="add">${properties.clicksText || 'clicks: '} {{ counter }}</button>
</simple-counter>
the JS:
notice how it does not have a template in the JS, because it's inlined above
Vue.component('simple-counter', {
data: function() {
return {
counter: 0,
style: {
color: 'red',
width: '200px'
}
}
},
methods: {
add: function() {
this.counter = this.counter + 1;
this.style.color = this.style.color == 'red' ? 'green' : 'red';
}
}
})
You can build more AEM components in this fashion, then at the end of your clientlib when all your Vue components have been registered, you can run:
new Vue({ el: '#app'})
This, off course, assumes that your page body or some other parent element has the id: app.
The second part of this, how do you enable re-mount of components after authoring dialog is submitted, you could just refresh the page.
I have a question about how we can re-mount components without refreshing the page here
The basic idea is to add an afteredit event to the component and run a new Vue instance only on the newly mutated component... still working on that
Solution:
Replace all new Vue(...) stuff into Vue.component(...) Vue.extend(...) etc for better interface management.
Only use ONE Vue instance witch is new Vue({...options})
Slice your vuex store into modules.
Google teacher knows everything.

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

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)