0 Eslint报错的通用解决方式
- 鸵鸟算法:在命令行和编译器中直接忽略
- 按照提示修改代码
- 根据报错信息修改配置文件,忽略一些特殊规则
1.导入文件夹的错误
报错信息:error: '__WebpackModuleApi' is not defined (no-undef)
解决方案 :在eslint的配置文件中添加以下这一句,全局可用
module.exports = {
"globals":{ "__WebpackModuleApi":"writable" }
}
2.Vue中的@
在Vue中@是src目录的别名
JS中的使用方法
import Tabs from '@/components/Tabs.vue';
CSS/SCSS的方法
@import "~@/assets/style/reset.scss";
3.Vue2中使用TS的基础模板
<template>
<div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import {Component} from 'vue-property-decorator';
@Component
export default class Name extends Vue {
XXX=YYY// 一般变量使用赋值写法
zzz(){}// 函数直接写函数体即可
}
</script>
<style lang='scss' scoped>
</style>
注意TS不会对模板中的JS进行检查
4.固定位置的模块使用什么布局
在手机中fix定位会出现非常多的BUG,可以使用以下配合的flex布局
- 主体部分
flex-grow:1,保证主体尽量占据剩余空间 - 超出页面长度时使用
overflow:auto
5. Vue+TS中使用SVG
- shims-vue.d.ts中声明类型
declare module '*.svg' {
const content: any
export default content
}
- 配置
下载 svg-sprite-loader
然后在vue.config.js中添加
chainWebpack: config => {
const dir = path.resolve(__dirname, 'src/assets/icons')
config.module
.rule('svg-sprite')
.test(/\.(svg)(\?.*)?$/)
.include.add(dir).end()
.use('svg-sprite-loader-mod').loader('svg-sprite-loader-mod').options({extract: false}).end()
.use('svgo-loader').loader('svgo-loader')
//.tap(options => ({...options, plugins: [{removeAttrs: {attrs: 'fill'}}]}))
.end()
config.plugin('svg-sprite').use(require('svg-sprite-loader-mod/plugin'), [{plainSprite: true}])
config.module.rule('svg').exclude.add(dir)
}
- 使用
<svg class="icon" >
<use :xlink:href="'#'+name"/>
</svg>
- SVG自带颜色的问题
- 进入SVG文件删除fill属性
- 使用svgo-loader,但是最近的版本不太好用
6. 选中项
简而言之,根据情况变化出现或消失的内容尽量使用伪类实现,防止高度抖动
&.selected::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 4px;
background-color: #333;
}
6. 父组件传递类
父组件
<div class="content" :class=" classPrefix &&`${classPrefix}-content`">
子组件
<template>
<div class="layout-wrapper">
<div class="content" :class=" classPrefix &&`${classPrefix}-content`">
<slot></slot>
</div>
<Nav> </Nav>
</div>
</template>
<script lang="ts">
export default {
name: 'Layout',
props:["classPrefix"]
};
</script>
<style lang='scss' scoped>
.layout-wrapper{
display: flex;
flex-direction: column;
min-height: 100vh;
}
.content{
flex-grow: 1;
overflow: auto;
}
</style>
7.类的绑定
一个Vue标签可以同时动态和静态绑定
<div class="content" :class=" classPrefix &&`${classPrefix}-content`">
有冒号的是动态绑定,动态和静态可以各有一个
8.Props装饰器的应用
子组件
@Prop(String) classPrefix?: string; //前一个类型是静态编译时检查的类型,后一个是动态运行时验证的类型
父组件
<XXX :classPrefix=YYY>
注意冒号,一定是动态绑定,否则会变成字符串
9.注意对象的引用,以及深克隆
数据收集完之后,想实现以下功能:每次按ok,将数据放到LocalStorage。
在父组件Money.vue的NumberPad新加了一个监听@submit="saveRecord"
<template>
<layout class-prefix="layout">
<NumberPad @update:value="onUpdateAmount" @submit="saveRecord"/>
...
</layout>
</template>
<script lang="ts">
...
export default class Money extends Vue{
tags = ['餐饮','交通','购物','居家'];
recordList: Record[] = [];
record: Record = {tags: [], notes: '', type: '-', amount: 0};
...
// 新增函数
saveRecord(){
this.recordList.push(this.record)
}
@Watch('recordList')
onRecordListChange(){
window.localStorage.setItem('recordList',JSON.stringify((this.recordList)))
}
}
</script>
在子组件NumberPad.vue文件中的export default中的ok函数中添加代码
<script lang="ts">
...
export default class NumberPad extends Vue {
...
ok(){
this.$emit('update:value',this.output);
this.$emit('submit',this.output); //新增
}
}
</script>
这样用户每次点击ok,都会将数据上传至LocalStorae
但是这里出了一个错误,如下:
第一次输入1,点击ok,打印this.recordList,amount是数字1,正确。
但第二次输入2,点击ok,再打印this.recordList,amount得到两次结果都是2,出现bug。
Local Storage如下
原因是因为this.recordList.push(this.record)中this.record只是引用,所以第一次ok和第二次ok,都只是引用了record的地址,结果是两个2。
修改代码,record2是一个深拷贝,相当于保存了this.record的副本这样就可以实现预想的功能了。
saveRecord(){
const record2 = JSON.parse(JSON.stringify(this.record));
this.recordList.push(record2)
console.log(this.recordList);
}
10. 子组件不能直接修改父组件属性
通过onValuechanged对value进行变更,发送事件让父组件处理。
<template>
<div>
<label class="formItem">
<span class="name">{{ this.fieldName }}</span>
<input type="text"
:value = "value"
@input = "onValueChanged=($event.traget.value)"
:placeholder="placeholder">
</label>
</div>
</template>
<script lang="ts">
...
export default class FormItem extends Vue{
@Prop({default:''}) readonly value!:string;
...
onValueChanged(value:string){
this.$emit('update:value',value)
}
}
</script>