vue 項目總結一組件開發的配置和例子

原文地址:https://segmentfault.com/a/1190000012410259?_ea=2993723

先上 src 文件夾的結構圖:

clipboard.png

文件及文件夾作用

App.vue

App.vue: 根組件,pages 裏的組件會被插入此組件中,此組件再插入 index.html 文件裏,形成單頁面應用

根組件裏面是這樣子的:

clipboard.png

其中,<router-view> 組件是一個 functional 組件,渲染路徑匹配到的視圖組件。渲染的組件還可以內嵌自己的,根據嵌套路徑,渲染嵌套組件。這樣,就實現了單頁面下,根據不同路由,渲染不同組件的目的。

基本上根組件沒什麼交互要做,底部的樣式其實也可以放在全局的樣式表裏。


main.js

main.js: 入口 js 文件,影響全局,作用是引入全局使用的庫、公共的樣式和方法、設置路由等。

這個是負責配置影響全局的內容的文件,具體會有以下幾種作用:

1、引入vue 以及相關的庫

import Vue from 'vue'  //引入 vue

import store from './store'  //引入 vuex

import router from './router';  //引入路由配置文件

import App from './App'  //引入根組件

2、 引入需要用到的第三方庫(注意註冊使用方式的區別)

// 引入element-ui

import ElementUI from 'element-ui';

import 'element-ui/lib/theme-default/index.css';

Vue.use(ElementUI);

// 引入字體圖標樣式,這裏使用了阿里媽媽的 iconfont 字體庫

import '@assets/iconfont/iconfont.css';

import '@assets/iconfont/iconfont.js';

// 引入copy 信息組件

import VueClipboards from 'vue-clipboards';

Vue.use(VueClipboards);

// 引入 axios 庫

import axios from 'axios'

// 引入 d3 圖形庫

import * as d3 from 'd3'

// 引入國際化的庫

import VueI18n from 'vue-i18n';

Vue.use(VueI18n);

//引入自定義的 json 格式中英文對照文件

import zh from '@assets/lang/zh-CN'

import en from '@assets/lang/en-US'

Vue.config.lang = 'zh-cn'  //設置默認中文

Vue.locale('zh-cn', zh)

Vue.locale('en', en)

// 引入時間轉換模塊

import moment from 'moment';

moment.locale('zh-cn');

Vue.prototype.$moment = moment;  //將 moment 模塊轉換成 Vue 的原型方法,在組件裏可以直接使用 this.$moment(time)

// 引入圖表

import ECharts from 'vue-echarts';

Vue.component('chart', ECharts);  //註冊 Echarts 成爲全局組件,在組件裏可以直接調用 <chart></chart>    

3、 引入自定義的庫

// 引入銀行卡圖標樣式

import '@assets/icon-bank/iconfont.js';  // iconfont 上收集的銀行卡圖標

// 引入自定義的http模塊

import { AjaxApi } from '@http/AjaxApi.js';  //http 文件夾裏自定義的處理 api 接口的文件,導出一個包含所有與後臺接口交流的函數的對象

Vue.prototype.$axios = AjaxApi;  //加入 Vue 原型方法,組件裏通過 this.$axios.xxx() 調用

// 引入公共方法

import commonMixins from '@mixins/common-mixins.js';  //mixins 文件夾裏自定義的通用函數的集合

Vue.mixin(commonMixins);  //全局註冊混合

4、 引入自定義的公共樣式,使得組件內可以用scoped定義自身的樣式

// 引入公共樣式以及修改過的 element 樣式

import '@assets/css/common.less'

import '@assets/css/theme.less'

5、 定義一些簡短的不需要單獨引入的全局修改

 // 在html5 history 模式下,在form表單的組件(input輸入框等)裏點擊enter,會自動將表單數據以get的方式發送到後臺,需要阻止默認事件

document.onkeydown = function(e) {

    var e = e || event;

    if(e.keyCode == 13) {

        e.preventDefault ? e.preventDefault() : (e.returnValue = false);

    }

};

// 格式化金額,每三位加逗號,可選保留幾位小數

Number.prototype.format = function(n, x) {

    var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\.' : '$') + ')';

    return this.toFixed(Math.max(0, ~~n)).replace(new RegExp(re, 'g'), '$&,');

};
  

6、 設置vue的全局配置,在啓動應用前應用

Vue.config.productionTip = false;  // 阻止 vue 在啓動時生成生產提示    

7、 指定渲染的文件

 new Vue({

    el: '#app',

    template: '<App/>' ,

    router,

    store,

    components: { App }

})

assets 文件夾

assets: 放置靜態資源,包括公共的 css 文件、 js 文件、iconfont 字體文件、img 圖片文件以及其他資源類文件。

結構如下:

clipboard.png

css 文件夾裏會有重置 css 樣式的文件以及其他全局樣式文件。

js 文件夾裏放置了包含銀行字典和全國省市的字典文件,在組件裏引用之後遍歷獲取數據。


components 文件夾

components: 放置通用模塊組件。項目裏總會有一些複用的組件,例如彈出框、發送手機驗證碼、圖片上傳等,將它們作爲通用組件,避免重複工作;

結構如下:

clipboard.png

可以根據功能模塊建立文件夾,放置本功能會用到的通用組件。例如 login 文件夾裏可以放置註冊、登錄、重置密碼這幾個功能會用的共同模塊文件(賬號、密碼、圖形驗證碼、短信驗證碼); account-center 文件夾放置修改賬號相關的模塊。

全局通用的公共模塊可以不需要建立文件夾。


http 文件夾

http: 放置與後臺 api 相關的文件。這裏面有 axios 庫的實例配置文件、使用配置的 axios 實例接入 api 獲取數據的函數的集合的文件;

結構如下:

clipboard.png

config.js 是根據項目需求配置的 axios 實例文件,通過 axios.create([config]) 創建,可以配置諸如指定成功的狀態碼、序列化 params、設置 headers 、修改 token 、設置全局請求/響應攔截器、設置 baseURL 等。

AjaxApi.js 是通過導入 config.js 實例,傳入 API 和其他參數,給每個 API 配置一個專屬函數,再集合導出成對象的文件。例子如下:

clipboard.png


mixins 文件夾

mixins: 放置混合選項的文件。具體來說,相當於是公用函數的集合,在組件中引用時,可以作用於組件而不必書寫重複的方法

個人認爲,相當於是沒有 <template/> 和 <style/> 的組件,例子如下:

clipboard.png


pages 文件夾

pages: 放置主要頁面的組件。例如登錄頁、用戶信息頁等。通常是這裏的組件本身寫入一些結構,再引入通用模塊組件,形成完整的頁面

這裏面就是會被插入根組件的 <router-view/> 節點裏的文件,根據路由變化,根組件渲染不同的文件。

都是單文件組件,沒有特殊的結構,就不放圖了。


router 文件夾

router: 放置路由設置文件,指定路由對應的組件,設置路由鉤子

例子如下:

import Vue from 'vue';

import Router from 'vue-router';

import Tab from '@pages/tab';

import { MessageBox } from 'element-ui';

Vue.use(Router);

const router = new Router({  //新建路由

routes: [

    {

        path: '/',

        redirect: '/signin'  //重定向路由

    },

    {

        path: '/signin',

        name: 'signIn',  //命名路由

        component: (resolve) => {  //按需加載

            require(['@pages/sign-in'], resolve);

          }

      },

    {

        path: '/signup',

        name: 'signUp',

        component: (resolve) => {

            require(['@pages/sign-up'], resolve);

            }

        },

        {

            path: '/tab',

            component: Tab,

            children: [  //嵌套路由

                {

                    path: 'index',

                    name: 'index',

                    component: (resolve) => {

                    require(['@pages/index'], resolve);

                    }

                }

            ]

        }

    ]

});

router.beforeEach((to, from, next) => {  //檢測 token ,跳轉登錄頁

if (checkPathRequiredAuth(to.path) && !sessionStorage.token) {

    sessionStorage.clear();

    MessageBox({

        title: '跳轉提示',

        message: '用戶認證已過期或不存在,確認後跳轉到登錄頁',

        confirmButtonText: '確定',

        type: 'warning',

        callback: action => {

            next({

                path: '/signin'

            });

        }

    });

} else {

    next();

}

});

export default router;

store 文件夾

store: 放置 vuex 需要的狀態關聯文件,設置公共的 state、mutations 等

1、如果項目結構不是很複雜,多是父子組件的通信,可以使用 props 傳遞數據,$emit 和 on 事件通信,store 文件夾裏就只需創建 js 文件。

結構如下:

clipboard.png

2、反之,主要使用 vuex 來傳遞數據和通信的話,需要按照模塊來劃分 modules 。store 文件夾裏除了有index.js 和全局相關的 js 文件外,還有 modules 文件夾, 在 modules 文件夾里根據模塊創建對應的 js 文件,導出,最後在 store 文件夾下一級的 index.js 裏導入。

store 結構如下:

clipboard.png

modules 結構如下:

clipboard.png

sign-in.js:

clipboard.png

index.js:

clipboard.png

要注意的是,使用 modules 分割模塊後,組件裏獲取 state 時要指明對應的 modules。
computed: {
  ...mapState({
    data: state => state.signIn.data,  //sign-in.js 裏的 state
    user: state => state.user    //index.js 裏的 state
  })
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章