Can't detect components in vue component with v-pre - vue.js

I want to create nested element mounted vue.
However, vue-devtools can't detect components in vue component with v-pre. See desired code below:
HTML:
<body>
<div id="app">
<header></header>
<main id="main" v-pre>
something contents... <!-- NOT detected by vue-devtools -->
</main>
<footer></footer>
</div>
</body>
Attached JavaScript:
...
// About layouts
new Vue({
el: '#id',
components: {
Header,
Footer
}
});
// About main contents
new Vue({
el: '#main',
components: {
...
}
});
...
How do I solve this?

Related

import Laravel blade component with VueJs in another blade with VueJs

When I import a component with VueJs content into another component with VueJs content I get this error:
Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as <style>, as they will not be parsed.
example.blade.php is the component
<div id="appComp">
#{{ msg }}
</div>
<script>
var appComp = new Vue({
el: '#appComp',
data: {
msg : #json($msg),
}
});
</script>
app.blade.php which imports the example component
<head>
<script src="https://cdn.jsdelivr.net/npm/vue#2/dist/vue.js"></script>
</head>
<div id="app">
<x-example/>
#{{ text }}
</div>
<script>
var app = new Vue({
el: '#app',
data: {
text: #json($text),
}
});
</script>
if I move <x-example/> out <div id="app">, everything works fine, but it's not good for me.
<x-example/>
<div id="app">
#{{ text }}
</div>
What solutions can I find to use Laravel blades with VueJs source code?

Component inside `transition-group` is rendered twice (duplicated)

Here is a strange issue i am facing.
<script src="https://unpkg.com/vue#2.6.11/dist/vue.min.js"></script>
<div id="app">
<transition-group name="fadeLeft" tag="ul">
<section key="0">
<testt></testt>
<template v-pre id="myId">
<div>My neighbors: <a v-for="(val,index) in myArray">{{val}}</a></div>
</template>
</section>
</transition-group>
</div>
<script>
Vue.component('testt', {
template: '#myId',
props: {
myArray: {
type: Array,
default: function() {
return ['James', 'Mike'];
}
}
}
})
new Vue({
el: '#app'
})
</script>
transition-group renders the component twice (and the second rendering is done without parsed "{{variable}}").
If you just remove transition-group parent at all, it works as expected and there is no duplicated content. So, definitely the problem seems somewhere there. How to fix that (so, retain transition-group and solve the problem)
Please don't post answers "use component outside of app" or similar offtopic, i described the problem I need to find answer. Also, the aprior is that the template needs to be within transition-group decendants.
The problem:
In the section tack you have the testt tag which was rendered with the parsed HTML and also the template which was rendered as another literal tag (no rendering). And since transition-group elements must be keyed, the template had to be moved out.
The solution:
<script src="https://unpkg.com/vue"></script>
<div id="app">
<transition-group name="fadeLeft" tag="ul">
<section key="0">
<testt></testt>
</section>
</transition-group>
<template v-pre id="myId">
<div>My neighbors: <a v-for="(val,index) in myArray">{{val}} </a></div>
</template>
</div>
<script>
Vue.component('testt', {
template: '#myId',
props: {
myArray : { type:Array, default :function(){ return ['James','Mike'];} }
}
})
new Vue({
el: '#app'
})
</script>

How to bind v-model from input in one div to another div or component

