UniAppプロジェクト構築ガイド:uView UI統と効率的な状態管理

UniAppプロジェクト構築ガイド:uView UI統と効率的な状態管理

1. プロジェクトの初期セットアップ

HBuilderXでのプロジェクト作成:

ファイル > 新規 > プロジェクト > uni-appを選択 > プロジェクト名入力 > ディレクトリ選択 > デフォルトテンプレート > 作成

2. uView UIコンポーネントの導入

プラグインマーケットからインストール:

  1. uView UIプラグインページにアクセス
  2. 「HBuilderXでプラグインをインポート」をクリック

main.jsでの設定:

import uView from '@/uni_modules/uview-ui'
Vue.use(uView)

uni.scssでのインポート:

@import '@/uni_modules/uview-ui/theme.scss';

App.vueでのスタイル設定:

<style lang="scss">
    /* styleタグの最初行に記述し、lang="scss"を必ず付与 */
    @import "@/uni_modules/uview-ui/index.scss";
</style>

3. HTTP通信のカプセル化

utils/http.js - 基本設定:

export default (vm) => {
    uni.$u.http.setConfig((config) => {
        config.baseURL = 'https://api.example.com'
        config.timeout = 30000
        return config
    })

    uni.$u.http.interceptors.request.use((config) => {
        config.data = config.data || {}
        // 認証トークンをヘッダーに追加
        if (vm.$store.state.userToken) {
            config.header.Authorization = `Bearer ${vm.$store.state.userToken}`
        }
        return config
    })

    uni.$u.http.interceptors.response.use((response) => {
        const data = response.data
        if (response.statusCode === 200) {
            return data
        }
        
        if (response.statusCode === 401) {
            vm.$utils.redirectToLogin()
            return Promise.reject(data)
        }
        
        uni.$u.toast(data.message || 'リクエストエラー')
        return Promise.reject(data)
    })
}

main.jsでの初期化:

import httpConfig from '@/utils/http'
httpConfig(app)

api/index.js - APIエンドポイント定義:

const http = uni.$u.http

export const fetchUserInfo = () => http.get('/user/profile')
export const updateProfile = (data) => http.put('/user/profile', data)
export const getProducts = (params) => http.get('/products', { params })

4. Vuex状態管理の実装

store/index.js - ストア構成:

import Vue from 'vue'
import Vuex from 'vuex'
import persistedState from 'uni-persisted-state'

Vue.use(Vuex)

const store = new Vuex.Store({
    state: {
        userProfile: null,
        authToken: '',
        appConfig: {
            theme: 'light',
            language: 'ja'
        }
    },
    
    mutations: {
        SET_USER(state, payload) {
            state.userProfile = payload
        },
        SET_TOKEN(state, token) {
            state.authToken = token
        },
        UPDATE_CONFIG(state, config) {
            state.appConfig = { ...state.appConfig, ...config }
        }
    },
    
    actions: {
        async login({ commit }, credentials) {
            try {
                const response = await uni.$u.http.post('/auth/login', credentials)
                commit('SET_TOKEN', response.token)
                commit('SET_USER', response.user)
                return response
            } catch (error) {
                throw error
            }
        },
        
        logout({ commit }) {
            commit('SET_TOKEN', '')
            commit('SET_USER', null)
        }
    },
    
    plugins: [
        persistedState({
            paths: ['authToken', 'userProfile']
        })
    ]
})

export default store

main.jsでのストア統合:

import store from '@/store'

const app = new Vue({
    store,
    ...App
})

5. ルートとリクエストの認証制御

utils/auth.js - 認証チェック:

export default {
    install(Vue) {
        Vue.prototype.$auth = {
            checkToken() {
                return !!this.$store.state.authToken
            },
            
            requireAuth() {
                if (!this.checkToken()) {
                    const pages = getCurrentPages()
                    const currentPage = pages[pages.length - 1]
                    
                    uni.redirectTo({
                        url: `/pages/login/index?redirect=${currentPage.route}&${this.$utils.formatQuery(currentPage.options)}`
                    })
                    return true
                }
                return false
            }
        }
    }
}

main.jsでのプラグイン登録:

import AuthPlugin from '@/utils/auth'
Vue.use(AuthPlugin)

ページでの認証チェック:

export default {
    onLoad() {
        if (this.$auth.requireAuth()) return
        // 認証済みの場合の処理
    }
}

ログイン後のリダイレクト処理:

methods: {
    async handleLogin() {
        try {
            await this.$store.dispatch('login', this.formData)
            
            const pages = getCurrentPages()
            const redirectPage = pages.find(page => page.route.includes('login'))
            
            if (redirectPage && redirectPage.options.redirect) {
                const { redirect, ...params } = redirectPage.options
                const queryString = Object.keys(params).length ? 
                    '?' + Object.entries(params).map(([k, v]) => `${k}=${v}`).join('&') : ''
                
                uni.reLaunch({
                    url: `/${redirect}${queryString}`
                })
            } else {
                uni.switchTab({ url: '/pages/index/index' })
            }
        } catch (error) {
            console.error('ログイン失敗:', error)
        }
    }
}

5月26日 04:22 投稿