Custom Component in Laravel Spark - laravel

I try to add my custom component to my Laravel Spark instance and always get the error:
Property or method "obj" is not defined on the instance but referenced during render..
It all works fine if i only bind a data value (ex. "testkey") without a loop...but if i add the for loop i receive this error...so my code:
app.js (spark)
require('spark-bootstrap');
require('./components/bootstrap');
//my new Component
import OmcListObjects from './components/modules/omc/objectlist.vue';
Vue.component('omc-objectlist', OmcListObjects);
var app = new Vue({
mixins: [require('spark')]
});
my Component (objectlist.vue)
<template>
<div :for="(obj in objlist)" class="property-entry card col- col-md-4 shadow-sm">
</div>
</template>
<script>
export default {
data () {
return {
objlist: [{title: 'test1'}, {title: 'test2'}],
testkey: 'testval'
}
}
}
</script>

I think you mean by :for the v-for directive, directives are always prefixed by v- like v-for one in which the compiler can recognize the obj variable as an temporary element used in the loop, but if you set :for which is recognized as a prop bound to a data or another property.

Related

What is the best way to use v-model without using it in the main app.js file?

I was wondering i have this code inside my blade file:
<input type="text" class="form-control" :model="productname" id="name" name="name" aria-describedby="emailHelp" placeholder="Title" value="{{ old('name') }}" required>
and i want to create an 2 way data binding, so when user submitted 3 or more character to get an green background of this input field, but when they are less to get a red background.
I tried to do this with vue-component, but it seems for whatever reason the vue-component does not have access to the main #app id which is assign to the main app blade template in order all vue code to have access to the html code and change it. I have created an vue-component called Upload inside ressources/assests/js/components/Upload.js, but when i write this code:
<template>
</template>
<script>
export default {
data() {
return {
productname: '',
};
},
mounted() {
console.log('Upload component', this.message);
}
}
</script>
and added of course to app.js like that Vue.component('upload-component', require('./components/Upload.vue'));
and run - npm run dev to compile the code i am getting this error:
[Vue warn]: Property or method "productname" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
Whatever when i write this code inside the main app.js file (resources/assests/js/app.js):
const app = new Vue({
el: '#app',
data() {
return {
productname: '',
};
},
});
everything is working fine and i dont get any errors, but i dont want that, as imagine for my website/app i have to have for example 100 v-models and i dont want to put them all inside the main app.js file. Is there other way to do this?
Can i still somehow make it work inside the vue component, so the component can see the v-model and not giving me this error?
If not, can i make it work and use vue inside the blade file something like that?
new Vue({
el: '#form',
data: {
productname: ''
}
});
but this code its not working. Thanks!
It's a bit tricky to make out what you are doing exactly, but your error is related to having no data property 'message', you have only a property called 'productname'.
If you want your component to communicate up to its parents or siblings you should read into emitting events in vue using
this.$emit

How to pass custom nativescript-Vue component to custom child Component

I would like to add a dynamic child component to a parent component using Nativescript-Vue. For example:
<template>
<MyParentComponent>
<MyChildComponent :foo="foo"></MyChildComponent>
</MyParentComponent>
<template>
<script>
import MyParentComponent from './components/MyParentComponent';
import MyChildComponent from './components/MyChildComponent';
export default {
components: {
MyParentComponent,
MyChildComponent
},
data: function(){
return {
foo: ''
}
}
}
</script>
I think I need to define a slot in the parent component where the child component should be inserted, but I don't know how this should be done.
Any ideas?
In MyParentComponent's template you need to add a <slot /> tag, that's where Vue will insert the content.
Read more about slots, and what they can do in the Vue docs:
https://v2.vuejs.org/v2/guide/components.html#Content-Distribution-with-Slots

Laravel + Bootstrap-Vue Table not accepting data

