前端某项目总结

264 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

最近像是进入一种正向的迭代循环,每一天都很积极,像是有使不完的劲儿~

每个人的生命中都会有那么个人吧,一出现,世界变得生机勃勃,灿烂千阳。🙏

1.JavaScript部分:

a):bind.(null,args)像这样bind的第一个参数传入null的用法:

首先bind1个参数传null的话不改变this指向,而且可以在后续的调用中传入参数

function addThreeNum(x,y,z){
	return x+y+z;
}
var res = addThreeNum.bind(null,20);
console.log(res(500,1));

b)关于数组data通过forEach遍历去删除某个内容的时候,容易出现数组越界问题,从而导致想要删除的项目未被删除。

解决办法:

  • 通过forEach方法循环从data最后一项data[data.lengtth-1]开始反向开始查找要删除的项;而不是从index
  • 对数据源进行深拷贝([...data]的方式即可)

c)学会使用...来操作对象

  • 对于一些对象的属性,保留部分属性不变,而且修改几个变化的属性,那么使用...是个不错的选择;这样避免了把所有对象都写出来,一个个赋值。
    this.SHIJXB = sjxbData.map((sjxb:any) => ({
      ...sjxb,
      content: sjxb.FKNR,
      datetime: sjxb.FKSJ,
      userName: sjxb.FKRY,
      roleName: '',
    }));

d):关于mixins:

Mixin钩子按照传入顺序依次调用,并在调用组件自身的钩子之前被调用。

e):关于并行请求的处理:

    //...略
    let { rows: sjxbData = [] } = await this.getTicklingDatas({ attachId: this.id, querys: JSON.stringify([{ key: '是否反馈信息', value: '2', operate: '等于' }]) });
    const files: any = await Promise.allSettled(sjxbData.map((item:any) => getFiles({
      tableCn,
      uuid: item.UUID,
    })));
    //...略

Promise.allSettled返回一个在所有给定的 promise 都已经fulfilledrejected后的 promise,并带有一个对象数组,每个对象表示对应的 promise 结果

f):获取元素getElementById()querySelector()两种方法:

  • getElemnetById('map')
  • querySelector('#map')

2.CSS部分:

a):border实现渐变色:

border-bottom: 2px solid;
border-image: linear-gradient(90deg, rgba(0, 216, 247, 0) 0%, #00afed 100%) 2 2 2 2;

b):一些关于elementui样式的全局调整:

在项目中或多或少的会涉及对elementui样式进行重写,对于一些按钮下拉等复用程度比较高的样式,可以在src/assist文件夹下新建一个样式文件index.less或者index.css,然后将其引入到main.ts或者main.js中即可。

3.elementui组件库使用相关:

a):区分好template的嵌套层级,以及各自的使用场景和用途

            <PersonTables :showHeader="false" 	ref="selectedTables":data="storageSelectedPerson" key="selectedTables">
              <template slot="last-column" > ①🚀
                <el-table-column width="80" align="center" fixed="right">
                  <template slot-scope="{row,$index}"> ②🚀
                    <el-button 
                    	class="opt-btn" 
                      type="text" 
                      @click="cancelPerson(row,$index)">
                      	取消
                    </el-button>
                  </template>
                </el-table-column>
              </template>
            </PersonTables>

这里其实涉及到的是一个细节的问题,主要是针对于🚀位置的template:

  • 处:主要是的作用用是挂接名为名为last-columnslot插槽

  • 处:用于将el-table-column的数据,抛出来--slot-scope="{row,$index}",从而让<el-button>click事件处理函数能够获取到数据内容。

b):关于$listenerselementuiel-table中的使用:

1.在对于el-table表格进行二次封装的时候,在el-table上挂v-on="$listeners"属性

<template>
  <el-table class="idt-table" :ref="refName" v-bind="$attrs" v-on="$listeners" :data="data" style="width: 100%" :row-class-name="tableRowClassName" v-loading="loading">
    <slot name="first-column"></slot>
    <el-table-column
      prop="BT"
      label="案例名称"
      min-width="180">
    </el-table-column>
    <el-table-column
      prop="LX"
      align="center"
      label="案例类型">
    </el-table-column>
    <slot name="last-column"></slot>
  </el-table>
