kindle本「Vue.jsでTodoアプリを作ってみよう」のまとめ。
点数
78点
感想
内容が簡単なので、よく理解することができた。
Vuetifyが便利なので、もっと情報収集していきたい。
Vue.jsの基本
手順
- npm init -y
- npm install @vue/cli
- vue create myapp1
- cd myapp1
- npm run serve
v-on, v-model, v-for, v-bindを使ったコンポーネント
<template>
  <div>
    <p>@click:<a href="" @click="alertHoge" data-hoge="100">{{ title }}</a></p>
    <p>@change, @input:<input @change="handleTextChange" @input="handelTextInput"/></p>
    <p>v-model:<input v-model="title"/></p>
    v-for<p v-for="food in foods" :key="food.id">{{ food.name }}<button @click="deleteFood(food.id)">削除</button></p>
  </div>
</template>
<script>
export default {
  name: 'App',
  data() {
    return {
      title: 'hoge',
      foods: [
        {id: 1, name: 'apple'},
        {id: 2, name: 'lemon'},
      ]
    }
  },
  methods: {
    alertHoge(e) {
      window.alert(`hoge:${e.target.dataset.hoge}`);
    },
    handleTextChange(e) {
      console.log(`change:${e.target.value}`);
    },
    handelTextInput(e) {
      console.log(`input:${e.target.value}`);
    },
    deleteFood(id) {
      this.foods = this.foods.filter((food) => food.id !== id)
    },
  }
}
</script>コンポーネント間のやりとり
- 親⇒子
 propsとして渡す。
- 子⇒親
 this.$emit()を使って親のメソッドを実行する。
親コンポーネント
<Child msg="hello" @alertHoge="alertHogeHoge"/>
および
methods: {
  alertHogeHoge() {
    alert('hogehoge');
  }
}子コンポーネント
<template>
  <h3>{{ msg }}<button @click="alertHoge">this.$emitで親のaddHogeメソッドをコール</button></h3>
</template>
<script>
export default {
  name: 'Child',
  props: {
    msg: String
  },
  methods: {
    alertHoge(){
      this.$emit('alertHoge');
    }
  }
}
</script>ルーティング
- vue create history-router-app
 ※Manually select featuresを選択⇒Routerを選択
- src/components/にPageOne.vue, PageTwo.vueを作成
- router/index.jsを修正
import PageOne from '../components/PageOne'
import PageTwo from '../components/PageTwo'
および
const routes = [
  {
    path: '/',
    component: PageOne
  },
  {
    path: '/page2',
    component: PageTwo
  }
]※ デフォルトはHashモードなので、Hisotryモードにする場合はmodeオプションを指定する
const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})- App.vueを修正
<router-link to="/">ページ1</router-link> |
<router-link to="/page2">ページ2</router-link>
<button @click="toPage1">ページ1</button>
<button @click="toPage2">ページ2</button>
<router-view/>
および
methods: {
  toPage1() {
    this.$router.push('/');
  },
  toPage2() {
    this.$router.push('/page2');
  },
}Todoアプリ作成
- vue create todoapp
 ※Manually select featuresを選択⇒Routerを選択
- App.jsを修正<router-view/>とするだけ。
- router/index.jsを修正
import TodoForm from '../components/TodoForm'
import TodoList from '../components/TodoList'
および
const routes = [
  {
    path: '/',
    component: TodoList
  },
  {
    path: '/add',
    component: TodoForm
  }
]- TodoForm.vueを作成
<router-link to="/">一覧へ戻る</router-link>
<input type="text" v-model="newTodo"/>
<button @click="addTodo">登録</button>
および
addTodo() {
  const todos = JSON.parse(localStorage.getItem('todos')) || [];
  todos.push(this.newTodo);
  localStorage.setItem('todos', JSON.stringify(todos));
  this.newTodo = '';
  this.$router.push('/');
}- TodoList.vueを作成
<router-link to="/add">登録フォームへ</router-link>
<ul>
<li v-for="(todo, i) in todos" :key="i">{{ todo }}<button @click="deleteTodo(i)">削除</button></li>
</ul>
および
created() {
  this.todos = JSON.parse(localStorage.getItem('todos')) || [];
},
methods: {
  deleteTodo(i) {
    this.todos.splice(i, 1);
    localStorage.setItem('todos', JSON.stringify(this.todos));
  }
}VuetifyをTodoアプリに適用する
- vue add vuetify
- TodoList.vueを修正
<v-card>
  <div>
    <v-list-item v-for="(todo, i) in todos" :key="i">
      <v-list-item-content>
        <v-list-item-title>{{ todo }}</v-list-item-title>
      </v-list-item-content>
      <v-list-item-action>
        <v-btn @click="deleteTodo(i)" color="primary">
          <v-icon>mdi-delete</v-icon>
        </v-btn>
      </v-list-item-action>
    </v-list-item>
  </div>
</v-card>- TodoForm.vueを修正
<div>
  <v-text-field v-model="newTodo" placeholder="Todoを入力してください"/>
  <v-btn @click="addTodo" dark color="indigo">登録</v-btn>
</div>- App.vueを修正
<v-app>
  <v-main>
    <div>
      <v-toolbar color="primary" dark>
        <v-toolbar-title>Todoアプリ</v-toolbar-title>
      </v-toolbar>
    </div>
    <div>
      <v-tabs background-color="deep-purple accent-4" center-active dark>
        <v-tabs-slider color="yellow"></v-tabs-slider>
        <v-tab to="/">Todo一覧</v-tab>
        <v-tab to="/add">登録フォーム</v-tab>
      </v-tabs>
    </div>
    <div>
      <v-container fluid>
        <v-row>
          <v-col cols="3">
            <router-view />
          </v-col>
        </v-row>
      </v-container>
    </div>
  </v-main>
</v-app>※ <v-tab>のto属性を使えば<router-link>の記述は不要
アイコンのオフライン対応
デフォルトではindex.htmlの以下のタグでアイコンデータを外部から取得している。
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">サーバに置きたい場合、スマホアプリとして動作させたい場合、などは以下の手順が必要。
- npm install material-icons
- main.jsにimport 'material-icons/iconfont/material-icons.css'を追加
- index.htmlの<link>を削除
 
  
  
  
  

コメント