Vue JS how to access data variable in script - javascript

I am new to vue.js.
and i am using 2.5.13 version.
I'm trying to access my data variable in component file script.
But this give to me a undefined message.
Id attribute in the component returns correct value, but inside script, it would return undefined.
If I want to use that variable, what do I need to do?
Below is my app.js code
import App from './components/App.vue';
new Vue(Vue.util.extend({
router,
data : {
test : 1
},
}, App))
.$mount('#root');
And bleow is my App component code
<template>
<div id="app" :data-id="test">
</div>
</template>
<script>
console.log(this.data);
</script>

assign variable var app = new Vue({..}) to your Vue App. and access variable outside vue app by using appname.variable_name like app.message
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
console.log(app.message);
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div id="app">
{{ message }}
</div>

Related

Data from Blade File not rendering in Vue Component

I am working in Laravel Blade and trying to convert some blade files to vue components. I have a property in my blade file of pagetitle. I am trying to get the dynamically created page title to render on the screen from my vue component and not blade. But in my vue console, data comes back as "". Not sure why the data is carrying over.
Header.vue
<template>
<div>
<p title="page-title">{{pageTitle}}</p>
</div>
</template>
<script>
export default {
props: {
pageTitle: {
type: String
}
}
}
</script>
app.js
window.Vue = require('vue');
import Header from './components/Header';
Vue.component('header', Header);
const app = new Vue({
el: '#app',
});
main.blade.php
<div id="app">
<header :page-title="{{$pageTitle}}"></header>
</div>
header.blade.php //where page title is being pulled from
<title>
{{ $pageTitle ?? 'Default Page Title' }}
</title>
In your Header.vue file you are defining pageTitle as a data property, while it should be defined as a prop, since you are actually providing it as a property on the header component.
props: {
pageTitle: {
type: String
}
}
There already exists an HTML element called header, I suggest you rename your component. Your component is missing a props attribute to take input from blade:
Pagetitle.vue:
<template>
<div>
<p title="page-title">{{ this.pageTitle}}</p>
</div>
</template>
<script>
export default {
props: ['title'],
data() {
return {
pageTitle: '',
};
},
created() {
this.pageTitle = this.title
}
}
</script>
We created a title property. When the component is created, we set the component's pageTitle to the title given in main.blade.php.
app.js
window.Vue = require('vue');
import Pagetitle from './components/Pagetitle';
Vue.component('pagetitle', Pagetitle);
const app = new Vue({
el: '#app',
});
main.blade.php
<div id="app">
<pagetitle :title="foo bar"></pagetitle>
</div>
https://v2.vuejs.org/v2/guide/components-props.html

Vue instance inside Vue instance

