2022-02月vue开发总结

286 阅读3分钟

架构方面

数据管理

使用vuex,按页面来管理数据,每个页面目录下提供一个store.js文件。

store/index.js中通过require.context()来聚合所有页面目录下的store.js文件,创建为一个个的vuex数据模块。

尝试为每一个state,自动创建一个up开头,首字母大写的mutation。

为每个模块创建一个方便使用的mixin,方便组件使用。computed包含模块的stategettersmethods包含模块的mutationsactions

import { createNamespaceHelpers as cnh } from 'vuex';

function getKeys(obj) {
  if (!obj) obj = Object.create(null);
  return Object.keys(obj);
}

function createStoreMixin(module, moduleName) {
  const { state, mutations, getters, actions } = module;
  const { mapState, mapMutations, mapGetters, mapActions } = cnh(moduleName);
  return {
    computed: {
      ...mapState(getKeys(state)),
      ...mapGetters(getKeys(getters))
    },
    methods: {
      ...mapMutations(getKeys(mutations)),
      ...mapActions(getKeys())
    }
  };
}

将所有数据模块的mixin放入StoreMixin这个对象,并设置为全局(无需导入即可使用,通过ProvidePlugin)。

// vue.config.js

configureWebpack: {
  plugins: [
    new webpack.ProvidePlugin({
      StoreMixin: [path.resolve(__dirname, 'src/store'), 'StoreMixin']
    });
  ]
}

// .eslintrc.js
globals: {
  StoreMixin: true
}

请求发送

接口配置化,按后端微服务组织划分。

读取配置,自动构建请求。

根据环境(app/web),构建请求路径,选择请求器。

提供默认的请求报文解析。

使用vuex发送请求和管理响应数据

// store/index.js
export const $api = (api, postData, options) => {
  return store.dispatch('$api', { api, postData, options });
};
Vue.prototype.$api = $api;

数据mock

将app中的访问的数据,自动发送到开发端,并保存为mock文件。

接口请求时,可以指定返回mock文件数据。

// vue.config.js
devServer: {
  watchOptions: {
    ignored: [/mocks/]
  },
  before(app) {
    app.use(bodyParser.json());
    // 将接口数据保存到mock文件
    app.post(`/mock/save`, function(req, res) {
      // fs.mkdirSync(, { recursive: true }) // 递归创建目录
      // fs.writeFileSync()
      res.send('ok');
    });
    // 读取mock文件内容返回
    app.post(`/mock/file`, function(req, res) {
      // fs.readFileSync(, 'utf8')
      res.send(fileContent)
    });
  }
}

服务组件封装、提升使用的便捷性

  1. 提供fresourse的助手方法。
  2. viewWillAppear等服务组件方法作为组件的option使用。
function install(Vue) {
  const strats = Vue.config.optionMergeStrategies;
  strats.viewWillAppear = strats.created;
  
  Vue.mixin({
    created() {
      const fns = this.$options.viewWillAppear;
      if (fns) {
        viewWillAppear.set(() => {
          fns.forEach(fn => {
            try {
              fn.call(this);
            } catch (e) {} 
          });
        });
      }
    }
  });
}

3.物理栈路由参数混入$route.query

UI组件封装、二次封装

  1. Layout 转化default插槽作为content插槽,自动获取路由配置的title设置为页面标题,提供默认的返回方法并设置物理返回键。

  2. 封装Swiper组件,支持动态数据和2种使用方式。

  3. 封装选卡组件,提供triggerslot项。

  4. alertdialog便捷使用。

埋点封装

按页面拆分管理埋点事件,在每个页面目录下定义一个events.js文件。

events.js中按事件类型管理事件。

每个事件为一个方法,方法中处理埋点逻辑,并返回埋点业务参数。

在埋点事件方法中处理埋点逻辑的好处,可以从业务代码中剥离开。

提供页面级别的钩子设置页面通用埋点业务参数。

最终合并参数,构建埋点请求并发送。

埋点事件的方法自动绑定调用环境的this

代码管理

写README

先写README,再开发。

README中写业务需求、思考、测试啥都行,按着README写代码。

将数据处理放在顶层,就是store中。

组件的职责:view + controller

store(vuex)的职责:model

数据的存储、请求、处理都集中在store中。

好处

  1. 子组件或下游的组件无需处理,防止了重复处理数据的情况
  2. 由于所有的数据处理都集中在一块(store中),无需重复引入帮助函数等。
  3. 集中在一块,还可以方便修改与添加。

知识点

Array.prototype.splice

const arr = [1, 2, 3];
const idx = arr.indexOf(4);
arr.splice(idx, 1);
console.log(arr); // [1, 2]

一点要先判断idx > -1

idx > -1 && arr.splice(idx, 1);

window.onscroll

给window添加onscroll事件,事件处理器参数eventtarget属性为document。

document的onscroll事件的event.target也是document。

想要获取window的滚动高度,需要使用document.documentElement.scrollTop