Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TypeScriptで Vueを書いてみよう!

jiko21
June 22, 2019

TypeScriptで Vueを書いてみよう!

v-kansai Vue.js/Nuxt.js meetup #7の登壇資料です

jiko21

June 22, 2019
Tweet

More Decks by jiko21

Other Decks in Technology

Transcript

  1. TypeScriptで
    Vueを書いてみよう!
    Vue/Nuxt meetup #7
    Daiki Kojima (@Daikids2)

    View Slide

  2. https://speakerdeck.com/daikids2/typescriptde-vuewoshu-itemiyou

    View Slide

  3. ⼩島⼤基 (Daiki Kojima)
    [email protected]京⼤院(情報学)
    • Twitter: @Daikids2
    • GitHub: daikikojima

    View Slide

  4. Index
    • What is TypeScript
    • TSでコンポーネントを書いてみる
    • VuexでもTSを書いてみる
    • まとめ

    View Slide

  5. What is TypeScript

    View Slide

  6. About TypeScript
    • Microsoftが開発したAltJSの⼀種
    • ES5のスーパーセット
    • 型とか、ClassとかInterfaceが使える

    View Slide

  7. 型が使えてうれしいこと…
    • JSだとこのまま実⾏されてしまう。
    • 予期せぬバグの原因に
    • ちなみに…
    • add(a,b) -> 11 (string型)
    • mul(a,b) -> 1 (number型)
    function add (a, b) {
    return a + b;
    }
    function mul (a, b) {
    return a * b;
    }
    const a = 1;
    const b = “1";
    add(a, b);
    mul(a, b);

    View Slide

  8. TSだとこう書ける!
    • トランスパイルの段階で
    はじかれるし、
    VS Codeとかだと、書くだけで
    怒られる
    function add(a: number, b: number):
    number {
    return a + b;
    }
    function mul(a: number, b: number):
    number {
    return a * b;
    }
    const a = 1;
    const b = "1";
    console.log(add(a, b));
    console.log(mul(a, b));

    View Slide

  9. Interfaceが使えるぞ!!
    • (僕的には)TS使う⼀番の理由だったりする…
    • Object内のプロパティとその型を記述したもの
    • こんなやつです↓
    export default interface Todo {
    content: string;
    status: number;
    key: string;
    }

    View Slide

  10. JSDocとの違い
    • JSDocは何回も書く必要あり?
    • TSなら⼀度どっかに書いとけばそれをimportするだけでいい
    • entities/*.tsとか、models/*.tsとか
    /**
    * @param todo TODO Entity Object
    * @param {string} todo.content actual task
    * @param {number} todo.status status:
    {todo->0, doing->1, done->2}
    * @param {string} todo.key firebase key
    */
    export default interface Todo {
    content: string;
    status: number;
    key: string;
    }

    View Slide

  11. TSでComponentを書いてみる

    View Slide

  12. 気になったら…
    • https://github.com/daikikojima/Open-CharTo
    に実際に動かしているコードがあります。

    View Slide

  13. その前に…
    • Vue cliのバージョンは3以上
    • @vue/cliを使う
    • vue-cliはもうdeprecated
    • Nuxtの場合はまだ知らないです…

    View Slide

  14. Creating project
    • 思考停⽌してもできます!

    View Slide

  15. Class Style Componentって?
    import Vue from 'vue';
    import {mapGetters, mapActions, mapState} from 'vuex';
    export default Vue.extend({
    name: 'Header’,
    props: {
    isToggled: {
    type: Boolean,
    required: true,
    },
    doLogout: {
    type: Function,
    required: true,
    },
    toggleBurger: {
    type: Function,
    required: true,
    },
    },
    computed: {
    ...mapGetters(
    ['isLoggedIn’],
    ),
    },
    });
    普通に書いた場合 (Object Style)

    View Slide

  16. Class Style Componentって?
    import {Component, Prop, Vue} from "vue-property-decorator";
    import {mapGetters, mapActions, mapState} from 'vuex';
    @Component({
    computed: {
    ...mapGetters(
    ['isLoggedIn’],
    ),
    },
    })
    export default class Header extends Vue {
    @Prop() private isToggled!:boolean;
    @Prop() private doLogout!:() => {};
    @Prop() private toggleBurger!:() => {};
    }
    型周りはきれい

    View Slide

  17. 実は…
    https://github.com/vuejs/rfcs/pull/17#issuecomment-494242121

    View Slide

  18. RFCでは採⽤されないことに…
    • Rfc上でdropされました…
    • エッジケース・仕様依存・未解決の問題があるため
    • composition functionsのほうがいい
    ってEvan Youが⾔ってました…
    • 未だに@vue/cliでは使うに決まってるよね、
    と聞かれます

    View Slide

  19. VuexもTSで書いてみる

    View Slide

  20. Vuexってなんだっけ…
    • FluxをVueで簡単にやろうぜ! っていうやつ
    • Vuejsが管理しているように、
    Vueで簡単に扱えるように作られている。

    View Slide

  21. 公式の画像やけど…
    https://vuex.vuejs.org/ja/

    View Slide

  22. そのまえに…
    Page固有の
    Store
    Root Store
    • 基本的にこんな感じで
    ディレクトリ構成を考える

    View Slide

  23. Actions
    • VueからActionを受け取る部分
    • この中にどんどんactionを定義していく
    const actions: ActionTree = {...
    initialize({ commit }) {
    const user = this.state.user;
    if (user !== null) {
    firebaseRdbService.getTodos(user, (todos: TodoResponse|null) => {
    if (todos !== null) {
    commit('setTodos', objModule.objectToArrayWithKey(todos!));
    }
    });
    }
    },

    View Slide

  24. もし、RootStateを定義しない場合…
    • Anyで逃げてください
    • 特に、Reducksパターンとか、ページごとにStateが独⽴なら
    こうなることがあるかも!
    const actions: ActionTree

    View Slide

  25. Mutations
    • めっちゃかんたん
    • ここでも引数に型、つけられます!
    const mutations: MutationTree = {...
    const mutations: MutationTree = {
    setTodos(state: TopState, todos: Todo[]): void {
    state.todos = todos;
    },
    };

    View Slide

  26. Getters
    • これもかんたん!
    • 普通のTypeScriptですよね…
    const getters: GetterTree = {...
    const getters: GetterTree = {
    getAllTodos(state: TopState): TodoPacks|null {
    return {
    todo: filterTodos(state.todos, 0),
    doing: filterTodos(state.todos, 1),
    done: filterTodos(state.todos, 2),
    };
    },
    ...

    View Slide

  27. こうすると嬉しかったこと…
    • どこからどんなobjectが来るかが明⽰的にわかる!
    • いったんtypesとか、modelsみたいなとこに書いとけば
    それを参照するだけでいい!
    • 実際にはentitiesディレクトリを作ってそこにinterfaceは書いてます

    View Slide

  28. ただし…

    View Slide

  29. 当然⾟い部分も出てくる…

    View Slide

  30. (個⼈的に)⾟かった部分
    • Router部分のGuardの引数とか…
    • 参考してたサイトに従って型定義したけどダメ
    • (いま書いたりしてるけど)テストとか…
    • wrapper.vmにpropとかdataがないと⾔いやがる注意してくれる…

    View Slide

  31. 解決策

    View Slide

  32. Anyを使おう!!
    • そもそもここら辺ってあんま厳密な型はいらなそう
    • テストなんて動いてくれればいいでしょ (正論)

    View Slide

  33. Anyが恥ずかしいと思う⽅へ…
    https://twitter.com/__gfx__/status/1127816243040227330

    View Slide

  34. Anyは恥ずかしいくない!!
    • 確かに、Vue + TSは厳密にやろうとすると⾟い…
    •でも、使えるとこだけうまいことつかおうや?

    View Slide

  35. まとめ
    • VueもTSで書く時代です。
    • Componentを書くのはつらいかもしれない
    • Vuexはわりかし書きやすい
    •Anyは恥じゃない!!

    View Slide