I just can't find a way to pass my data from vue.js component to blade view in my Laravel project. I tried to use hidden inputfield but data binding returns [object Object].
Any help would be appreciated.
Create a variable in the root component data object and change it from the child component so assuming resources/js/components/ExampleComponent.vue like this
<template>
<div class="container">
<input v-model="field" type="text">
</div>
</template>
<script>
export default {
data() {
return {
field: ''
}
},
watch: {
field: function (val) {
this.$root.bladeValue = val;
}
}
}
</script>
and a resources/js/app.js like so
window.Vue = require('vue');
Vue.component('example-component', require('./components/ExampleComponent.vue').default);
const app = new Vue({
el: '#app',
data() {
return {
bladeValue: ''
}
}
});
and a blade view like so resources/views/welcome.blade.php
<div id="app">
<example-component></example-component>
<h1>#{{ bladeValue }}</h1>
</div>
<script src="/js/app.js"></script>
Then bladeValue will be binded to field in ExampleComponent
Related
My Vue 2 fails to react when an entry is added to an object returned by data(). I can make it work other way but would like to know the underlying reason. See also JSfiddle
var app = new Vue ({
el: "#app",
data() {
return {
addedRows: {
'section1': {}
}
}
},
methods: {
addToList(chapter) {
this.addedRows.section1[chapter] =
this.addedRows.section1[chapter] || []
this.addedRows.section1[chapter].push({'T': 'XXX'})
console.log(this.addedRows)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<span #click="addToList('chapter1')">{{ addedRows }}</span>
</div>
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
I'm working in Laravel. What I want to do is to get the posts from the server and show them in view, however before that I wanted to set static array containing sample posts but my problem is that I can't access posts variable in app.js file when passing by data(){...} and receiving by props: ['posts']. When I even console.log(this.posts) in app.js file it returns undefined. I'm confused what the problem is:
My resources/js/app.js file:
window.Vue = require('vue');
window.App = require('./App.vue');
window.addEventListener('load', function ()
{
const app = new Vue({
el: '#app',
render: h => h(App)
});
});
My resources/js/App.vue file:
<template>
<div>
<app-head></app-head>
<app-post v-for="post in posts" :key="post.id"></app-post>
<app-foot></app-foot>
</div>
</template>
<script>
import Head from './components/Head.vue';
import Foot from './components/Foot.vue';
import Post from './components/Post.vue';
export default {
props: ['posts'],
components: {
'app-head': Head,
'app-post': Post,
'app-foot': Foot,
}
}
</script>
My resources/js/components/Post.vue file:
<template>
<div class="post">
// The post content...
</div>
</template>
<script>
export default {
data() {
return {
posts: [
{id: 1, title: 'Hello :)'}
]
}
}
}
</script>
Few alterations are required.
App.vue
<template>
<div>
<app-head></app-head>
<app-post :posts="posts"></app-post>
<app-foot></app-foot>
</div>
</template>
<script>
import Head from './components/Head.vue';
import Foot from './components/Foot.vue';
import Post from './components/Post.vue';
export default {
components: {
'app-head': Head,
'app-post': Post,
'app-foot': Foot,
},
data() {
return {
posts: [
{id: 1, title: 'Hello :)'}
]
}
}
}
</script>
If you need to prop the posts list to the component then it has to come from here. Hence, notice data is modified (or inserted).
Post.vue
<template>
<div class="post" v-for="post in posts" :key="post.id">
// The post content...
</div>
</template>
<script>
export default {
props: ['posts']
}
</script>
Notice that v-for should be in the post component.
Let me know if that works for you.
You should use props in your component(Post) the receive the data from parent component(App).
Question
In VueJS 2 how do you show some HTML if a Function prop was passed to the component.
Example
<template>
<div v-if="backBtn" #click="$emit('backBtn')">Back Button</div>
</template>
<script>
export default {
props: {
backBtn: Function
}
}
</script>
I can do this by passing a separate prop to key the v-if off of but I'm trying to do this will the one prop.
I created a Fiddle for this issue here
that should work,
you can add more definition with !== undefined
<template>
<div v-if="backBtn !== undefined" #click="$emit('backBtn')">Back Button</div>
</template>
<script>
export default {
props: {
backBtn: {
type: Function,
},
}
}
</script>
but as mentioned, that should work already, so you error may be somewhere else.
after seeing your code, I see what the issue is. it's a case issue
use :back-btn instead of :backBtn
this happens only if you're using vue runtime only (without the compilation)
read more here:
https://v2.vuejs.org/v2/guide/installation.html#Runtime-Compiler-vs-Runtime-only
you can solve it also by passing the function only
https://jsfiddle.net/rz6hyd7b/7/
Vue.component('my-btn', {
props: {
backbtn: {
type: Function
}
},
template: `
<div>
<div v-if="backbtn" #click="backbtn">Back Button</div>
</div>
`
})
var vm = new Vue({
el: '#app',
components: 'my-btn',
methods: {
btnClicked: function(){
console.log('adsf')
}
},
template: `
<div>
Show Btn => <my-btn :backbtn="btnClicked"></my-btn>
</br>
Hidden Btn => <my-btn></my-btn>
</div>
`
});
In the Vue docs for components it says:
Including the prop with no value will imply true:
<blog-post favorited></blog-post>
However, when I try it on my component, it doesn't work (related fiddle):
<!-- html -->
<div id="app">
<test-component visible></test-component>
</div>
<template id="template">
<span>open: {{ open }}; visible: {{ visible }}</span>
</template>
<!-- JS -->
const TestComponent = Vue.extend({
template: '#template',
props: ['visible'],
data: function() {
return { 'open': true }
}
});
new Vue({
el: "#app",
components: {
'test-component': TestComponent
}
});
Is this a bug or am I doing something wrong?
I would also expect it to work as it is, but it seems you need to specify the type of field in the props declaration:
props: {
'visible': {
type: Boolean
}
}
This makes it work correctly