tl;dr:
Use
<example :data="{{ json_encode($data) }}"></example> for Blade and
props: ['data'] for component.
Beware of using
{!! !!} for content contains
" and
'.
—
Recently I write a lot of Laravel and VueJS 2 then faced with the common case when want to pass PHP variables to VueJS component.
There are a lot of proposed methods including pass as global JS variables, pass as a slot, and pass as a props.
Each one has its own advantages and disadvantages here I will explain.
Pass as global JS variables
This is the most straightforward solution and surely work. Moreover, there is a nice helper library for this Transform PHP Vars to JavaScript.
However, sometimes I only want to pass to a single component as maybe I use blade to render several components it once. And I against using global variables as it’s harder to track the issue. As a result, this is not suitable for my requirement.
Pass as a slot
This is a creative way of using VueJS ability to avoid escaping JSON as HTML entities by encoding JSON to the HTML tag and use VueJS to read it on mounted. However, it must be read manually every time and I believe it should be easier.
Pass as a prop
This should be the best way as a beginning without thinking because it is scoped to the component and automatically loaded. I browsed around the internet for awhile and wonder when most people suggest to use
{!! !!} instead of
{{ }} as the code will be more beautiful.
When you print JSON with
{{ }} it will escape HTML and change
" to
" which can be very ugly in HTML code. However, think about when your data contain
" and
' , there the problem comes.
It is inevitable to face
" and
' for the content generated by users, so you must escape the string.
Here is the example on how to pass data from Blade to VueJS component.
Blade
1 2 3 4 5 6 7 8 9 |
@php $quote = [ 'text' => 'Remember there\'s no such thing as a small act of kindness. Every act creates a ripple with no logical end.', 'author' => 'Scott Adams', 'fullText' => 'Scott Adams: "Remember there\'s no such thing as a small act of kindness. Every act creates a ripple with no logical end."', ]; @endphp <example :quote="{{ json_encode($quote) }}"></example> |
Vue Component
1 2 3 4 5 6 7 8 9 10 |
<script> export default { props: [ 'quote', ], mounted() { console.log(this.quote); } } </script> |
Open the web console and there you go. The quote should be printed correctly.
However, if you’re confident that your data will not contain
" you can use
{!! !!} as you wish.
But I would not go for safety sake and there is no reason to make HTML code readable on user web browser.
How about using less traffic to transfer the HTML?
Well, as gzip enabled it would not much different in compressed size.
Here are some references for further read.
- https://forum-archive.vuejs.org/topic/4584/tip-passing-json-from-back-end-to-front-end recommended
- https://stackoverflow.com/questions/36559391/pass-array-to-laravel-view-and-use-that-array-as-vuejs-prop
- https://stackoverflow.com/questions/44416598/how-to-pass-a-variable-from-laravel-5-4-to-vuejs
- https://laracasts.com/discuss/channels/vue/pass-json-to-a-vue-component
- https://stackoverflow.com/questions/35757575/laravel-pass-json-to-vue-js
- https://medium.com/@m_ramsden/passing-data-from-laravel-to-vue-98b9d2a4bd23
- https://laracasts.com/discuss/channels/laravel/pass-a-variable-to-vuejs