I'm currently playing with Laravel Spark and I'm slowly learning the Vue.js system.
I have a bunch of data I want to display in a table that is pulled from AWS DynamoDB. I am successfully parsing this data in sorts of ways and can display the data in a standard static Bootstrap table. I'm now trying to use the Vue.js version and I cannot for the life of me get this data to display at all. If I insert dummy data into the Vue Component, the dummy data shows so it must be the way I'm passing the data in.
My code as follows:
TableController.php
public function show()
{
$data = $this->fetchAWSData($condition); // This is my separate AWS method
return view('table')->with('items', $data);
}
table.blade.php
#extends('spark::layouts.app')
#section('content')
<home :user="user" inline-template>
<div class="container-fluid" style="text-align: left">
<h1>Data</h1>
<MyTable items={{ $items }}></MyTable>
</div>
</home>
#endsection
MyTable.vue
<template>
<b-table striped hover :items=items></b-table>
</template>
<script>
export default {
data() {
return {
items: this.items
}
}
}
</script>
What am I doing wrong here? I've tried formatting my data all sorts of ways; JSON, manually, Arrays... nothing works. So it must be the way I'm passing it in.
Any insight would be AMAZING :)
You have to use props to be able to pass attributes to Vue's components.
MyTable.vue
...
<script>
export default {
props: ['items'],
}
</script>
Then you can pass data to component:
<MyTable :items="{{ $items }}">

Laravel Vuejs pass data from blade to .vue template

I am new in Vuejs. I have the following code and i am getting an error. I am trying to pass a var into vue file.
What do i do wrong? And how can i achieve this?
App.js:
window.Vue = require('vue');
Vue.component('formlements' ,require('./components/formelements/Input.vue') );
const app = new Vue({
el: '#app'
});
Blade:
<formlements :testinfo="{somekey: 'someinfo'}"></formlements>
Vue file
<template>
<div class="container">
{{testinfo.somekey}}
</div>
</template>
Error:
Property or method "testinfo" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property
As per my comment, you have not defined props on your component or app. Even though you have bound the variable to the prop using :bind, it is still not accessible to the component.
All you need to do is declare the prop, e.g. props: { testinfo: Object }.

Pass data from blade to vue component

I'm trying to learn vue and with that I want to integrate it with laravel too..
I simply want to send the user id from blade to vue component so I can perform a put request there.
Let's say I have this in blade:
<example></example>
How can I send Auth::user()->id into this component and use it.
I kept searching for this but couldn't find an answer that will make this clear.
Thanks!
To pass down data to your components you can use props. Find more info about props over here. This is also a good source for defining those props.
You can do something like:
<example :userId="{{ Auth::user()->id }}"></example>
OR
<example v-bind:userId="{{ Auth::user()->id }}"></example>
And then in your Example.vue file you have to define your prop. Then you can access it by this.userId.
Like :
<script>
export default {
props: ['userId'],
mounted () {
// Do something useful with the data in the template
console.dir(this.userId)
}
}
</script>
If you are serving files through Laravel
Then here is the trick that you can apply.
In Your app.blade.php
#if(auth()->check())
<script>
window.User = {!! auth()->user() !!}
</script>
#endif
Now you can access User Object which available globally
Hope this helps.
Calling component,
<example :user-id="{{ Auth::user()->id }}"></example>
In component,
<script>
export default {
props: ['userId'],
mounted () {
console.log(userId)
}
}
</script>
Note - When adding value to prop userId you need to use user-id instead of using camel case.
https://laravel.com/docs/8.x/blade#blade-and-javascript-frameworks
Rendering JSON
Sometimes you may pass an array to your view with the intention of rendering it as JSON in order to initialize a JavaScript variable. For example:
<script>
var app = <?php echo json_encode($array); ?>;
</script>
However, instead of manually calling json_encode, you may use the #json Blade directive. The #json directive accepts the same arguments as PHP's json_encode function. By default, the #json directive calls the json_encode function with the JSON_HEX_TAG, JSON_HEX_APOS, JSON_HEX_AMP, and JSON_HEX_QUOT flags:
<script>
var app = #json($array);
var app = #json($array, JSON_PRETTY_PRINT);
</script>
Just to add for those who still get error.
For me this <askquestionmodal :product="{{ $item->title }}"></askquestionmodal> still gives error in console and instead showing html page I saw white screen.
[Vue warn]: Error compiling template:
invalid expression: Unexpected identifier in
Coupling to connect 2 rods М14 CF-10
Raw expression: :product="Coupling to connect 2 rods М14 CF-10"
Though in error I can see that $item->title is replaced with its value.
So then I tried to do like that <askquestionmodal :product="'{{ $item->title }}'"></askquestionmodal>
And I have fully working code.
/components/askquestionmodal.vue
<template>
<div class="modal-body">
<p>{{ product }}</p>
</div>
</template>
<script>
export default {
name: "AskQuestionModal",
props: ['product'],
mounted() {
console.log('AskQuestionModal component mounted.')
}
}
</script>

Resources