I have my input field in one div, and will have label in another div (as sidebar in my application). I want to update label in sidebar, as I type in input on first div.
I am happy to create second div a component if that's the way. I was reading online, and it was said we could use props to pass data to component. But I am not able to link input field to component. Please find my code as below:
var app = new Vue({
el: '#div1',
data: {
message: ''
}
})
Vue.component('testp', {
props: ['message'],
template: '<p>Message is: {{ message }}</p>'
})
var div2 = new Vue({
el: '#div2'
});
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="div1">
<input v-model="message" placeholder="edit me">
</div>
<div id="div2">
<testp></testp>
</div>
</body>
</html>
As Pointed in Comment You have no reason to have two separate Vue instance and the First Answer is correct. But in some cases where you really need to have multiple Vue instances, you can actually use them in the following manner.
var app = new Vue({
el: '#div1',
data: {
message: ''
}
})
Vue.component('testp', {
props: ['message'],
template: '<p>Message is: {{ message }}</p>'
})
var div2 = new Vue({
el: '#div2',
computed: {
newMessage() {
return app.message;
}
},
});
Html
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="div1">
<input v-model="message" placeholder="edit me">
</div>
<div id="div2">
<testp :message="newMessage"></testp>
</div>
</body>
</html>
Please observe the computed value newMessage is actually getting its value form a different Vue instance (app) and it is also reactive. Therefore whenever the value in first Vue instance changes, it is updated in another Vue instance.
Codepen: https://codepen.io/ashwinbande/pen/xMgQQz
Like I have pointed out in my comments, there is no reason for you to use two separate Vue instances. What you can do is simply wrap everything within an app container, e.g. <div id="#app">, and then instantiate your VueJS instance on that element instead.
Then, you can use v-bind:message="message" on the <testp> component to pass in the message from the parent. In this sense #div1 and #div2 are used entirely for markup/decorative purposes and are not used as VueJS app containers in your code.
Vue.component('testp', {
props: ['message'],
template: '<p>Message is: {{ message }}</p>'
});
var app = new Vue({
el: '#app',
data: {
message: ''
}
});
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<div id="div1">
<input v-model="message" placeholder="edit me">
</div>
<div id="div2">
<testp v-bind:message="message"></testp>
</div>
</div>

vue.js helloworld not working within existing bootstrap site

I want to replace my project's first piece of vanilla JS with vue.
I try to get the hello world example working.
It works as stated, but when I nest the element in another element (these may be the wrong terms) it does not work.
My source code:
<!-- this works -->
<div id="app">
<p>${ message }</p>
</div>
<!-- but this doesn't for some reason -->
<div class="container">
<div id="app">
Nested ${ message }
</div>
</div>
Full code example.
The class="container" is needed for bootstrap.
EDIT:
I took the generated html and edited it down to just the bare minimum to show it not working.
See the result.
Wrap the container with
<div id="app"></div>
It should work that way
this works fine, the problem in your template is that you have two elements with id="app" so vue instance is initialized with the first element with id="app", then the second (the nested one) is never initialized
<html>
<head>
<script src="https://unpkg.com/vue"></script>
</head>
<body>
<!-- but this doesn't for some reason -->
<div class="container">
<div id="app">
Nested ${ message }
</div>
</div>
<script>
new Vue({
delimiters:['${', '}'],
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})
</script>
</body>
</html>
You have 2 #app id but one vue instance. If you need two #app you should make two Vue instance. Instance 1 for #app1 and instance 2 for #app2. You can save theme in variables if you need to interact within theme:
<div id="app1">
<p>${ message }</p>
</div>
<div class="container">
<div id="app2">
Nested ${ message }
</div>
</div>
<script>
var app1 = new Vue({
delimiters:['${', '}'],
el: '#app1',
data: {
message: 'Hello Vue.js!'
}
});
var app2 = new Vue({
delimiters:['${', '}'],
el: '#app2',
data: {
message: 'Hello Vue.js!'
}
})
</script>
if this answer helped you, consider to accept it.

Unknown custom element using VUE