Sup people!
I got this HTML code here:
// index.html
<div data-init="component-one">
<...>
<div data-init="component-two">
<button #click="doSomething($event)">
</div>
</div>
This basically references a Vue instance inside another Vue instance if I understood everything correctly. The respective JS code is split up in two files and looks like this:
// componentOne.js
new Vue(
el: '[data-init="component-one"]',
data: {...},
methods: {...}
);
// componentTwo.js
new Vue(
el: '[data-init="component-two"]'
data: {...}
methods: {
doSomething: function(event) {...}
}
);
Now, the problem with this is, that doSomething from componentTwo never gets called.
But when I do some inline stuff, like {{ 3 + 3 }}, it gets computed like it should. So Vue knows there is something. And it also removes the #click element on page load.
I tried fiddling around with inline-template as well, but it doesn't really work as I'd expect it to in this situation. And I figured it isn't meant for this case anyway, so I dropped it again.
What would the correct approach be here? And how can I make this work the easiest way possible with how it's set up right now?
The Vue version we use is 2.1.8.
Cheers!
The problem is that you have two vue instances nested to each other.
If the elements are nested, then you should use the same instance or try components
https://jsfiddle.net/p16y2g16/1/
// componentTwo.js
var item = Vue.component('item',({
name:'item',
template:'<button #click="doSomething($event)">{{ message2 }</button>',
data: function(){
return{
message2: 'ddddddddddd!'
}},
methods: {
doSomething: function(event) {alert('s')}
}
}));
var app = new Vue({
el: '[data-init="component-one"]',
data: {
message: 'Hello Vue!'
}
});
<div data-init="component-one">
<button >{{ message }}</button>
<item></item>
</div>
Separate instances work if they are independant of each other.
as follows:
https://jsfiddle.net/p16y2g16/
var app = new Vue({
el: '[data-init="component-one"]',
data: {
message: 'Hello Vue!'
}
});
// componentTwo.js
var ddd = new Vue({
el: '[data-init="component-two"]',
data: {
message: 'ddddddddddd!'
},
methods: {
doSomething: function(event) {alert('s')}
}
});
But when I do some inline stuff, like {{ 3 + 3 }}, it gets computed like it should. So Vue knows there is something.
Because you have parent instance 'componentOne'. It activated Vue for this template. If you need to set another instance inside, you have to separate part of template. Example (it can lag in snippet!) .
Alternative
https://jsfiddle.net/qh8a8ebg/2/
// componentOne.js
new Vue({
el: '[data-init="component-one"]',
data: {
text: 'first'
},
methods: {}
});
// componentTwo.js
new Vue({
el: '[data-init="component-two"]',
data: {
text: 'second'
},
template: `<button #click="doSomething($event)">{{text}}</button>`,
methods: {
doSomething: function(event) {
console.log(event);
}
}
});
<script src="https://vuejs.org/js/vue.min.js"></script>
<div data-init="component-one">
{{text}}
</div>
<div data-init="component-two">
</div>
The button element inside component-two is referenced as a slot in Vue.
The evaluation of the #click directive value happens in the parent component (component-one, which host component-two). Therefor, you need to declare the click handler over there (over component-one).
If you want the handler to be handled inside component-two, you should declare a click directive for the slot element in it's (component-two) template, and pass the handler function, for instance, as a pop.
good luck.
You're doing everything right except you've nested the 2nd Vue instance inside the 1st. Just put it to the side and it will work as expected.
Vue ignores binding more than once to the same element to avoid infinite loops, which is the only reason it doesn't work nested.
Use vue-cli to create a webpack starter app. vue init app --webpack
Then, try to structure your components this way. Read more: https://v2.vuejs.org/v2/guide/components.html#What-are-Components
This is main.js
import Vue from 'vue'
import ComponentOne from './ComponentOne.vue'
import ComponentTwo from './ComponentTwo.vue'
new Vue({
el: '#app',
template: '<App/>',
components: {
ComponentOne,
ComponentTwo
}
})
This is ComponentOne.vue
<template>
<div class="user">
<div v-for="user in users">
<p>Username: {{ user.username }}</p>
</div>
</div>
</template>
<script>
export default {
data () {
return {
users: [
{username: 'Bryan'},
{username: 'Gwen'},
{username: 'Gabriel'}
]
}
}
}
</script>
This is ComponentTwo.vue
<template>
<div class="two">
Hello World
</div>
</template>
<script>
export default {
}
</script>
<div th:if="${msg.replyFloor}">
<div class="msg-lists-item-left">
<span class="msg-left-edit"
th:classappend=" ${msg.unreadCount == 0} ? 'msg-all-read' ">您在</span>
<span th:text="${msg.topic.title}"
class="msg-left-edit-res"
th:classappend=" ${msg.unreadCount == 0} ? 'msg-all-read' ">问题回答</span>
<span th:text="${msg.type.name}"
class="msg-left-edit "
th:classappend=" ${msg.unreadCount == 0} ? 'msg-all-read' ">帖子相关</span>
<span class="msg-left-edit-number" >
产生了<span th:text="${msg.unreadCount} ? : ${msg.unreadCount} + '条新' : ${msg.unreadCount} + '条' "
th:class="${msg.unreadCount} ? : 'number-inner':''">2132条</span>回复
</span>
</div>
<div class="msg-lists-item-right">
<span th:text="${msg.lastShowTime}">2017-8-10</span>
</div>
</div>

Passing data to a component in render using vue-loader

