How to include js files on a vuejs component? - vuejs2

I'm just started to study how to do an laravel api with vuejs framework and I have a lot of doubts. On of them is: how can I include js files on a specific vue component? Nowadays, I'm importing all my js files on index of my vue client but what I whised it's how to load specific js file on its specific vue component. I've already tried require('assets/path/to/jsfile'), import('assets/path/to/jfsile') and nothing works.
For example:
in my folders I have this structure: myapp -> static -> myjsfolder -> myjsfile
and in my vue-component I want to import my myjsfile. The admin template I'm using is AdminLTE, laravel as backend and webpack as client on vuejs.

Are your js files exporting anything?
If so, try using:
import * as Something from 'assets/path/to/jsfile'
The path will be relative to the component so you may need to use ./ or ../path for example.
Edit: Does the following work? Assuming a single file component is being used:
<script type="text/javascript" src="some/js/file.js"></script>
<script type="text/ecmascript-6">
export default {
...
}
</script>
Within teste.js either add a function:
function printToConsole() {
console.log('working')
}
then later call printToConsole() within your component.
or use an IIFE
(function () {
console.log('working')
})()

Related

Can i use multiple Vue Composable functions in one file? how do I structure it?

Can i use multiple vue composables in one file?
example:
<script>
export function arrayToInt(arr) {
...
}
export function arrayToUint(arr) {
...
}
</script>
then somewhere else:
import {arrayToInt, arrayToUint} from "./useBytesHelper"
because im getting a vue router parsing error right at the beggining when loading my app. and i might be doing this wrong
Considering that the file is JavaScript module (useBytesHelper.js) and not Vue SFC (useBytesHelper.vue), it's incorrect to use <script> tag there.
The rest is correct, it should be used as listed:
import {arrayToInt, arrayToUint} from "./useBytesHelper"

Automatically initialising multiple Vue.js3 Single File Components each within its own Vue instance

