I came across this error when trying to pass a JSON object from Laravel to a Vue component.
[Vue warn]: Invalid prop: type check failed for prop "myProperty". Expected Array, got String with value...
You may have passed a stringified JSON object which Vue is not parsing as an Array.
In my case, the error was I wasn't binding a property but passing a raw String that was meant to be evaluated by Vue as a JavaScript expression.
I was defining properties in Laravel PHP.
$collection = Post::all();
$numbers = [1,2,3];
Then passing them with the Blade templating syntax to my Vue component.
<issue-cover
v-bind:collection="{!! $collection->toJson() !!}"
my-numbers="{!! $numbers !!}"
><\/issue-cover>
As you can see, my-numbers
is not using the v-bind:property-name
or :property-name
(a short-hand to the former) syntax. That was all I had to do to solve this issue on my end.
<issue-cover
v-bind:collection="{!! $collection->toJson() !!}"
v-bind:my-numbers="{!! $numbers !!}"
><\/issue-cover>
If you multiple Vue components of the same type throughout your application but they're not in the same parent DOM element, mounting them may not be as easy as calling their parent.
In this first example, we can mount all of our button-counter
components by mounting their parent, #button-container
.
<div id="button-container">
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
We just need to make one call.
new Vue({ el: '#button-container' });
But what if our components are spread throughout different HTML elements?
Imagine you have components of the same (or different) types spread throughout your website's DOM.
<div>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
<div>
<button-counter></button-counter>
</div>
<button-counter></button-counter>
We can iterate through the DOM elements and mount them one by one.
// Obtain all button-counter elements
let elements = document.getElementsByTagName('button-counter');
// Convert HTMLCollection to array
let arr = Array.prototype.slice.call( elements )
// Loop through array and mount all elements
arr.forEach((el) => {
new Vue( { el });
});
Note that we had to convert the HTMLCollection
to a JavaScript array before we could call the .forEach()
function to iterate over the button-counter
host DOM nodes.
This works with Vue 2, and Vue 3 recently released new features for multi-root components and optional TypeScript support.
Change this.
window.Vue = require('vue');
For this.
window.Vue = require('vue').default;
Then this should work.
window.Vue = require('vue').default;
window.VueResource = require('vue-resource');
window.Vue.use(window.VueResource);