Component inside another component not working - webpack - Vue.js 2 - vue.js

I am totally new to Vue.js and hence I feel the issue is very simple. Here is my Test.vue component:
<template>
<p>Hello Worldd</p>
</template>
<script>
export default {
name : 'test'
}
</script>
I am trying to display this "Hello Worldd" in another component called UserDevices.vue. Here is the contents of that file:
<template>
<div>
<test></test>
<p>test</p>
</div>
</template>
<script>
import Test from './Test'
export default {
name: 'UserDevices',
components: {Test}
}
I am getting an error says:
[Vue warn]: Unknown custom element: <test> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
found in
---> <UserDevices> at src/components/UserDevices.vue
<App> at src/App.vue
<Root>
I am using webpack scaffold for vue as template. Isn't this the correct approach to do this?

You are using a .vue file, meaning that vue-loader is looking for a script section enclosed in <script> tags. But, because you are not closing the script tag with </script>, vue-loader will just ignore that section of the .vue file (without any warning).
The template of the Vue component will still get loaded, but the Vue instance's model (with all of its data properties, methods, component, etc.) will not. This is why Vue can't find the <test> component.

Related

How to register component directly vuetify-date-range picker ? Cannot get custom element

I intall https://github.com/praveenpuglia/vuetify-daterange-picker in my currently vue app with vuetify i follow the docs. but it get me an error.
[Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.
//in main.js
//and in my component
//package.json
//error
From link you provided:
// If you want to register this as a global component then
// in main.js
import VDateRange from 'vuetify-daterange-picker';
import 'vuetify-daterange-picker/dist/vuetify-daterange-picker.css';
Vue.use(VDateRange);
And in your components you can use VDateRange with name v-date-range:
<template>
<div>
<v-date-range :options="dateRangeOptions" #input="onDateRangeChange"></v-date-range>
</div>
</template>

Importing Vanilla js file to Vue.js component

I have previously made some drag and drop functionality in vanilla JS which I have used in other projects. Now I have started a Vue.js project and I would like to use the same drag and drop functionality.
Is it possible to include a vanilla JS file in a Vue.js component? And how can it be done?
So far I have only tried to add a <script> tag in the head element in the index.html but it throws an error.
<script src="../src/js/drag-and-drop.js"></script>
You can import the script within your vue component with either
import
import '../src/js/drag-and-drop.js';
require
require('../src/js/drag-and-drop.js');
in the script section of your component.
e.g.
<template>
<!-- vue component markup -->
</template>
<script>
import drag from '../src/js/drag-and-drop';
export default {
name: 'you-vue-component',
}
</script>

pass router params to component object

I have view and I want to load svg based on router params, I have installed vue-loader and it is working if I hard code it.
<template>
<div>
<suit/>
</div>
</template>
<script>
export default {
components:{
suit: ()=>import('../assets/svg/'+Param+'.svg')
}
}
</script>
<style>
</style>
This is what I have. Instead of Param I want to get this.route.params, but when I try this I get undefined which is logical because components wrapper is object. Is there a way to pass a variable here or must I redo the whole thing?
Instead of this.route.params, within a component you should be using this.$route.params. Vue Router Docs.

Nested single file components - vue.js with electron-forge

I am trying electron for the first time and I am blown away by it. I have hit a wall, though, when trying to use single file vue.js components using electron-forge. My problem is the following:
I create a project using the vue.js template and run it. Works and looks great. I have a single file page with an index file that looks like this:
<div id="test"></div>
</body>
<script>
import Vue from 'vue';
import Test from './test';
const app = new Vue(Test).$mount('#test');
app.text = "Electron Forge with Vue.js!";
</script>
So far, so good. It imports Test, which is a single file component and renders it.
Now, I would like to have other single file components nested in this main component. For example, I would like to have the following, in my app file called test.vue
<template>
<h2>Hello from {{text}}</h2>
</template>
<script>
import About from './About.vue'
export default {
components: {
appAbout: About,
},
data () {
return {
text: 'Electron'
}
}
}
</script>
Again, so far so good. I can run the app with no errors so the component is being imported.
Here comes my problem: if I now try to render the component using <appAbout></appAbout>, as I have done before in web apps with vue.js, I get the following error.
It basically says that I am not using a single root element in my component, which is really strange because my component looks like this:
<template lang="html">
<div>Hello from component</div>
</template>
<script>
export default {
}
</script>
<style lang="css">
</style>
I am stuck. Can someone please help?
So I have tried a few different things with no success, like using or even as the component names.
I also have tried these two ways of starting the vue:
The way you get with electron-forge
const app = new Vue(App).$mount('#app')
and the way I learned
new Vue({el: '#app', render: h => h(App)})
Nothing seems to work...
Define your component like this :
export default {
components: {
'app-about': About
}
}
Then use it in template like this (with kebab-case) :
<app-about></app-about>
About your compiling template error you need to wrap everything in test.vue in a root element :
<template>
<div>
<h2>Hello from {{text}}</h2>
<app-about></app-about>
</div>
</template>

How to preserve custom component tag names in Vue.js

I'm using Vue's single-file component spec (*.vue) for custom components in my application. Together with rollup and rollup-plugin-vue, I have observed the output in the DOM, for custom components I have written, to be composed of the equivalent html elements.
For example:
component-a.vue
<template>
<span>Hello World</span>
</template>
<script>
export default { name: 'component-a' };
</script>
component-b.vue
<template>
<component-a></component-a>
</template>
<script>
import ComponentA from './path/to/component-a.vue';
export default { name: 'component-b', components: { ComponentA } };
</script>
The above example, if component-a is added to the Vue mount component, will render to a the sum of the two component's template contents in the DOM, which in this case is simply a span element:
<span>Hello World<span>
Is it possible to achieve a rendered output in the DOM like the snippet below, such that custom elements' templates are represented in the DOM by tags which preserve their tag names?
<component-b>
<component-a>
<span>Hello World</span>
</component-a>
</component-b>
Inside your component-a.vue you should be able to achieve that by including some html code within your <template> tag as follow
component-a.vue:
<template>
<customelement>
// Other stuff
</customelement>
</template>
In this way you will be able to call your component-a from anywhere in your app, and to render an element named customelement.
Ideally you should use this "trick" to render standard HTML5 elements, otherwise you might see some error in your vue app console. Let me know how it goes.
Referring to the Vuejs documentation
https://v2.vuejs.org/v2/guide/components.html#DOM-Template-Parsing-Caveats
It should be noted that this limitation does not apply if you are
using string templates from one of the following sources:
String templates (e.g. template: '...')
Single-file (.vue) components
<script type="text/x-template">
If you use Vuejs like the examples above you won't get the result you wanted. So if you render your components in other ways you should get the result you wanted.