I'd like to have multiple Vue3 components. Each as a separate Vue instance, and all automatically loaded.
Why? Because I want to use them on a page where there's potentially many other JS scripts that alter the page so I cannot change the DOM for them (by globally initialising Vue) and I want not to worry that they will mess with my Vue components - so mounting all my components to some one big Vue instance like <body id="app"> is not an option.
With Vue2 it was a bit easier but does not work with Vue3. Now after some fight I worked out a solution for Vue3 it works fine but it seems ugly in my eyes so I assume there's a better one :)
I'm using (laravel-mix - Webpack solution for building my files).
Here's my HTML file with the components embedded:
// index.php
<TestOne data-vue-component="TestOne" />
<TestTwo data-vue-component="TestTwo" />
<TestOne data-vue-component="TestOne" />
And here's my JS file for loading those components:
// index.js
import { createApp } from 'vue';
const vueComponents = document.querySelectorAll('[data-vue-component]');
if (vueComponents.length) {
vueComponents.forEach((elem) => {
const componentName = elem.getAttribute('data-vue-component');
const app = createApp(require(`./components/${componentName}/${componentName}.vue`).default);
app.mount(elem);
}
}
So I look for the Vue components using data attribute data-vue-component and then for each one found I get the component's name, create a Vue3 instance importing the component at the same moment. Finally I mount it and do the same with the next one.

document is not defined in a Vue component imported to Nuxt when extract_css: false

I have built a Vue component using #vue/cli and tried importing it to Nuxt applications as a dependency. The component is built using --target lib and it compiles to .umd.js source.
When I use vue.config.js with the following setup:
module.exports = {
css: { extract: false }
}
the component styles are included in the bundle and results in throwing the error document is not defined in the following line of bundle file
...
var styleElement = document.querySelector('style[' + ssrIdKe`
...
The component works completely fine if I set the extract value to true, but obviously that requires a manual import of the bundled CSS file ( which I want to avoid )
Is there any solution to get a custom component included inside Nuxt project with styles bundled?
This is due to the server-side rendering. If you need to specify that you want to import a resource only on the client-side, you need to use the process.client variable.
Try this:
if (process.client) {
var styleElement = document.querySelector('style[' + ssrIdKe`
}

Unknown html tag warning of Bootstrap-Vue.js support in WebStorm

I'm using WebStorm 2017.2.4 and webpack Vue.js project. I have added bootstrap-vue.js to my project and would like to see hints for it and components support.
But instead of that I have got "Unknown html tag" warning.
BTW: bootstrap-vue works as expected when running project.
Do you have any suggestions how to make it work?
UPDATED on 2019/07/30
PHPShtorm(WebStorm) was updated to 2019.2 and now they added better support for vuejs libraries:
https://blog.jetbrains.com/webstorm/2019/07/webstorm-2019-2/#development_with_vue
I've just tested and it works.
OLD answer
I solved this issue by adding components manually.
According to: https://bootstrap-vue.js.org/docs/#individual-components-and-directives
I created new file, e.g. bootstrap.js then register globally components which required
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap-vue/dist/bootstrap-vue.css';
import Vue from 'vue';
import navbar from 'bootstrap-vue/es/components/navbar/navbar';
import container from 'bootstrap-vue/es/components/layout/container';
// ...
Vue.component('b-navbar', navbar);
Vue.component('b-container', container);
// ...
It work for me in phpstorm 2018.1
Bootstrap vue uses very dynamic way of defining components. I am using PyCharm with vuejs extension which is unable to resolve the components when registered using
import { Layout } from 'bootstrap-vue/es/components'
Vue.use(Layout)
What I use to do is make a new file bootstrap.js in components directory, and register all bootstrap components I would use like
import Vue from 'vue'
import bContainer from 'bootstrap-vue/es/components/layout/container'
import bRow from 'bootstrap-vue/es/components/layout/row'
import bCol from 'bootstrap-vue/es/components/layout/col'
Vue.component('b-container', bContainer);
Vue.component('b-col', bCol);
Vue.component('b-row', bRow);
and then import this file in main.js
import './components/bootstrap'
Just a little cleaner solution.
#Updated: There're two ways to fix "Unknown html tag" warning: (Global and Local Registration)
Global Registration :
You should have to register your component globally Vue.component(tagName, options) before creating the new Vue instance. For example:
Vue.component('my-component', {
// options
})
Once registered, a component can be used in an instance’s template as a custom element, <my-component></my-component>. Make sure the component is registered before you instantiate the root Vue instance. Here’s the full example:
HTML:
<div id="example">
<my-component></my-component>
</div>
JS:
// global register
Vue.component('my-component', {
template: '<div>A custom component!</div>'
})
// create a root instance
new Vue({
el: '#example'
})
Which will render HTML::
<div id="example">
<div>A custom component!</div>
</div>
Local Registration :
You don’t have to register every component globally. You can make a component available only in the scope of another instance/component by registering it with the components instance option:
var Child = {
template: '<div>A custom component!</div>'
}
new Vue({
// ...
components: {
// <my-component> will only be available in parent's template
'my-component': Child
}
})
The same encapsulation applies for other registerable Vue features, such as directives.
Read more at https://v2.vuejs.org/v2/guide/components.html#Using-Components
#Before Updated:
In WebStorm, a library is a file or a set of files whose functions and methods are added to WebStorm's internal knowledge in addition to the functions and methods that WebStorm retrieves from the project code that you edit. In the scope of a project, its libraries by default are write-protected.
WebStorm uses libraries only to enhance coding assistance (that is, code completion, syntax highlighting, navigation, and documentation lookup). Please note that a library is not a way to manage your project dependencies.
Source: https://www.jetbrains.com/help/webstorm/configuring-javascript-libraries.html
Simply, upgrade WebStorm from version 2017.2.4 to 2017.3 which fixed this issue. It is tested.

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)