总结最近项目中学到的知识

222 阅读4分钟

前言

最近在项目中遇到一些问题,今天借着这篇文章记录一下,方便后面如果遇到同样的问题,可以查漏补缺,快速解决。

正文

vue组件里引入public的js文件

今天小伙伴需要在vue组件引入public的js文件,问我该怎么处理?

如果是直接使用相对路径,应该不会有问题,但是如果层级很深,就会出现下面这种情况

import xxx from '../../../../../js/xxx.js'

// xxx.js
const name = '答案cp3'
export default name

如果以后当前vue组件路径变了,这个相对路径也要改,维护相对麻烦,这个方案是下策。

如果是绝对路径呢?

import xxx from '/js/xxx.js'

这个eslint直接报错了,import不能直接使用绝对路径

Do not import modules using an absolute patheslint import/no-absolute-path

webpack也不支持,直接报错了

image.png

那还有什么方案?

是不是还可以用process.env.BASE_URL来拼接文件地址?

process.env.BASE_URL代表的是项目的路径

import xxx from process.env.BASE_URL + '/js/xxx.js'

直接编译不通过,SyntaxError:Unexpected token (4:16)

路径别名

尝试最后一种方案,webpack还支持路径别名的写法。

比如我们经常使用的@/views/@就是一个别名,代表的是src目录。

\node_modules\@vue\cli-service\lib\config\base.js路径下:

webpack设置@别名:

image.png

我们是不是也可以用public来代表public目录?

vue.config.js中添加:

第一种写法:

function resolve (dir) {
  return path.join(__dirname, dir)
}
// ...省略其它代码
configureWebpack: {
  resolve: {
    // 配置路径别名
    alias: {
      public: resolve('public')
    }
  }
}

第二种写法:

function resolve (dir) {
  return path.join(__dirname, dir)
}
// ...省略其它代码
chainWebpack: (config) => {
  config.resolve.alias
    .set('public', resolve('public'))
    .set('xxx',resolve('xxx'))
},

这样就可以在页面中使用

import xxx from 'public/xxx.js'

重新运行,没有报错,通过了。

补充:

如果你的xxx是压缩后的文件,可能会有eslint校验报错

image.png

这时候可以在.eslintignore文件添加忽略即可。

el-menu使用route.name跳转

如果要导航菜单,我们一般是使用elementUI的menu组件,它的样式和逻辑基本上都能满足需求,需要改动的地方不多。

举个例子:

<el-menu :default-active="route.path" router>
    <el-menu-item index="home">首页</el-menu-item>
    <el-submenu index="about">
        <template slot="title">关于</template> 
        <el-menu-item index="about-we">我们</el-menu-item> 
    </el-submenu> 
</el-menu>

因为el-menu它有提供router属性,我们就不用重新定义路由跳转的事件,它是取el-menu-item定义的index,当作path去跳转,所以我们el-menudefault-active需要取当前的path,否则不会高亮样式。

image.png

但是有时候route.path会有动态路径参数(类似 /user/:id/),和el-menu-item index可能不匹配,所以我会更喜欢使用route.nameindex,这样不管路径如何变,route.name还是可以对应的。

但是el-menu是把index当作path来跳转的,如果用route.name当作path跳转,一旦路由定义的namepath不一样,就会报404

所以el-menu-item还提供了一个参数route

image.png

通过这个route参数,我们可以定义跳转的route.name,还可以传query参数,或者parmas参数,很方便。

提供了route这个参数,el-menu就不会取index的值,而是优先route的参数去跳转。

示范的例子:

    <el-menu :default-active="route.name" router>
      <el-menu-item
        index="home"
        :route="{
          name: 'Home',
          query: {name: '首页'}
        }">首页</el-menu-item>
      <el-submenu index="about">
        <template slot="title">关于</template>
        <el-menu-item
          index="about-we"
          :route="{
            name: 'aboutWe',
            query: { name: '我们' }
          }">我们</el-menu-item>
      </el-submenu>
    </el-menu>

line-height与absolute混用

今天发现在一个div里面设置line-height,然后它的子元素设置position:absolute

<style>
.box {
  position: relative;
  width: 100px;
  height: 50px;
  line-height: 50px;
  border: 1px solid red;
}
.item {
  position: absolute;
  top: 0;
}
</style>
<div class="box">
  <div class="item">答案cp3</div>
</div>

image.png

可以看到子元素设置了top:0,并不是在顶部,而是居中显示。

你可能会认为line-heightabsolute的优先级还高。

非也。

其实是因为line-height是有继承性的,子元素继承了父元素的line-height,导致子元素高度也是50px,所以它设置top: 0也是在顶部。

只不过设置了line-height,文案垂直居中了,会让你误认为line-heightabsolute的优先级还高。

image.png

总结

很多时候我们遇到了问题,解决了问题就过去了,下次如果遇到同样问题还是一头雾水。

如果我们从问题中学到知识,并且把它总结下来,下次遇到问题快速解决,那么这就是一种进步。