main.js:
import Vue from 'vue'
import App from './app.vue'
let vm = new Vue({
el: '.layers-container',
render: h => h(App),
})
//This doesn't work, layers undefined
console.log(vm.layers);
//This doesn't work either
vm.layers.push({'name': 'image2'})
app.vue using vue-loader:
<template>
<div>
<div v-for="item in layers>
<a :href="item.name"></a>
</div>
</div>
</template>
<script>
export default {
name: 'app',
data() {
return {
layers: [{'name': 'image1'}]
}
}
}
</script>
I have objects from a canvas that are treated as layers I want to add to this list, so I'm trying to take the instance of Vue and push objects onto it so it then updates the data in the template. But, it seems that I can't actually do that outside of the component itself, and I don't know if I'm just doing it wrong, or if I really have to put the rest of my code into the components.
How would I push the data as exampled above, to the layers array in app.vue?

Why all values are not Dynamically Passed in Html using Vue JS?

I use vue js with laravel.
I pass multiple variables threw vuejs component(template), i can pass few variables successfully.
But few of them not passed, shows Empty("").
HTML (Template):
<template v-if="showTemplate" id="segment_body">
<div class="col-md-2" align="center">
<b>Grid</b><br>
<i class=""></i>Grid |
<i class=""></i>List
</div>
<b>ID : #{{ t_id }}</b><br>
<b>LIST : #{{ t_showList }}</b>
</template>
HTML (Data Source):
<script> var a = { list: false} </script>
<div>
<campaign_segment :t_id=1 :t_showList="a.list"></campaign_segment>
</div>
VueJS :
Vue.component('campaign_segment', {
template: '#segment_body',
props: ['t_showList','t_id']
});
OUPUT :
ID : 1
LIST :
If i click Option "Grid",
OUTPUT :
ID: 1
LIST : False
Why I'm not get the value of list?
Why I only get the value of ID ?
Any other solutions ?
You're running into this issue because you're you're trying to pass in the javascript object directly to the component instead of passing it through the Vue instance.
Check out this bin: http://jsbin.com/fosifo/edit?html,js,output
The only real difference in the bin is that rather than trying to pass a to the component directly here (which won't work b/c the vue instance isn't aware of the data):
<script> var a = { list: false} </script>
<div>
<campaign_segment :t_id=1 :t_showList="a.list"></campaign_segment>
</div>
We pass it in through the vue instance:
In your html:
<script>
var a = {list: false}
</script>
In your javascript:
new Vue({
el: '#app',
data:{
a: a // the `a` value here is referencing that same `var a = {list: false}` in your markup.
}
})
By doing it this way, as the vue instance is being created it's able to bind it's a data property to the globally defined variable a from your markup.
It's essentially the same as doing this:
new Vue({
el: '#app',
data:{
a: {list: false}
}
})

VueJS data() not working

I am trying to make a VueJS app but I am failing even with the simplest examples.
I am using Laravel 5.3 with pre-built support for VueJS (version 1, I tried version 2 as well).
Here is my Example.vue component
<template>
<div class="profile">
{{ name }}
</div>
</template>
<script>
export default {
data () {
return {
name: 'John Doe'
}
}
}
</script>
And here is the main code
Vue.component('example', require('./components/Example.vue'));
const app = new Vue({
el: '#app'
});
This is the error that shows up everytime in console:
[Vue warn]: Property or method "name" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option. (found in component )
Any ideas whats wrong?
Thanks
In your script tags instead of export default use:
module.exports = {
data() {
return { counter: 1 }
}
}
This should work for you
Call the component inside your template
Vue.component('example', {
template: `<div class="profile">{{ name }}</div>`,
data () {
return {
name: 'John Doe'
}
}
})
const app = new Vue({
el: '#app'
})
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app"><example></example></div>
The problem is that you are trying to load the component 'example' from that file but you didn't give a name to it. You should use:
<script>
export default {
name: 'example',
data() {
return {
name: 'John Doe'
}
}
}
</script>
Or load the component the following way (not sure if extension .vue is needed):
require('./exmaple').default();
If you are using Babel you can also load the components without giving them a name using this syntax:
import Example from ./example
Also checkout this post to get some more info in case you use Babel

Categories