├── .gitignore ├── src ├── Components │ ├── Basic.php │ ├── Inline.php │ └── Component.php ├── Directives │ ├── Basic.php │ └── Inline.php ├── DirectiveServiceProvider.php └── Element.php ├── tests ├── TestCase.php ├── Unit │ ├── ElementTest.php │ ├── VueDirectiveTest.php │ └── ComponentTest.php └── Integration │ └── BladeTest.php ├── artisan ├── phpmd.xml ├── .gitlab-ci.yml ├── LICENSE.md ├── composer.json ├── phpunit.xml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.idea/ 3 | /vendor/ 4 | /node_modules/ 5 | /composer.phar 6 | /composer.lock 7 | /*.sublime-workspace 8 | /coverage 9 | .phpunit.result.cache 10 | -------------------------------------------------------------------------------- /src/Components/Basic.php: -------------------------------------------------------------------------------- 1 | setConfig([ 9 | 'test-suite' => require('./vendor/two-thirds/laravel-test-suite/config/default.php'), 10 | 'test-suite.php-cs-fixer.folders' => ['./src', './tests'], 11 | 'test-suite.phpmd.folders' => ['./src', './tests'] 12 | ]); 13 | 14 | $artisan->registerCommands([ 15 | TwoThirds\TestSuite\Console\RunTestCommand::class, 16 | TwoThirds\TestSuite\Console\RunPhpUnitCommand::class, 17 | TwoThirds\TestSuite\Console\RunPhpCsFixerCommand::class, 18 | TwoThirds\TestSuite\Console\RunPhpmdCommand::class, 19 | ]); 20 | 21 | exit($artisan->handle()); 22 | -------------------------------------------------------------------------------- /src/Directives/Basic.php: -------------------------------------------------------------------------------- 1 | '; 15 | } 16 | 17 | /** 18 | * Php code required to parse the expression and render the starting component html tag 19 | * 20 | * @param string $expression 21 | * @return string 22 | */ 23 | public static function start(string $expression) : string 24 | { 25 | return "
"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Directives/Inline.php: -------------------------------------------------------------------------------- 1 | '; 15 | } 16 | 17 | /** 18 | * Php code required to parse the expression and render the starting component html tag 19 | * 20 | * @param string $expression 21 | * @return string 22 | */ 23 | public static function start(string $expression) : string 24 | { 25 | return "
"; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /phpmd.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | Blade Vue Directive PHPMD rule set 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | image: php:7.2-cli 2 | 3 | before_script: 4 | - bash ci/docker_install.sh > /dev/null 5 | - wget https://composer.github.io/installer.sig -O - -q | tr -d '\n' > installer.sig 6 | - php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" 7 | - php -r "if (hash_file('SHA384', 'composer-setup.php') === file_get_contents('installer.sig')) { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" 8 | - php composer-setup.php 9 | - php -r "unlink('composer-setup.php'); unlink('installer.sig');" 10 | - export APP_ENV=testing 11 | - export APP_KEY=$(php -r 'echo md5(uniqid());') 12 | - php composer.phar install --prefer-dist --no-progress --no-suggest 13 | 14 | tests: 15 | script: 16 | - php artisan test:phpunit --without-tty 17 | 18 | phpCsFixer: 19 | script: 20 | - php artisan test:php-cs-fixer --without-tty 21 | 22 | messDetector: 23 | script: 24 | - php artisan test:phpmd --without-tty 25 | -------------------------------------------------------------------------------- /tests/Unit/ElementTest.php: -------------------------------------------------------------------------------- 1 | assertEquals('', $element->getStartTag()); 18 | $this->assertEquals('', $element->getEndTag()); 19 | } 20 | 21 | /** 22 | * @test 23 | */ 24 | public function newElementAddsBooleanAttributes() 25 | { 26 | $element = (new Element('newTag')) 27 | ->setAttribute('foobar', null); 28 | 29 | $this->assertEquals('', $element->getStartTag()); 30 | } 31 | 32 | /** 33 | * @test 34 | */ 35 | public function newElementAddsValueAttributes() 36 | { 37 | $element = (new Element('newTag')) 38 | ->setAttribute('foobar', 'bazqux'); 39 | 40 | $this->assertEquals('', $element->getStartTag()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Jordan Hoff 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/DirectiveServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->afterResolving('blade.compiler', function (BladeCompiler $bladeCompiler) { 27 | $bladeCompiler->directive('vue', function ($expression) { 28 | return Basic::start($expression); 29 | }); 30 | 31 | $bladeCompiler->directive('endvue', function () { 32 | return Basic::end(); 33 | }); 34 | 35 | $bladeCompiler->directive('inlinevue', function ($expression) { 36 | return Inline::start($expression); 37 | }); 38 | 39 | $bladeCompiler->directive('endinlinevue', function () { 40 | return Inline::end(); 41 | }); 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jhoff/blade-vue-directive", 3 | "description": "Vue directive for Laravel Blade", 4 | "keywords": [ 5 | "laravel", 6 | "blade", 7 | "vue.js" 8 | ], 9 | "homepage": "https://github.com/jhoff/blade-vue-directive", 10 | "license": "MIT", 11 | "authors": [ 12 | { 13 | "name": "Jordan Hoff", 14 | "email": "jhoff484@gmail.com" 15 | } 16 | ], 17 | "require": { 18 | "php": ">=7.0", 19 | "laravel/framework": "^5.4|^6.0|^7.0|^8.0" 20 | }, 21 | "require-dev": { 22 | "friendsofphp/php-cs-fixer": "^2.13|^2.16", 23 | "mockery/mockery": "^1.0|^1.3.1", 24 | "orchestra/testbench": "^4.0|^6.0", 25 | "phpmd/phpmd": "^2.6", 26 | "phpunit/phpunit": "^8.0|^9.3", 27 | "squizlabs/php_codesniffer": "^2.9|^3.5", 28 | "two-thirds/artisan-anywhere": "^1.2", 29 | "two-thirds/laravel-test-suite": "^4.1" 30 | }, 31 | "config": { 32 | "preferred-install": "dist", 33 | "sort-packages": true 34 | }, 35 | "autoload": { 36 | "psr-4": { 37 | "Jhoff\\BladeVue\\": "src" 38 | } 39 | }, 40 | "autoload-dev": { 41 | "psr-4": { 42 | "Jhoff\\BladeVue\\Testing\\": "tests" 43 | } 44 | }, 45 | "extra": { 46 | "laravel": { 47 | "providers": [ 48 | "Jhoff\\BladeVue\\DirectiveServiceProvider" 49 | ] 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | tests/Integration 14 | 15 | 16 | tests/Unit 17 | 18 | 19 | 20 | 24 | 26 | 29 | 30 | 31 | 32 | src 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /tests/Unit/VueDirectiveTest.php: -------------------------------------------------------------------------------- 1 | "bar"]'); 18 | 19 | $this->assertEquals( 20 | ' "bar"]); ?>
', 21 | $code 22 | ); 23 | } 24 | 25 | /** 26 | * @test 27 | */ 28 | public function basicEndDirectiveReturnsCorrectPhpBlock() 29 | { 30 | $code = Basic::end(); 31 | 32 | $this->assertEquals( 33 | '
', 34 | $code 35 | ); 36 | } 37 | 38 | /** 39 | * @test 40 | */ 41 | public function inlineStartDirectiveReturnsCorrectPhpBlock() 42 | { 43 | $code = Inline::start('"component", ["foo" => "bar"]'); 44 | 45 | $this->assertEquals( 46 | ' "bar"]); ?>
', 47 | $code 48 | ); 49 | } 50 | 51 | /** 52 | * @test 53 | */ 54 | public function inlineEndDirectiveReturnsCorrectPhpBlock() 55 | { 56 | $code = Inline::end(); 57 | 58 | $this->assertEquals( 59 | '
', 60 | $code 61 | ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Element.php: -------------------------------------------------------------------------------- 1 | name = $name; 29 | } 30 | 31 | /** 32 | * Gets the ending tag for the element 33 | * 34 | * @return string 35 | */ 36 | public function getEndTag() : string 37 | { 38 | return "name}>"; 39 | } 40 | 41 | /** 42 | * Gets the starting tag for the element 43 | * 44 | * @return string 45 | */ 46 | public function getStartTag() : string 47 | { 48 | $attributes = $this->renderAttributes(); 49 | 50 | return "<{$this->name}" . ($attributes ? ' ' . $attributes : '') . '>'; 51 | } 52 | 53 | /** 54 | * Sets the attribute on the element 55 | * 56 | * @param string $name 57 | * @param mixed $value 58 | * @return $this 59 | */ 60 | public function setAttribute(string $name, $value) 61 | { 62 | $this->attributes[$name] = $value; 63 | 64 | return $this; 65 | } 66 | 67 | /** 68 | * Builds an attribute string 69 | * 70 | * @param string $key 71 | * @param mixed $value 72 | * @return string 73 | */ 74 | protected function buildAttribute(string $key, $value) : string 75 | { 76 | if (is_numeric($key)) { 77 | return $value; 78 | } 79 | 80 | if (is_null($value)) { 81 | return $key; 82 | } 83 | 84 | return sprintf('%s="%s"', $key, $value); 85 | } 86 | 87 | /** 88 | * Renders all of the attributes in the proper format 89 | * 90 | * @return string 91 | */ 92 | protected function renderAttributes() : string 93 | { 94 | return implode(' ', array_map( 95 | [$this, 'buildAttribute'], 96 | array_keys($this->attributes), 97 | $this->attributes 98 | )); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /tests/Integration/BladeTest.php: -------------------------------------------------------------------------------- 1 | renderBasicBlade('"my-component"'); 15 | 16 | $this->assertStringContainsString('assertStringContainsString('is="my-component"', $output); 18 | $this->assertStringContainsString('', $output); 19 | } 20 | 21 | /** 22 | * @test 23 | */ 24 | public function bladeRendersAdvancedVueDirective() 25 | { 26 | $output = $this->renderBasicBlade('"my-component", ["foo" => "bar"]'); 27 | 28 | $this->assertStringContainsString('assertStringContainsString('is="my-component"', $output); 30 | $this->assertStringContainsString('foo="bar"', $output); 31 | $this->assertStringContainsString('', $output); 32 | } 33 | /** 34 | * @test 35 | */ 36 | public function bladeRendersInlineVueDirective() 37 | { 38 | $output = $this->renderInlineBlade('"my-component"'); 39 | 40 | $this->assertStringContainsString('assertStringContainsString('inline-template', $output); 42 | $this->assertStringContainsString('is="my-component"', $output); 43 | $this->assertStringContainsString('', $output); 44 | } 45 | 46 | /** 47 | * @test 48 | */ 49 | public function bladeRendersAdvancedInlineVueDirective() 50 | { 51 | $output = $this->renderInlineBlade('"my-component", ["foo" => "bar"]'); 52 | 53 | $this->assertStringContainsString('assertStringContainsString('inline-template', $output); 55 | $this->assertStringContainsString('is="my-component"', $output); 56 | $this->assertStringContainsString('foo="bar"', $output); 57 | $this->assertStringContainsString('', $output); 58 | } 59 | 60 | /** 61 | * Creates a vue file in the testbench views directory and renders it 62 | * 63 | * @param string $expression 64 | * @return string 65 | */ 66 | protected function renderBasicBlade(string $expression) 67 | { 68 | @file_put_contents( 69 | resource_path('views/vue.blade.php'), 70 | "@vue($expression)\n
Testing
\n@endvue" 71 | ); 72 | 73 | return view()->make('vue')->render(); 74 | } 75 | 76 | /** 77 | * Creates a vue file in the testbench views directory and renders it 78 | * 79 | * @param string $expression 80 | * @return string 81 | */ 82 | protected function renderInlineBlade(string $expression) 83 | { 84 | @file_put_contents( 85 | resource_path('views/vue.blade.php'), 86 | "@inlinevue($expression)\n
Testing
\n@endinlinevue" 87 | ); 88 | 89 | return view()->make('vue')->render(); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/Components/Component.php: -------------------------------------------------------------------------------- 1 | getEndTag(); 35 | } 36 | 37 | /** 38 | * Builds a component element and returns the starting element tag 39 | * 40 | * @param string $name 41 | * @param array $attributes 42 | * @return string 43 | */ 44 | public static function start(string $name, array $attributes = []) : string 45 | { 46 | if (count(func_get_args()) > 2) { 47 | throw new Exception('Too many arguments passed to vue directive'); 48 | } 49 | 50 | if (!empty($attributes) && !Arr::isAssoc($attributes)) { 51 | throw new Exception('Second argument for vue directive must be an associtive array'); 52 | } 53 | 54 | return (new static) 55 | ->setAttributes(static::$defaultAttributes) 56 | ->setAttribute('is', $name) 57 | ->setAttributes($attributes) 58 | ->getStartTag(); 59 | } 60 | 61 | /** 62 | * Instantiates a new component element to build off of 63 | */ 64 | protected function __construct() 65 | { 66 | $this->element = new Element('component'); 67 | } 68 | 69 | /** 70 | * Gets the end tag from the element 71 | * 72 | * @return string 73 | */ 74 | protected function getEndTag() : string 75 | { 76 | return $this->element->getEndTag(); 77 | } 78 | 79 | /** 80 | * Gets the start tag from the element 81 | * 82 | * @return string 83 | */ 84 | protected function getStartTag() : string 85 | { 86 | return $this->element->getStartTag(); 87 | } 88 | 89 | /** 90 | * Resolves the given attribute to vue component form 91 | * 92 | * @param string $name 93 | * @param mixed $value 94 | * @return array 95 | */ 96 | protected function resolveAttributeValue(string $name, $value) : array 97 | { 98 | if (is_bool($value)) { 99 | return [":$name", $value ? 'true' : 'false']; 100 | } 101 | 102 | if (is_numeric($value)) { 103 | return [":$name", $value]; 104 | } 105 | 106 | if (!is_scalar($value) && !is_null($value)) { 107 | return [":$name", e(json_encode($value))]; 108 | } 109 | 110 | return [$name, $value]; 111 | } 112 | 113 | /** 114 | * Resolve and set an attribute on the element 115 | * 116 | * @param string $name 117 | * @param mixed $value 118 | * @return $this 119 | */ 120 | protected function setAttribute(string $name, $value = null) 121 | { 122 | list($name, $value) = $this->resolveAttributeValue($name, $value); 123 | 124 | $this->element->setAttribute(Str::kebab($name), $value); 125 | 126 | return $this; 127 | } 128 | 129 | /** 130 | * Sets an array of attributes on the element 131 | * 132 | * @param array $attributes 133 | * @return $this 134 | */ 135 | protected function setAttributes(array $attributes) 136 | { 137 | foreach ($attributes as $name => $value) { 138 | $this->setAttribute($name, $value); 139 | } 140 | 141 | return $this; 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /tests/Unit/ComponentTest.php: -------------------------------------------------------------------------------- 1 | assertRegExp('/\/', $tag); 21 | $this->assertRegExp('/[\s\>]v-cloak[\s\>]/', $tag); 22 | $this->assertRegExp('/[\s\>]is="foobar"[\s\>]/', $tag); 23 | } 24 | 25 | /** 26 | * @test 27 | */ 28 | public function inlineComponentRendersStartTag() 29 | { 30 | $tag = Inline::start('foobar'); 31 | 32 | $this->assertRegExp('/\/', $tag); 33 | $this->assertRegExp('/[\s\>]inline-template[\s\>]/', $tag); 34 | $this->assertRegExp('/[\s\>]v-cloak[\s\>]/', $tag); 35 | $this->assertRegExp('/[\s\>]is="foobar"[\s\>]/', $tag); 36 | } 37 | 38 | /** 39 | * @test 40 | */ 41 | public function basicComponentRendersEndTag() 42 | { 43 | $tag = Basic::end(); 44 | 45 | $this->assertEquals('', $tag); 46 | } 47 | 48 | /** 49 | * @test 50 | */ 51 | public function tooManyArgumentsThrowsException() 52 | { 53 | try { 54 | Basic::start('foobar', [], 'this is invalid'); 55 | } catch (Exception $exception) { 56 | $this->assertEquals('Too many arguments passed to vue directive', $exception->getMessage()); 57 | return; 58 | } 59 | 60 | $this->fail('Failed to throw exception with too many arguments'); 61 | } 62 | 63 | /** 64 | * @test 65 | */ 66 | public function nonArraySecondArgumentThrowsTypeError() 67 | { 68 | try { 69 | Basic::start('foobar', 'this is invalid'); 70 | } catch (TypeError $typeError) { 71 | $this->assertStringContainsString('::start() must be of the type array', $typeError->getMessage()); 72 | return; 73 | } 74 | 75 | $this->fail('Failed to throw type error with non array second argument'); 76 | } 77 | 78 | /** 79 | * @test 80 | */ 81 | public function nonAssociativeArraySecondArgumentThrowsException() 82 | { 83 | try { 84 | Basic::start('foobar', [1, 2, 3]); 85 | } catch (Exception $exception) { 86 | $this->assertEquals( 87 | 'Second argument for vue directive must be an associtive array', 88 | $exception->getMessage() 89 | ); 90 | return; 91 | } 92 | 93 | $this->fail('Failed to throw exception with non associtive array second argument'); 94 | } 95 | 96 | /** 97 | * @test 98 | */ 99 | public function componentWithBooleanArgumentsRendersStartTag() 100 | { 101 | $tag = Basic::start('foobar', ['foo' => true, 'baz' => false]); 102 | 103 | $this->assertRegExp('/[\s\>]:foo="true"[\s\>]/', $tag); 104 | $this->assertRegExp('/[\s\>]:baz="false"[\s\>]/', $tag); 105 | } 106 | 107 | /** 108 | * @test 109 | */ 110 | public function componentWithScalarArgumentsRendersStartTag() 111 | { 112 | $tag = Basic::start('foobar', ['foo' => 'bar', 'baz' => 123]); 113 | 114 | $this->assertRegExp('/[\s\>]foo="bar"[\s\>]/', $tag); 115 | $this->assertRegExp('/[\s\>]:baz="123"[\s\>]/', $tag); 116 | } 117 | 118 | /** 119 | * @test 120 | */ 121 | public function componentWithArrayOrObjectArgumentsRendersStartTag() 122 | { 123 | $tag = Basic::start( 124 | 'foobar', 125 | [ 126 | 'foo' => [1, 2, 3], 127 | 'bar' => (object) ['foo' => 'bar'], 128 | 'baz' => ['baz' => 'qux'] 129 | ] 130 | ); 131 | 132 | $this->assertRegExp('/[\s\>]:foo="\[1,2,3\]"[\s\>]/', $tag); 133 | $this->assertRegExp('/[\s\>]:bar="{"foo":"bar"}"[\s\>]/', $tag); 134 | $this->assertRegExp('/[\s\>]:baz="{"baz":"qux"}"[\s\>]/', $tag); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Laravel Blade Vue Directive 2 | ============== 3 | 4 | Laravel Blade Vue Directive provides blade directives for vue.js single file and inline template components. 5 | 6 | [![Latest Stable Version](https://img.shields.io/github/release/jhoff/blade-vue-directive.svg?style=flat-square)](https://packagist.org/packages/jhoff/blade-vue-directive) 7 | [![Total Downloads](https://img.shields.io/packagist/dt/jhoff/blade-vue-directive.svg?style=flat-square)](https://packagist.org/packages/jhoff/blade-vue-directive) 8 | [![MIT License](https://img.shields.io/packagist/l/jhoff/blade-vue-directive.svg?style=flat-square)](https://packagist.org/packages/jhoff/blade-vue-directive) 9 | [![Build Status](https://scrutinizer-ci.com/g/jhoff/blade-vue-directive/badges/build.png?b=master)](https://scrutinizer-ci.com/g/jhoff/blade-vue-directive/build-status/master) 10 | [![Code Coverage](https://scrutinizer-ci.com/g/jhoff/blade-vue-directive/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/jhoff/blade-vue-directive/?branch=master) 11 | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/jhoff/blade-vue-directive/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/jhoff/blade-vue-directive/?branch=master) 12 | 13 | 14 | 15 | - [Upgrade from 1.1.x to 2.0.0](#upgrade-from-11x-to-200) 16 | - [Installation](#installation) 17 | - [Usage](#usage) 18 | - [Basic Example](#basic-example) 19 | - [Scalars Example](#scalars-example) 20 | - [Booleans and Numbers Example](#booleans-and-numbers-example) 21 | - [Objects and Arrays Example](#objects-and-arrays-example) 22 | - [camelCase to kebab-case](#camelcase-to-kebab-case) 23 | - [Using compact to pass variables directly through](#using-compact-to-pass-variables-directly-through) 24 | 25 | 26 | 27 | 28 | ## Upgrade from 1.1.x to 2.0.0 29 | 30 | In 2.0, the `@vue` and `@endvue` directives have been renamed to `@inlinevue` and `@endinlinevue`. The new `@vue` and `@endvue` directives should now be used for non-inline components. 31 | 32 | **WARNING: You'll need to make sure that you run `php artisan view:clear` after upgrading** 33 | 34 | 35 | ## Installation 36 | 37 | To install the Laravel Blade Vue Directive, simply run `composer require jhoff/blade-vue-directive` in a terminal, or if you prefer to manually install you can the following in your `composer.json` file and then run `composer install` from the terminal: 38 | 39 | ```javascript 40 | { 41 | "require": { 42 | "jhoff/blade-vue-directive": "2.*" 43 | } 44 | } 45 | ``` 46 | 47 | For Laravel 5.5 and later, the package will automatically register. If you're using Laravel before 5.5, then you need to add the provider to the providers array of `config/app.php`. 48 | 49 | ```php 50 | 'providers' => [ 51 | // ... 52 | Jhoff\BladeVue\DirectiveServiceProvider::class, 53 | // ... 54 | ], 55 | ``` 56 | 57 | 58 | ## Usage 59 | 60 | The Laravel Blade Vue Directive was written to be simple and intuitive to use. It's not opinionated about how you use your vue.js components. Simply provide a component name and (optionally) an associative array of properties. 61 | 62 | 63 | ### Basic Example 64 | 65 | Using the vue directive with no arguments in your blade file 66 | 67 | ```html 68 | @vue('my-component') 69 |
Some optional slot content
70 | @endvue 71 | ``` 72 | 73 | Renders in html as 74 | 75 | ```html 76 | 77 |
Some optional slot content
78 |
79 | ``` 80 | 81 | Note that the contents between the start and end tag are optional and will be provided as [slot contents](https://vuejs.org/v2/guide/components-slots.html). To use an inline-template, use the `@inlinevue` directive instead: 82 | 83 | ```html 84 | @inlinevue('my-component') 85 |
Some inline template content
86 | @endinlinevue 87 | ``` 88 | 89 | Renders in html as 90 | 91 | ```html 92 | 93 |
Some inline template content
94 |
95 | ``` 96 | 97 | 98 | ### Scalars Example 99 | 100 | Using the vue directive with an associative array as the second argument will automatically translate into native properties that you can use within your vue.js components. 101 | 102 | ```html 103 | @vue('page-title', ['title' => 'Welcome to my page']) 104 |

@{{ title }}

105 | @endvue 106 | ``` 107 | 108 | Renders in html as 109 | 110 | ```html 111 | 112 |

{{ title }}

113 |
114 | ``` 115 | 116 | Then, to use the properties in your vue.js component, add them to `props` in your component definition. See [Component::props](https://vuejs.org/v2/guide/components.html#Props) for more information. 117 | 118 | ```javascript 119 | Vue.component('page-title', { 120 | props: ['title'] 121 | }); 122 | ``` 123 | 124 | 125 | ### Booleans and Numbers Example 126 | 127 | Properties that are booleans or numeric will be bound automatically as well 128 | 129 | ```html 130 | @vue('report-viewer', ['show' => true, 'report' => 8675309]) 131 |

Report #@{{ report }}

132 | @endvue 133 | ``` 134 | 135 | Renders in html as 136 | 137 | ```html 138 | 139 |

Report #{{ report }}

140 |
141 | ``` 142 | 143 | 144 | ### Objects and Arrays Example 145 | 146 | The vue directive will automatically handle any objects or arrays to make sure that vue.js can interact with them without any additional effort. 147 | 148 | ```html 149 | @vue('welcome-header', ['user' => (object)['name' => 'Jordan Hoff']]) 150 |

Welcome @{{ user.name }}!

151 | @endvue 152 | ``` 153 | 154 | Renders in html as 155 | 156 | ```html 157 | 158 |

Welcome {{ user.name }}!

159 |
160 | ``` 161 | 162 | Notice that the object is json encoded, html escaped and the property is prepended with `:` to ensure that vue will bind the value as data. 163 | 164 | To use an object property in your component, make sure to make it an `Object` type: 165 | 166 | ```javascript 167 | Vue.component('welcome-header', { 168 | props: { 169 | user: { 170 | type: Object 171 | } 172 | } 173 | }); 174 | ``` 175 | 176 | 177 | ### camelCase to kebab-case 178 | 179 | If you provide camel cased property names, they will automatically be converted to kebab case for you. This is especially useful since vue.js will [still work](https://vuejs.org/v2/guide/components.html#camelCase-vs-kebab-case) with camelCase variable names. 180 | 181 | ```html 182 | @vue('camel-to-kebab', ['camelCasedVariable' => 'value']]) 183 |
You can still use it in camelCase see :) @{{ camelCasedVariable }}!
184 | @endvue 185 | ``` 186 | 187 | Renders in html as 188 | 189 | ```html 190 | 191 |
You can still use it in camelCase see :) {{ camelCasedVariable }}!
192 |
193 | ``` 194 | 195 | Just make sure that it's still camelCased in the component props definition: 196 | 197 | ```javascript 198 | Vue.component('camel-to-kebab', { 199 | props: ['camelCasedVariable'] 200 | }); 201 | ``` 202 | 203 | 204 | ### Using compact to pass variables directly through 205 | 206 | Just like when you render a view from a controller, you can use compact to pass a complex set of variables directly through to vue: 207 | 208 | ```html 209 | 210 | @vue('compact-variables', compact('one', 'two', 'three')) 211 |
Variables are passed through by name: @{{ one }}, @{{ two }}, @{{ three }}.
212 | @endvue 213 | ``` 214 | 215 | Renders in html as 216 | 217 | ```html 218 | 219 |
Variables are passed through by name: {{ one }}, {{ two }}, {{ three }}.
220 |
221 | ``` 222 | 223 | Then in vue, make sure to define all of your properties: 224 | 225 | ```javascript 226 | Vue.component('compact-variables', { 227 | props: ['one', 'two', 'three'] 228 | }); 229 | ``` 230 | --------------------------------------------------------------------------------