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

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>

Related

vue component is not shown

i know this has been asked before, but none of the solutions are working for me.
npm is not giving me any errors and if i change the path or mess with the code in any other way, npm will complain. so i am fairly certain that the code is correct, but maybe missing something. the component is just not shown.
from some online tutorial i got the following test component:
Vue.component('testcomponent',{
template : '<div><h1>This is coming from component</h1></div>'
});
i would like to use this in another component like this:
<template>
<testcomponent></testcomponent>
</template>
<script>
import testcomponent from "./testcomponent.vue";
export default {
name: "whatever"
,components:
{
testcomponent
}
}
i also tried loading the component like this:
import testcomponent from "./testcomponent.vue";
Vue.component('testcomponent', testcomponent);
and like this:
Vue.component(
'passportclients',
require('./components/passport/Clients.vue').default
);
i don't think there is an issue with importing the file as it is also not working when i place the component definition into the same file.
thank you very much for any help!
in your testcomponent.vue just paste this code
<template>
<div>
<h1>
This is coming from component
</h1>
</div>
</template>
delete everything else

Import npm package into a Vue.js Single File component

I would like to use Jodit in a SFC, but I am not sure how this is supposed to be done. I realized there is a wrapper (jodit-vue), but for educational purposes, I would like to know how it's done without it. I created a Vue CLI project with default presets, and all I changed is the App.vue:
<template>
<div id="app">
<textarea id="editor" name="editor"></textarea>
</div>
</template>
<script>
import "../node_modules/jodit/build/jodit.min.js"
export default {
name: 'App',
created(){
let editor = new Jodit('#editor');
editor.value = '<p>start</p>';
}
}
</script>
<style>
#import "../node_modules/jodit/build/jodit.min.css" ;
</style>
This produces the error: error 'Jodit' is not defined no-undef, and
if I change the import to:
import Jodit from "../node_modules/jodit/build/jodit.min.js"
Then the compilation is fine, but the browser console says:
vue.runtime.esm.js?2b0e:1888 TypeError: _node_modules_jodit_build_jodit_min_js__WEBPACK_IMPORTED_MODULE_0___default.a is not a constructor
Admittedly, I am new to all of this, but pointing me to the right direction is appreciated.
The jodit module exports the Jodit constructor, so your component would import it like this:
import { Jodit } from 'jodit'
You'd also need the Jodit styles, which could be imported like this:
import 'jodit/build/jodit.min.css'
To create a Jodit instance, we need to provide an element or selector to an existing <textarea>. The Vue component's elements are available in the mounted() lifecycle hook (not in the created() hook), so that's where we would initialize:
export default {
mounted() {
const editor = new Jodit('#editor')
editor.value = '<p>start</p>'
},
}
demo

Trying to use ref inside a Vue single file component. Got undefined

I'm beginning with vuejs and I try to figure what could be done about reference of child component instance in root instance. I used ref attribute and it works pretty well, except if I use it in a single file component (in the template tags). In this specific case, I get 'undefined'.
So, I try to understand why, because it could be very useful for establishing dynamic references. I could probably bypass that situation easily, but I would like to understand the problem instead of run away.
So if someone have an idea ;)
I am using webpack to import my single file component in my app.js and compiled it. However the template compilation isn't done by webpack, but by the browser at runtime (maybe it's the beginning of an explanation ?).
My app is very simple, and I log my references on click on the header, so I don't think it's lifecylce callback related.
Here is my files :
app.js
import Vue from 'Vue';
import appButton from './appButton.vue';
import appSection from './appSection.vue';
var app = new Vue({
el: '#app',
components:
{
'app-button' : appButton
},
methods:
{
displayRefs: function()
{
console.log(this.$refs.ref1);
console.log(this.$refs.ref2);
console.log(this.$refs.ref3);
}
}
});
my component appButton.vue
<template>
<div ref="ref3" v-bind:id="'button-'+name" class="button">{{label}}</div>
</template>
<script>
module.exports =
{
props: ['name', 'label']
}
</script>
my index.html body
<body>
<div id="app">
<div id="background"></div>
<div id="foreground">
<img id="photo" src="./background.jpg"></img>
<header ref="ref1">
<h1 v-on:click="displayRefs">My header exemple</h1>
</header>
<nav>
<app-button ref="ref2" name="presentation" label="Qui sommes-nous ?"></app-button>
</nav>
</div>
</div>
<script src="./app.js"></script>
</body>
ref1 (header tag) and ref2 (app-button tag) are both found. But ref3 (in my single file component) is undefined. Also
Thanks for all the piece of answer you could give me, hoping it's not a silly mistake.
A ref you set is only accessible in the component itself.
If you try to console.log(this.$refs.ref3); into a method from appButton.vue, it will work. But it won't work in the parent.
If you want to access that ref from the parent, you need to use the $ref2 to access the component, and then use the $ref3. Try this:
var app = new Vue({
el: '#app',
components:
{
'app-button' : appButton
},
methods:
{
displayRefs: function()
{
console.log(this.$refs.ref1);
console.log(this.$refs.ref2);
console.log(this.$refs.ref2.$refs.ref3); // Here, ref3 will be defined.
}
}
});
Accessing some child ref from the parent is not supposed to be a good practice tho.

Message Vue is not defined

I'm new to studying vue so my question may be kind of silly, but why am I getting the message "vue is not defined"? in this code:
<template>
<div id="app">
<input></input>
<button>{{ textoBotao }}</button>
</div>
</template>
<script>
new Vue({
data: {
a: 1
},
created: function () {
console.log('a é: ' + this.a)
}
})
export default ({
data() {
return{
textoBotao: 'Clique aqui'
}
}
})
</script>
In your code, you don't need to create another instance of Vue. I can't imagine a situation where you need to create a new Vue instance in a single file component. Uou can use components if you need to encapsulate some functionality
If you do need to do this, you can use the following code:
import Vue from 'vue'
new Vue({
...
})
please see vue's official documentation and sample projects
Old question, but if someone needs it
If you have new Vue({}) in a js file and you load that js file before loading vuejs javascript file, you will get this error. This was the reason for my error.
Basically add /vue.min.js"> before you add other js files using vuejs
Hope it helps
I think You miss to add vue.js file, example:
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.18/vue.min.js"></script>

vuejs Setting Dynamic path to template's src

I have an vue application which I have divided in components kinda manner seen below.
What I want is to bind src property in <template> like below so that I could have a dynamic path every time a user asks for different template to get loaded.
The .ts file will have same code in use for every different template. which prompt me to ask this question.
Please suggest a solution to it. Or am I going into right direction or not to achieve this ?
One way to achieve dynamic templates being rendered is using dynamic component rendering:
App.vue:
<template>
<div>
<button #click="selectedComponent = 'app-quote'">Quote</button>
<button #click="selectedComponent = 'app-author'">Author</button>
<button #click="selectedComponent = 'app-new'">New</button>
<hr>
<component :is="selectedComponent"></component>
</div>
</template>
<srcript>
import Quote from './components/Quote.vue'
import Author from './components/Author.vue'
import New from './components/New.vue'
data: function() {
return {
selectedComponent: 'app-quote'
}
},
components: {
'app-quote': Quote,
'app-author': Author,
'app-new': New
}
</script>