PHP
laravel
riot.js
laravel5.5

Laravel5.5 Riot.jsのセットアップ

概要

Laravel+Riot.jsを使ってみたかったのでその環境構築準備。
まともに使用したことがないので、より良い方法があったら指摘いただけると嬉しいです。
(yarnを使用しているので、npmの人は読み替えてください。)

この辺りを参考に上手く動かなかったので、試行錯誤した結果こうなった。
https://qiita.com/B73W56H84/items/b9968bd97e3128d891d0

環境

Laravel 5.5.42
PHP 7.1.16

プロジェクト作成およびライブラリ追加

# プロジェクト作成
composer create-project --prefer-dist laravel/laravel riot-demo "5.5.*"

# デフォルトで入っているものを削除(bootstrap, jQuery, vueなど)
php artisan preset none

# bootstrapが必要なら戻す
php artisan preset bootstrap

# laravel用のriotライブラリを追加
yarn add laravel-mix-riot

アセットコンパイル周りのソースを修正

app.js
require('./bootstrap');

// ここから下を追加
window.riot = require('riot');
webpack.mix.js
let mix = require('laravel-mix');

mix.riot = require('laravel-mix-riot');


/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix
    // riotに変更 
    //.js('resources/assets/js/app.js', 'public/js')
    .riot('resources/assets/js/app.js', 'public/js')
    .sass('resources/assets/sass/app.scss', 'public/css')
;

Todoアプリを実装

riot.jsの公式ページにあるTodoアプリを実装してみる。
https://riot.js.org/ja/play/todo/

resources/assets/js/todo/todo.tag
<todo>

    <h3>{ opts.title }</h3>

    <ul>
        <li each={ items.filter(whatShow) }>
            <label class={ completed: done }>
                <input type="checkbox" checked={ done } onclick={ parent.toggle }> { title }
            </label>
        </li>
    </ul>

    <form onsubmit={ add }>
        <input ref="input" onkeyup={ edit }>
        <button disabled={ !text }>Add #{ items.filter(whatShow).length + 1 }</button>

        <button type="button" disabled={ items.filter(onlyDone).length == 0 } onclick={ removeAllDone }>
            X{ items.filter(onlyDone).length } </button>
    </form>

    <!-- this script tag is optional -->
    <script>
        this.items = opts.items

        edit(e) {
            this.text = e.target.value
        }

        add(e) {
            if (this.text) {
                this.items.push({ title: this.text })
                this.text = this.refs.input.value = ''
            }
            e.preventDefault()
        }

        removeAllDone(e) {
            this.items = this.items.filter(function(item) {
                return !item.done
            })
        }

        // an two example how to filter items on the list
        whatShow(item) {
            return !item.hidden
        }

        onlyDone(item) {
            return item.done
        }

        toggle(e) {
            var item = e.item
            item.done = !item.done
            return true
        }
    </script>

</todo>
resources/assets/js/app.js
require('./bootstrap');

window.riot = require('riot');

// 追加
require('./todo/todo.tag');
resources/views/welcom.blade.php
<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>Demo: Riot.js</title>
    <link rel="stylesheet" href="{{ mix('/css/app.css') }}">

    <style type="text/css">

        body {
            font-family: 'myriad pro', sans-serif;
            font-size: 20px;
            border: 0;
        }

        todo {
            display: block;
            max-width: 400px;
            margin: 5% auto;
        }

        form input {
            font-size: 85%;
            padding: .4em;
            border: 1px solid #ccc;
            border-radius: 2px;
        }

        button {
            background-color: #1FADC5;
            border: 1px solid rgba(0,0,0,.2);
            font-size: 75%;
            color: #fff;
            padding: .4em 1.2em;
            border-radius: 2em;
            cursor: pointer;
            margin: 0 .23em;
            outline: none;
        }

        button[disabled] {
            background-color: #ddd;
            color: #aaa;
        }

        ul {
            padding: 0;
        }

        li {
            list-style-type: none;
            padding: .2em 0;
        }

        .completed {
            text-decoration: line-through;
            color: #ccc;
        }

        label {
            cursor: pointer;
        }
    </style>
</head>
<body>

<todo></todo>

<script src=" {{ mix('js/app.js') }} "></script>
<script>
    riot.mount('todo', {
        title: 'I want to behave!',
        items: [
            { title: 'Avoid excessive caffeine', done: true },
            { title: 'Hidden item',  hidden: true },
            { title: 'Be less provocative'  },
            { title: 'Be nice to people' }
        ]
    })
</script>
</body>
</html>
# アセットのコンパイル
yarn run dev

実行

スクリーンショット 2018-09-13 0.35.28.png