【心無旁騖】vuex-typescript-example

我不憚以最大的讚美去讚美這樣的項目,真的是很是有創意又有能力。
先放上我喜歡的這個項目的開源地址:https://github.com/gluons/vuex-typescript-example
咱們再看一下項目的效果

這是一個能夠存儲顏色的取色器呢,刷新頁面會發現顏色是有保存的,取色器中的顏色改變,左右兩個box的顏色也會改變。
接下來咱們來分析代碼
main.ts中通常定義全局公共組件和樣式等css

//main.ts
import Vue from 'vue';
// vuetify: 爲移動而生的Vue JS 2.0組件框架
import Vuetify from 'vuetify';

// Vuex store
import store from './store';

// Stylesheets
import 'vuetify/dist/vuetify.min.css';

// Components
import { Sketch } from 'vue-color';
import * as components from './components';

// Views
import Home from './views/Home.vue';

Vue.use(Vuetify);

Object.keys(components).forEach(name => {
    Vue.component(name, components[name]);
});
Vue.component('sketch-picker', Sketch);

new Vue({
    el: '#app',
    store,
    render: h => h(Home)
});

接下來看Home.vue頁面
Home.vue中還使用了jade的寫法,標籤都不須要呢~vue

<template lang="pug">
v-app#home
    v-toolbar.purple(dark)
        v-toolbar-title #[blank-link(url='https://github.com/vuejs/vuex/') Vuex] with #[blank-link(url='https://www.typescriptlang.org/') TypeScript] example
    main
        v-content
            v-container(fluid, grid-list-xl)
                v-layout(row, wrap, align-content-center, justify-space-around)
                    v-flex(xs12, md3, order-md2)
                        sketch-picker(:value='colour', @input='updateColor').picker-center
                    v-flex(xs12, md4, order-md1)
                        color-box(title='Box 1')
                    v-flex(xs12, md4, order-md3)
                        color-box(title='Box 2')
</template>

頗有意思的項目啊,當開源者的水平越高超,你可以欣賞到的代碼的快感就越強烈,越會有相逢恨晚的感受
接下來咱們看Home.vue中的ts部分
看到引入了
import { Getter } from '@/decorators';
我猜想那個時候,可能尚未裝飾器的功能,看到這裏將getters封裝了一層,好像是將getters變成store的全局變量

讓全局能夠使用getters函數
Home頁面中有一個取色器組件,他有一個updateColor方法git

//Home.vue
<template lang="pug">
v-app#home
    v-toolbar.purple(dark)
        v-toolbar-title #[blank-link(url='https://github.com/vuejs/vuex/') Vuex] with #[blank-link(url='https://www.typescriptlang.org/') TypeScript] example
    main
        v-content
            v-container(fluid, grid-list-xl)
                v-layout(row, wrap, align-content-center, justify-space-around)
                    v-flex(xs12, md3, order-md2)
                        sketch-picker(:value='colour', @input='updateColor').picker-center
                    v-flex(xs12, md4, order-md1)
                        color-box(title='Box 1')
                    v-flex(xs12, md4, order-md3)
                        color-box(title='Box 2')
</template>

<script lang="ts">
import Vue from 'vue';
import Component from 'vue-class-component';
import { Getter } from '@/decorators';

@Component({
    name: 'Home'
})
export default class Home extends Vue {
    @Getter('colour') colour: string;
    // Actions 支持一樣的載荷方式和對象方式進行分發:
    updateColor(newColor) {
        let newColorHex: string = newColor.hex;
        // newColorHex是deploy是載荷,傳遞的數據
        this.$store.dispatch('updateColor', newColorHex);
    }
}
</script>

<style scoped>
#home {
    margin-bottom: 1rem;
}
.picker-center {
    margin: 0 auto;
}
</style>

我仍是很疑問的,由於colorBox並無在Home.vue中定義,以至於我沒有結合colorBox進行分析項目github

//src\components\ColorBox.vue
<template lang="pug">
v-card(raised, hover)
    v-card-title(primary-title, v-if='hasTitle')
        span.title {{ title }}
    v-card-text
        .color-box(:data-color='colour', :style='boxStyle')
</template>

<script lang="ts">
import Vue from 'vue';
import Component from 'vue-class-component';
import { Getter } from '@/decorators';

@Component({
    name: 'ColorBox',
    props: {
        title: String
    }
})
export default class ColorBox extends Vue {
    @Getter('colour') colour: string;

    title: string;

    get hasTitle() {
        return !!this.title;
    }
    get boxStyle() {
        return {
            'background-color': this.colour
        };
    }
}
</script>

<style scoped>
.color-box {
    width: 150px;
    height: 150px;
    margin: 0 auto;
}
</style>
//src\components\BlankLink.vue
<template lang="pug">
a(:href='url', target='_blank', rel='noopener noreferrer')
    slot
</template>

<script lang="ts">
import Vue from 'vue';
import Component from 'vue-class-component';

@Component({
    name: 'BlankLink',
    props: {
        url: {
            type: String,
            required: true
        }
    }
})
export default class BlankLink extends Vue {}
</script>

<style lang="scss" scoped>
a {
    &, &:hover, &:visited {
        color: inherit;
        text-decoration: none;
    }
    &:hover {
        text-decoration: underline;
    }
}
</style>

state裏面定義color,color是個變量vuex

//src\store\state.ts
import randomColor from 'randomcolor';

export default class State {
    public color: string;

    constructor() {
        this.color = randomColor();
    }
}

getters中的color,從原有的定義中取出來typescript

//src\store\getters.ts
import { GetterTree } from 'vuex';

import State from './state';

// GetterTree<[current state], [root state]>
const getters: GetterTree<State, State> = {
    /*
     * It's just color with new name.
     * Example for using getters.
     */
    colour(state: State): string {
        return state.color;
    }
};

export default getters;

mutations同步處理函數app

//src\store\mutation-types.ts
export const COLOR = 'COLOR';
//src\store\mutations.ts
import { MutationTree } from 'vuex';

import { COLOR } from './mutation-types';
import State from './state';

const mutations: MutationTree<State> = {
    [COLOR](state: State, newColor: string): void {
        state.color = newColor;
    }
};

export default mutations;

看不懂這個
COLOR: void {
state.color = newColor;
}
action是進行異步處理的框架

//src\store\actions.ts
import { ActionContext, ActionTree } from 'vuex';

import { COLOR } from './mutation-types';
import State from './state';

// ActionTree<[current state], [root state]>
const actions: ActionTree<State, State> = {
    updateColor({ commit }: ActionContext<State, State>, newColor: string): void {
        commit(COLOR, newColor);
    }
};

export default actions;

updateColor這個更新函數,就能夠和updateColor進行結合了dom

相關文章
相關標籤/搜索