以下、バージョンの混在に注意。
CDNを利用する場合はインストールは不要。
※ただし後述する 単一ファイルコンポーネント等は使用できない。
<!-- 開発用 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- 開発用(バージョン指定) <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> <!-- 本番用 --> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <!-- 本番用(バージョン指定) --> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.min.js"></script>
npm i -g npm to update npm install -g @vue/cli
vue-cli を使用してプロジェクトの作成やローカル起動、ビルド等を行う事ができる。
npm i -g npm to update npm install -g @vue/cli
vue create sample-project
cd sample-project npm run serve
※ http://localhost:8080/ で確認
npm run build
※ dist 以下に出力される
※ 参考: https://jp.vuejs.org/v2/guide/deployment.html
Vueインスタンスを生成する事により、画面にデータを描画する事ができる。
また、Vueインスタンスを介して描画内容を変更する事も可能。
以下の通りVueインスタンスを生成して画面描画等を行う。
var vm = Vue({
.
.
})
指定できるオプション
| オプション | 内容 |
| data | UIの状態/データ |
| el | Vueインスタンスをマウントする要素 |
| filters | データの整形に使用する |
| methods | イベント発生時等の処理を関数として定義する |
| computed | データから派生して算出される値を関数として定義する |
<div id="app">
{{ message }}
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
// 2秒後にメッセージを書き換える
setTimeout(function(){
app.message = 'Change message!'
}, 2000);
</script>
後から動的に読み込んだコンテンツをマウントする場合等は、$mount メソッドを利用する。
<div id="app"></div>
<script>
var vm = new Vue({
template: '<p>{{message}}</p>',
data: {
message : 'Message!'
}
})
vm.$mount('#app')
</script>
filters プロパティを使用する事でローカルなフィルタを定義する事ができる
https://jp.vuejs.org/v2/guide/filters.html
<div id="app">
{{ message | toUpper }}
</div>
<script>
var vue = new Vue({
el: '#app',
data: {
message: 'Hello World!'
},
filters: {
toUpper : function(text){
return text.toUpperCase()
}
}
})
</script>
グローバルなフィルタを定義したい場合は、Vue.filter() を使用する
<div id="app">
{{ message | toUpper }}
</div>
<script>
Vue.filter('toUpper', function(text) {
return text.toUpperCase()
})
var vue = new Vue({
el: '#app',
data: {
message: 'Hello World!'
}
})
computed プロパティ使用すると加工済みデータの描画等を行う事が出来る。
filters プロパティと違い、対象データはVueインスタンスから得る。
https://jp.vuejs.org/v2/guide/computed.html
<div id="app">
<p>Message : {{ message }}</p>
<p>Upper message : {{ upperMessage }}</p>
</div>
<script>
var vue = new Vue({
el: '#app',
data: {
message: 'Hello World!'
},
computed: {
upperMessage: function(value){
return this.message.toUpperCase();
}
}
})
</script>
Vue.js のリアクティブシステムによる検知/要素の更新の他に、$watchメソッドによる状態の監視を行う事もできる。
<div id="app">
<input type="text" v-model="message" />
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!',
watch_message: ''
}
})
// メッセージが変わったらコンソールにログ出力
app.$watch(function(){
return this.message;
}, function(){
console.log('changed!');
});
// 2秒後にメッセージを変更
setTimeout(function(){
app.message = 'Change message!'
}, 2000);
</script>
コンポーネントを利用する事で画面を部分的に部品化して再利用する事ができる。
参考: https://jp.vuejs.org/v2/guide/components.html
例) クリックカウンターボタンをコンポーネント化して再利用する
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script>
</head>
<body>
<div id="components-demo">
<button-counter></button-counter>
<button-counter></button-counter>
</div>
<script>
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button v-on:click='count++'>click count is {{ count }}.</button>'
})
new Vue({ el: '#components-demo' })
</script>
</body>
</html>
画面や部品単位でvueファイル化する事によってコンポーネント化する事ができる。
※以下、ドキュメントまま。
関連: Vue.jsでコンポーネント化された画面を切り替える
<template>
<p>{{ greeting }} World!</p>
</template>
<script>
module.exports = {
data: function () {
return {
greeting: 'Hello'
}
}
}
</script>
<style scoped>
p {
font-size: 2em;
text-align: center;
}
</style>
https://jp.vuejs.org/v2/guide/events.html
v-if ディレクティブを使用して条件付きレンダリングを行う事ができる。
https://jp.vuejs.org/v2/guide/conditional.html
<div id="app">
<span v-if="display">Message1!</span>
<span v-else>Message2!</span>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
display: true
}
})
// 2秒後に表示を切り替える
setTimeout(function(){
app.display = false
}, 2000);
</script>
他に v-else-if や v-else も使用可能。
https://jp.vuejs.org/v2/guide/conditional.html#v-else
https://jp.vuejs.org/v2/guide/conditional.html#v-else-if
axios を使ってデータ通信を行う簡単なサンプル。
npm インストール
npm install --save-dev axios
利用例
import Vue from 'vue';
import axios from 'axios';
export default {
name: 'Page1',
mounted: function(){
axios
.get('/path_to/sample.json')
.then(response => {
console.log(response)
})
},
}
https://jp.vuejs.org/v2/guide/mixins.html
以下、ミックスインを使用して共通関数を定義する例を記載する。
src/components/MyMixin.js
import axios from 'axios';
export default {
name: 'MyMixin',
data: function(){
return {
CONTEXT_ROOT: "/"
}
},
methods: {
getData: function(url, option, callback){
console.log("get request: "+ this.CONTEXT_ROOT + url);
axios
.get(this.CONTEXT_ROOT + url, option)
.then(response => {
console.log(response);
callback(response)
})
}
}
}
src/components/Page1.vue
<template>
<div class="main">
<h1>Page1 content</h1>
<div>{{ results }}</div>
</div>
</template>
<script>
import myMixin from '../components/MyMixin.js';
export default {
mixins: [myMixin],
name: 'Page1',
data: function(){
return {
results: "データを読み込んでいます.."
}
},
mounted: function(){
this.getData(
'sample.json',
null,
response => {
this.results = response.data
}
);
}
}
</script>
Vue CLI を使用してプロジェクトの作成を行う場合は、マニュアルモードで作成する。(以下 Vue CLI v3.11.0 にて作成する例)
vue create sample-vue-router # 今回は手動インストールで以下の通り選択した。 ? Please pick a preset: Manually select features ? Check the features needed for your project: Babel, Router, Linter ? Use history mode for router? (Requires proper server setup for index fallback in production) No ※1 ? Pick a linter / formatter config: Basic ? Pick additional lint features: (Press to select, to toggle all, to invert selection)Lint on save ? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In dedicated config files ? Save this as a preset for future projects? (y/N) n
※1 ... historyモードの場合は、URLはロケーションハッシュで表現しない。
(Hisory API を使用してページのリロードなしに完全なURLとして表現される)
src/main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')
src/App.vue
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/page1">Page1</router-link> |
<router-link to="/page2">Page2</router-link> |
</div>
<div id="main">
<router-view/>
</div>
</div>
</template>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
}
#nav a {
font-weight: bold;
color: #2c3e50;
}
#nav a.router-link-exact-active {
color: #42b983;
}
</style>
src/router.js
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
routes: [
{ path: '/' , name: 'home' , component: () => import('./views/Home.vue') },
{ path: '/page1', name: 'page1', component: () => import('./views/Page1.vue') },
{ path: '/page2', name: 'page2', component: () => import('./views/Page2.vue') },
]
})
src/views/Home.vue
<template>
<h1>Home View</h1>
</template>
<script>
export default {
name: 'home',
components: {}
}
</script>
src/views/Page1.vue
<template>
<h1>Page1</h1>
</template>
<script>
export default {
name: 'page1',
components: {}
}
</script>
src/views/Page2.vue
<template>
<h1>Page1</h1>
</template>
<script>
export default {
name: 'page2',
components: {}
}
</script>