Skip to content
This repository has been archived by the owner on Nov 5, 2022. It is now read-only.

Latest commit

 

History

History
106 lines (90 loc) · 2.29 KB

vuejs.md

File metadata and controls

106 lines (90 loc) · 2.29 KB

Vue.js example

Install dependencies:

npm install vue vue-server-renderer

Create a server.js file in the project root:

import Vue from 'vue'
import { createRenderer } from 'vue-server-renderer'

export default Component => ({ script, stylesheet }, props) => {
    const serializedProps = encodeURIComponent(JSON.stringify(props))
    const component = new Vue({
        render: createElement => createElement(Component, { props })
    })
    return createRenderer().renderToString(component).then(html => `
        <!DOCTYPE html>
        <html>
            <head>
                <title>${props.title}</title>
                ${stylesheet && `<link href="${stylesheet}" rel="stylesheet">`}
            </head>
            <body>
                <div id="root" data-props="${serializedProps}">${html}</div>
                <script src="${script}"></script>
            </body>
        </html>
    `)
}

Create a client.js file in the project root:

import Vue from 'vue'

export default Component => {
    const root = document.getElementById('root')
    const props = JSON.parse(decodeURIComponent(root.dataset.props))
    const component = new Vue({
        render: createElement => createElement(Component, { props })
    })
    component.$mount(root)
}

Add custom scripts and vue extension to settings.py:

'OPTIONS' : {
    'extensions': ['vue'],
    'scripts': {
        'server': os.path.join(BASE_DIR, 'server.js'),
        'client': os.path.join(BASE_DIR, 'client.js'),
    }
}

Add a Django view:

from django.shortcuts import render

def vue_view(request):
    return render(request, 'template.vue', context={
        'title': 'Django Vue SSR',
        'initialCount': 0
    })

Export the root component from template.vue:

<template>
    <div>
        <h1>Count {{ count }}</h1>
        <button v-on:click="increment">+</button>
        <button v-on:click="decrement">-</button>
    </div>
</template>

<script>
export default {
    props: {
        initialCount: Number
    },
    data() {
        return {
            count: this.initialCount
        }
    },
    methods: {
        increment() {
            this.count++
        },
        decrement() {
            this.count--
        }
    }
}
</script>