</template>

2.在页面中使用el-table组件时,可以直接在组件上挂elementui封装的el-table支持的事件,下面代码中的@row-click便是使用例子

  <AnLiTable @row-click='getEventPlace' :data='data' :max-height="maxHeight" :loading="loading">
    <template slot="last-column">
      <el-table-column
        label="操作"
        fixed="right"
        align="center"
        width="100">
        <template slot-scope="{row}">
          <el-button class="opt-btn" type="text" @click="showDetial(row)">查看</el-button>
        </template>
      </el-table-column>
    </template>
  </AnLiTable>

此外还支持如下图中的所列出来的事件:

c).关于按需引入组件引发的页面消失后闪现问题:

之前对于elementui组件的一些引用大多才用的是按需引入,大抵是通过import的方式引入到页面中。

但是在实际开发项目过程中发现,在一些需要动态切换页面的的场景时,才用按需引入的方式会出现消失后闪现的问题。

//...略
@Component({
  components: {
    // jydw_list: () => import('./ListDuiwu.view.vue'),
    // wzsb_list: () => import('./ListWuzi.view.vue'),
    // wxy_list: () => import('./ListWeixy.view.vue'),
    // bncs_list: () => import('./ListBins.view.vue'),
    // fhmb_list: () => import('./ListMub.view.vue'),
    // bns_list_around: () => import('./ListBinsAround.view.vue'),
    // yjdu_list_around: () => import('./ListDuiwuAround.view.vue'),
    // wz_list_around: () => import('./ListWuziAround.view.vue'),
    // wxy_list_around: () => import('./ListWeixyAround.view.vue'),
    // fhmb_list_around: () => import('./ListMubAround.view.vue'),
    jydw_list,
    wzsb_list,
    wxy_list,
    bncs_list,
    fhmb_list,
    bns_list_around,
    yjdu_list_around,
    wz_list_around,
    wxy_list_around,
    fhmb_list_around,
  },
})
// ...略

解决办法就是将异步按需引入,修改为同步导入

// eslint-disable-next-line camelcase
import jydw_list from './ListDuiwu.view.vue';
// eslint-disable-next-line camelcase
import wzsb_list from './ListWuzi.view.vue';
// eslint-disable-next-line camelcase
import wxy_list from './ListWeixy.view.vue';
// eslint-disable-next-line camelcase
import bncs_list from './ListBins.view.vue';
// eslint-disable-next-line camelcase
import fhmb_list from './ListMub.view.vue';
// eslint-disable-next-line camelcase
import bns_list_around from './ListBinsAround.view.vue';
// eslint-disable-next-line camelcase
import yjdu_list_around from './ListDuiwuAround.view.vue';
// eslint-disable-next-line camelcase
import wz_list_around from './ListWuziAround.view.vue';
// eslint-disable-next-line camelcase
import wxy_list_around from './ListWeixyAround.view.vue';
// eslint-disable-next-line camelcase
import fhmb_list_around from './ListMubAround.view.vue';

4.第三方库功能集入引发的思考:

目前项目是有专门的人在做地图demo功能,然后将功能集入项目中去。

这个也是感觉在项目中比较耗费时间的一个东西,项目的负责制作demo的人只负责单个功能的demo的实现。

带我的大佬和我在把地图demo上的功能往项目中集入的时候,功能多了之后功能和功能之间会有冲突的地方,从而导致地图功能失效。

后续也是花了大量的时间在解决,地图各个功能之间的冲突问题,下面算是项目过后的一些反思吧。

  • 封装第三方库的功能时,要思考每一步是干啥的,是否有必要性,要看代码,而不是cv

  • 在拆分功能的时候,一定要抽离出纯函数,通俗点说,就是将配置项抽离至参数,通过参数进行设置

  • 保持功能的单一纯净性,就是要保证所封装的功能不要参杂混入其他功能

最后的最后,还是希望自己能够提高那种解决问题的能力吧,以及学习的加速度,成为一个能成事儿人。