I'm new to Vue and am having some trouble with a few things. First, off I was following this tutorial: eventbus. If I put all the code (html, JS and CSS) in one html file, this works just as described in this tutorial.
However, I have been reading and I was following a VUE cli app structure. I used
vue init webpack vueapp01
So, I have an index.html file in the vueapp01 root folder, in the src folder I have an app.vue and two vue files in the components folder; the-box.vue and the-button.vue; along with all the other files loaded by the vue template webpack.
Instead of having all the code in one html file (which works) I have the code separated out like this:
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>vueapp01</title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
App.vue:
<template>
<div id="the-example" class="container">
<h1>Building an Event Bus with Vue.js</h1>
<div class="row">
<div class="col-xs-6">
<the-button what="Event #1"></the-button>
<the-button what="Event #2"></the-button>
<the-button what="Event #3"></the-button>
</div>
<div class="col-xs-6">
<the-box name="Receiver #1"></the-box>
</div>
</div>
</div>
</div>
</template>
<script>
import the-button from './components/the-button'
import the-box from './components/the-box'
export default {
name: 'app',
components: {
the-button,the-box
}
}
</script>
<--
<script>
/******************************************
The Central Event Bus Instance
*******************************************/
let EventBus = new Vue();
</script>
the-box.vue:
/******************************************
Example Root Vue Instance
*******************************************/
new Vue({el: "#the-example"});
/******************************************
A sample Vue.js component that emits an event
*******************************************/
let TheButton = Vue.extend({
name: "the-button",
props: ["what"],
template: `
<button class="btn btn-md btn-success the-button" #click="makeItHappen()">Sender: {{what}}</button>
`,
methods: {
makeItHappen: function(){
EventBus.$emit("somethingHappened", this.what)
}
}
});
Vue.component("the-button", TheButton);
the-button.vue:
/******************************************
A sample Vue.js component that received an event
*******************************************/
let TheBox = Vue.extend({
name: "the-box",
props: ["name"],
template: `
<div class="well">
<div class="text-muted">{{name}}</div>
<div>{{respondedText}}</div>
</div>
`,
data: function(){
return {
respondedText: null
}
},
created: function(){
EventBus.$on('somethingHappened', (what)=>{
this.respondedText = 'Event Received: ' + what;
})
console.log("Responder")
}
});
Vue.component("the-box", TheBox);
Currently, I'm getting the errors, "unknown custom element the-box", "unknown custom element the-button". I've tried switching the script and template orders to have templates load first but I still have no luck.
Any help would be greatly appreciated. Also, I assume I'm doing this correctly by separating these components out to separate files but if that is incorrect I'd gladly take criticism on the way I'm learning to use Vue.
Change:
import the-button from './components/the-button'
import the-box from './components/the-box'
to
import TheButton from './components/the-button'
import TheBox from './components/the-box'
and do
components: {
TheButton,
TheBox,
}
There must be another far larger error somewhere you're somehow not seeing.
Here is a full example of how the files should look to implement that fiddle in single file components assuming you used vue init webpack <project>.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>bus</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
main.js
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
window.EventBus = new Vue()
new Vue({
el: '#app',
template: '<App/>',
components: { App }
})
App.vue
<template>
<div id="the-example" class="container">
<h1>Building an Event Bus with Vue.js</h1>
<div class="row">
<div class="col-xs-6">
<the-button what="Event #1"></the-button>
<the-button what="Event #2"></the-button>
<the-button what="Event #3"></the-button>
</div>
<div class="col-xs-6">
<the-box name="Receiver #1"></the-box>
<the-box name="Receiver #2"></the-box>
<the-box name="Receiver #3"></the-box>
</div>
</div>
</div>
</template>
<script>
import TheButton from './components/TheButton.vue'
import TheBox from './components/TheBox.vue'
export default {
name: 'app',
components: {
TheButton, TheBox
}
}
</script>
components/TheBox.vue
<template>
<div class="well">
<div class="text-muted">{{name}}</div>
<div>{{respondedText}}</div>
</div>
</template>
<script>
export default {
name: "the-box",
props: ["name"],
data: function(){
return {
respondedText: null
}
},
created: function(){
EventBus.$on('somethingHappened', (what)=>{
this.respondedText = 'Event Received: ' + what;
})
console.log("Responder")
}
}
</script>
components/TheButton.vue
<template>
<button class="btn btn-md btn-success the-button" #click="makeItHappen()">Sender: {{what}}</button>
</template>
<script>
export default {
name: "the-button",
props: ["what"],
methods: {
makeItHappen: function(){
EventBus.$emit("somethingHappened", this.what)
}
}
}
</script>