vue nuxt load css file in a method function with props variable - vue.js

I would like to load a .css file after a component event has been fired. Is this possible in vue/nuxt?
scenario
1. component is loaded and props passed in
2. init event calls method
3. method loads css with a props value
export default {
methods: {
myLoadCss(){
(load css from static folder)
'/mycss/+this.$props.myCssFolder+/custom.css'
}
}
}

Related

Is it component definition in vue? How do I find whether it is a component by looking at the code?

When I search for something I came across this post
Here, something, I believe it is component, is defined as below.
export default {
name: 'app',
methods: {
testFunction: function (event) {
console.log('test clicked')
}
},
components: {
Test
}
}
As per the documentation, I came across this
import BaseButton from './BaseButton.vue'
import BaseIcon from './BaseIcon.vue'
import BaseInput from './BaseInput.vue'
export default {
components: {
BaseButton,
BaseIcon,
BaseInput
}
}
I really not sure, whether app is a component which contains Test. Is it the component definition in export? How do we understand that is a component from vue code?
Is it only by the below ways?
Vue.component
components in Vue instance
Not sure - the export default way?
I understand that I sound different because it is Javascript. Could someone help me with this?
There are conventionally, three different types of components in Vue JS.
Root Component
View Component
Normal Component
In a conventional structure the Root component is named 'app' and is passed to the Vue instance when initializing the App for the first time. This component can not be imported and reused inside other components as it will cause a recursive effect. For example this App.vue file is a Root component. It is used inside this main.js file and passed to the Vue instance using new Vue.
The View components are dynamically added or removed from the Root component based on the route. They are written and act as normal component and are only used for Vue router component property. For example the Home and Comments components inside this Router index file are known as View components. They are passed inside the route objects as components inside individual routes. When the app navigates to that particular route, the <router-view> template inside the App.vue file gets replace with the template of the corresponding View component.
Normal components can be used anywhere and are imported by other components. They can be imported inside the View components as well as the Root components. For example, in root component App.vue we see the component Navbar is used. In View component Comments.vue the Replies component is used.
All these components are identical in declaration and behavior but differ in usage.

How to force vue to wait for async <script> to run before mounting components

I have an async js script which is loaded at the top of index.html in my vue project. This script exposes several functions into the window object which I would like to be able to call. I would like to be able to call these functions in the mounted() lifecycle hook, but the async function appears to complete only after mounted has finished. Is there a way I can force the vue instance to wait for all <script> to complete before mounting the root component?
According to this issue in Github https://github.com/vuejs/vue/issues/7209 it seems that the async hooks in Vue lifecycle mounted() created() etc, is only for the ability to call async functions. but the lifecycle itself is synchronous.
Here are some ideas to manage this problem:
You can wrap your component with v-if and render it just as soon as your data is ready.
If you render a component by router - you can use the lifecycle of Vue router. and call your async function before enter to Vue page. do it like this:
export default {
beforeRouteEnter (to, from, next) {
// called before the route that renders this component is confirmed.
next()
}
}
this next() function calls the first Vue lifecycle hook...
full tutorial: https://router.vuejs.org/guide/advanced/navigation-guards.html#in-component-guards
If anyone is interested, here is how I solved my problem:
I modified the js file that the <script> was referencing to set global.initComplete=false initially, and when the script was complete, I marked it as true.
For main.js file, I used:
import Vue from 'vue'
import App from './App.vue'
function init() {
let vm = await new Vue({
render: h => h(App),
})
if(!global.initComplete) {
setTimeout(init, 50)
} else {
vm.$mount('#app')
}
}
init()

Mounting component instance to $root from plugin

I'm creating a plugin, where there will be a single instance of ModalsContainer per $root.
Because of that - I want to create the instance manually, rather than having people add <v-modalscontainer/> to their app.
Code below does just that, it loads components and registers them for Vue to use, then creates an instance of the container and mounts it - the issue is, it's mounted nowhere - the method mounted() of component has console.log() in it and clearly it gets executed without an issue - but it's not mounted in any of $roots.
import Modal from './components/Modal.vue'
import ModalContainer from './components/ModalsContainer.vue'
const plugin =
{
install(Vue, options = {})
{
Vue.component('v-modal', Modal)
Vue.component('v-modalscontainer', ModalContainer)
var instance = new (Vue.extend(ModalContainer))
instance.$mount()
}
}
export default plugin

vue - moving child component code to another file

I have a subcomponent within a file, and I want to extract it out of the file and into another file.
I'm just using vue (not cli) and php, and I don't have access to ES6, so I can't use those import statements.
const form = {
...
components:{
subForm:{
/* lots of code */
}
}
}
If you are using require.js you can just import it from the new file
const subForm = require('path/to/new/file);
const form = {
components { subForm };
}
If not, you can create the component in a new file and registered in the global Vue instance.
Vue.component('subForm', {
/* lots of code */
});
This will work assuming that you import the file into your HTML using a bundler or something like gulp. And that Vue is globally included in the DOM either through a script tag linking to a CDN or through whatever you are using to bundle the application.

How to call mounted or created within a Vue plugin?

I am trying to create some plugins according to this article:
https://alligator.io/vuejs/creating-custom-plugins/
I have a plugin that needs to run something when the root Vue instance mounts or is created. So far I can only see a way to inject something into all components which is not what I would want.
I simply need to do something when the main Vue instance mounts. How can I do this with a plugin?
The install method from the plugin does not seem to do the trick because this seems to happen before the actual created method.
It's possible to have multiple root Vue components. A "root component" is just a component created with the new syntax and no parent component, so you can detect this as follows:
Vue.mixin({
created() {
if (!this.$parent) {
// This is either the root component or a component
// created with `new` and no parent
}
}
})
It's actually easy to include mixins for just a particular component!
In your component that you want to add the mixin to, just import it like you would anything else, and include an array in your component called mixins like so:
import myMixin from 'src/mixin/myMixin'
export default {
mixins: [myMixin]
}
Then your myMixin code would look like this (don't use Vue.mixin, which is global):
export default {
beforeMount () {
console.log('Your component is about to be mounted!')
}
}