Vue.jsを使ったワンランク上のkintone開発

## はじめに
kintoneカスタマイズにおいて、
・データバインディングを使いたいとき
・ちょっと凝ったUIを作りたいとき
そんなときに便利なのがVue.jsです。
今回はそんなVue.jsを使ったワンランク上の開発手法を紹介します。

## 今回使うもの
* Node.js
    * https://qiita.com/satoyan419/items/56e0b5f35912b9374305
* Vue.js
    * https://jp.vuejs.org/index.html
    * Javascriptフレームワーク
    * データバインディングなどができる
    * kintone開発との相性が良い
* Element-ui
    * https://element.eleme.io/
    * UIフレームワーク
    * kintoneのデザインに溶け込むうえに、既存のレイアウトが崩れない
* Webpack
    * 複数jsファイルを一つのjsにコンパイルしてくれるモジュール
    * グローバル変数を汚さずに開発ができる

## テンプレートを用意したよ

```{bash}
git clone https://github.com/tonio0720/kintone-apptemplate
cd kintone-apptemplate
npm i # パッケージのインストール
npm run build # ビルド処理
```

### kintoneカスタマイズ
#### Javascript
* https://js.cybozu.com/vuejs/v2.5.17/vue.min.js
* https://unpkg.com/element-ui/lib/index.js
* main.js(ビルド処理で作成されたファイル)

#### CSS
* https://unpkg.com/element-ui/lib/theme-chalk/index.css
* https://unpkg.com/element-ui/lib/index.js
* main.css(ビルド処理で作成されたファイル)

### フォルダ構成
```{bash}
|--.eslintrc.json
|--build
|  |--main.css
|  |--main.css.map
|  |--main.js
|  |--main.js.map
|--package.json
|--src
|  |--app.js
|  |--components
|  |  |--Button.vue
|  |--style.scss
|--webpack.config.js
```

### build/
ビルドされたJavascript、CSSが生成される場所。
ここに生成された<code>main.js</code>, <code>main.css</code>をkintoneに添付してください。

### app.js
ここで、各コンポーネントをしかるべき場所に配置していきます。
下記の例では、<code>Button.vue</code>を一覧画面のヘッダーに配置しています。

```{javascript:app.js}
import locale from 'element-ui/lib/locale/lang/ja';
import Button from './components/Button.vue';
import './style.scss';

Vue.use(ELEMENT, { locale });

let vm1;

kintone.events.on('app.record.index.show', (event) => {

    const headerMenuEl = kintone.app.getHeaderMenuSpaceElement();

    if (vm1) {
        vm1.$destroy();
        vm1.$el.parentNode.removeChild(vm1.$el);
    }

    const el = document.createElement('div');
    headerMenuEl.appendChild(el);

    vm1 = new Vue({
        el,
        render: h => h(Button, {
            props: { event }
        })
    });

    return event;

});

```

### components/Button.vue
Vueは基本的にコンポーネント単位で作成するので、
components/の下にVueファイルを作成していきます。
https://element.eleme.io/#/en-US/component/installation
ElementはUIが豊富ですので、ドキュメントを参考にしながら作成していきましょう。

下記、一例です。

```{vue:Button.vue}
<template>
	<div>
		<el-button type="primary" @click="dialog = true">ボタン</el-button>
		<el-dialog title="ダイアログ" :visible.sync="dialog" width="30%">
			<el-form ref="form" :model="form" label-width="160px">
				<el-form-item label="テキスト">
					<el-input v-model="form.text"></el-input>
				</el-form-item>
				<el-form-item label="セレクト">
					<el-select v-model="form.select">
						<el-option label="セレクト1" value="1"></el-option>
						<el-option label="セレクト2" value="2"></el-option>
					</el-select>
				</el-form-item>
				<el-form-item label="日時">
					<el-col :span="11">
						<el-date-picker type="date" v-model="form.date" style="width: 100%;"></el-date-picker>
					</el-col>
					<el-col class="line" :span="2">-</el-col>
					<el-col :span="11">
						<el-time-picker v-model="form.time" style="width: 100%;"></el-time-picker>
					</el-col>
				</el-form-item>
				<el-form-item label="スイッチ">
					<el-switch v-model="form.switch"></el-switch>
				</el-form-item>
				<el-form-item label="チェックボックス">
					<el-checkbox-group v-model="form.check">
						<el-checkbox label="チェック1" name="check"></el-checkbox>
						<el-checkbox label="チェック2" name="check"></el-checkbox>
						<el-checkbox label="チェック3" name="check"></el-checkbox>
						<el-checkbox label="チェック4" name="check"></el-checkbox>
					</el-checkbox-group>
				</el-form-item>
				<el-form-item label="ラジオボタン">
					<el-radio-group v-model="form.radio">
						<el-radio label="ラジオ1"></el-radio>
						<el-radio label="ラジオ2"></el-radio>
					</el-radio-group>
				</el-form-item>
				<el-form-item label="テキストエリア">
					<el-input type="textarea" v-model="form.textarea"></el-input>
				</el-form-item>
			</el-form>
			<span slot="footer" class="dialog-footer">
				<el-button @click="dialog = false">キャンセル</el-button>
				<el-button type="primary" @click="dialog = false">OK</el-button>
			</span>
		</el-dialog>
	</div>
</template>

<script>

export default {
	props: [
		'event'
	],
	components: {},
	data() {
		return {
			dialog: false,
			form: {
				text: '',
				select: '',
				date: '',
				time: '',
				switch: '',
				check: [],
				radio: '',
				textarea: ''
			}
		};
	},
	computed: {

	},
	watch: {

	},
	methods: {

	},
	mounted() {

	}
}
</script>

<style lang="scss" scoped>
</style>
```

### その他ファイル
基本いじらなくてOKですが、お好みに合わせてカスタマイズしてください。

### こんなことができます
![apptemplate.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272803/295815de-d382-2108-67ad-34f58c5e05f0.gif)


### （余談）kintoneでBootstrapが使えないワケ
kintoneでBootstrapなどのCSSフレームワークを使うと、既存のレイアウトが崩れちゃったりします。
原因は<code>box-sizing: border-box</code>です。

#### box-sizingとは
例えば、CSSで<code>width</code>,<code>height</code>を<code>200px</code>とした際に、
<code>box-sizing: border-box</code>では<code>padding</code>や<code>border</code>を含めて<code>200px</code>とするが、
<code>box-sizing: content-box</code>では<code>padding</code>や<code>border</code>を含めずに<code>200px</code>とする。
Bootstrapでは<code>box-sizing: border-box</code>がグローバルに適応してしまうため、既存のレイアウトが崩れちゃうわけですね。

その点Element-uiはCSSのグローバルな指定が少なく、レイアウトが崩れないので便利ですね。

### （余談2）公式Vueコンポーネント？
https://github.com/kintone/vue-kintone-component
kintoneのGithubリポジトリにあるvue-kintone-componentってのが気になりますね。
使ってみたいですが、ドキュメントが見当たらない・・・