SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 社員募集 ...

vue + vuex + vue-router のwebpackなしサンプル(コピペでできる)

問題

webpackとかLaravelなしで vue+vuex+vue-routerできないですか。

答え

htmlファイル1個と、jsファイル1個で、小さなSPA(Single Page Application)っぽいことをしてみる。

ファイル構成は以下のみ。

.
|-- index.html
`-- app.js

vue, vuex, vue-router はCDNから読み込めばOK(もちろんローカルにダウンロードして使ってもOK)。

jsはhtmlの中に <script>~</script> で書いても構わないけど、一応分けた。

HTML(index.html)

SPAでよく見る <div id=”app”></div> しかないHTML。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>vue + vue-router + vuex</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script src="https://unpkg.com/vuex"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.js"></script>
    <script defer src="app.js"></script>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>

スタイルシートはBootstrap4を入れた。

自前のCSSファイルがあれば追加で読み込んでよい。

es6-promise.auto.js はIE対策。Promiseのないブラウザ対策。不要なら削除してもよい。

JavaScript(app.js)

1つのファイルにすべてを書く。

const Home ={
    template: '<div>Homeです。</div>'
}
const Foo ={
    template: '<div><p>Foo画面です</p>'
        + '<button class="btn btn-info" v-on:click="$store.commit(\'increment\')">クリックするとカウンターが増えます {{ count }}回目</button></div>',
    computed: {
        count: function () {
            return this.$store.state.count
        }
    }
}
const Bar ={
    template: '<div><p>Bar画面です</p>'
        + '<button class="btn btn-success" v-on:click="$store.commit(\'increment\')">クリックするとカウンターが増えます {{ count }}回目</button></div>',
    computed: {
        count: function () {
            return this.$store.state.count
        }
    }
}

const routes = [
    { path: '/', component: Home },
    { path: '/foo', component: Foo },
    { path: '/bar', component: Bar }
]
const router = new VueRouter({
    routes: routes
})

const store = new Vuex.Store({
    state: {
        count: 0
    },
    mutations: {
        increment(state) {
            state.count++
        }
    }
});

const Navigation ={
    template: '<nav class="nav bg-light mb-3">'
        + '<router-link to="/" class="nav-link">Home</router-link>'
        + '<router-link to="/foo" class="nav-link">Foo</router-link>'
        + '<router-link to="/bar" class="nav-link">Bar</router-link>'
        + '</nav>'
}
const Footer ={
    template: '<footer class="fixed-bottom bg-light p-3">フッター</footer>',
}
const App ={
    template: '<div><Navigation/><div class="container-fluid"><router-view/></div><Footer/></div>',
    components: {
        Navigation: Navigation,
        Footer: Footer
    },
    computed: {
        count () {
            return this.$store.state.count
        }
    }
}

new Vue({
    el: '#app',
    router: router,
    store: store,
    template: '<App/>',
    components: {
        App: App
    }
});

ES6では以下のように短縮して書かれていることが多いですが、

components: {
    Navigation,
    Footer
},

JSONっぽいこちらの書き方で書いてます。

components: {
    Navigation: Navigation,
    Footer: Footer
},

結果

ちゃんとちょっとしたSPAらしい動きをする。

次は

node.js、npm、composer、Laravelなどに一切触れなくてもここまではできました。

こうしてみると課題が見えてきます。

結局webpack導入となるわけですね。

関連するメモ

コメント