nekobill(喵喵记账)项目历程

全局组件 Nav 导航栏 怎么设置比较人性化?

1.加在页面固定位置→后续想设置导航栏隐藏挨个页面隐藏就很麻烦→✖
2.单独开一个代码页面写一个导航栏→那个页面用就引用→每次引用都声明有点麻烦……?→做成全局变量一次性引用✔

路由配置:

路由会逐次的去配对,不在路由表里的统一归纳到 “*” 所以添加一条路由

 {
    path:'*',
    component:Notfound
 }

这个页面写404报错,然后设置返回主页面的方法
返回页面:

1.<router-link to="/">
2.<a href="#/">

效果一样,任意选择

<template>
<div>
  <div>404</div>
  <div>
    <router-link to="/"> 返回首页</router-link>
    </div>
</div>
</template>
</template>这个标签只能有一个主<div>,所以写一个主的把这两个包进去,不然会报错
CSS定位实现

fixed还是flex? fixed由于三改过,各个浏览器支持的版本不一,实现移动端开发是很难的。所以选用flex,方便后期维护

<style lang="scss" scoped>
.nav{border:1px solid red;}
</style>

scoped:会自动生成一串字符,添加到<template>中的<nav>中,这样 .nav只会影响到当前<template>中的nav
总结:能加scoped就加吧,这样不会让自己的div class 和其他的页面起冲突

flex-grow:1;
1:尽可能的高,类似于占比百分百
overflow: auto;
如果内容被修剪,会出现滚动条

vue插槽 <slot>:重复的东西写组件传递,不重复的东西slot插槽插进去
在vue引入svg:把 svg变成symbol,再把symbol外面套上一层svg 再引用

vue.config代码:

const path = require('path')
const { config } = require('process')
module.exports = {
  lintOnSave: false,
  chainWebpack: config => {
    const dir = path.resolve(__dirname, 'src/assets/icons')
    config.module
      .rule('svg-sprite')
      .test(/\.svg$/)
      .include.add(dir).end()//包含icons目录
      .use('svg-sprite-loader').loader('svg-sprite-loader').options({ extract: false }).end()
    config.plugin('svg-sprite').use(require('svg-sprite-loader/plugin'), [{ plainSprite: true }])
    config.module.rule('svg').exclude.add(dir)//其他SVG排除loader目录
    }
}
svgo o:优化的单词缩写
<label class="notes">
          <span class="name">备注</span>
          <input type="text" placeholder="在这里输入备注" />
        </label>

用labal把Input包起来就可以直接建立二者的关联,不用写那么多了

一个前端文件一般要少于150行,多了的话就拆分成模块吧。这样省内存

placeholder语法
%x{
     &::after{
         content: '';
         clear: both;
         display: block;
     }
 }

使用的时候

buttons{
@extend %x;}

相当于每次编译的时候,把buttons选择器每次复制过去,然后编译。所有选择器都会出现在x的位置

box-shadow inset:内阴影

  box-shadow: inset 0 -2px 5px -5px fade-out( #D47926, 0.5) ;
0:左右不变   -2px:阴影向上移动2px  5px:宽度为5px    -5px:阴影向内推进5px

TS的第一次使用

切换选择.png

有两个按钮,用JS控制切换,这里我把JS改成了TS

具体踩坑和Bug修复以及原理请看我的这一篇博客,这里不再赘述https://www.jianshu.com/p/ac010ace611a

TS是不会使用构造选项的,赋值语句会自动变成实例的属性,实例的属性会默认的变成data,所以直接写 type=' '

<script lang="ts">
import Vue from 'vue'
import {Component} from 'vue-property-decorator';

@Component
export default class Types extends Vue {
   type ='-'//'-'表示支出,'+'表示收入
   selectType(type:string) {
      ///type只能是‘-’或者“+”
      if (type !== "-" && type !== "+") {
        throw new Error("type is unknow");
      }
      this.type = type;
      }

}

先从vue-property-decoratoryin'ru'y引入一个叫做Component的装饰器,然后把装饰器修饰到class上,然后我的class可以声明data和methods。这里面的data就是type ='-'

想在ts里面加上prop属性,查了文档之后得到了如下简化后的代码

 @Prop(Number) xxx:number|undefined

我在另一个文件里引用了xxx

  <Types :xxx=345678 />

有报错,然后加上了判断语句报错消失

 mounted(){
        if(this.xxx === undefined){
          console.log('no xxx')
        }else{
          console.log(this.xxx.toString());
          
        }
      }
总结下怎么用TS声明Vue组件。

首先要引入Component和Prop,从vue-property-decorator这个库里面引用。然后要声明一个类Type,在这个类上面必须写@Component。如果要声明data,赋值语句会自动变成实例的属性,实例的属性会默认的变成data,所以直接写 .声明methods也直接写就好了,和js一样。声明Prop类型按照官方文档写@Prop(Number) xxx:number|undefined在Prop的后面( )里写一个运行时的类型,在后面写上编译时的类型

报错:可能没有内容
不一定所有元素都有内容,图就没有,这个BUG可以用强制指定类型 as

event.target as HTMLButtonElement 强制类型转换
如果在代码里写了

:value = "x"
@input="x=$event.target.value"

那么可以替换成

window.localStorage 怎么用

这是错误写法

recordList:Record[ ]= 
window.localStorage.getItem('localStorageKeyName') 

因为我不能将字符串赋值给一个数组,想要字符串变成数组,用json

recordList:Record[ ]=
JSON.parse(window.localStorage.getItem('localStorageKeyName'))

这么写,万一数组是空怎么办?null不是数组啊。所以再给他一个空的字符串

recordList:Record[ ]=
JSON.parse(window.localStorage.getItem('localStorageKeyName')||'[]')
数据迁移是什么
深拷贝:先把对象变成一个字符串,然后再把字符串变成对象,这样就拥有完全一样的所有属性,但是是一个新的对象

把js后缀改成ts,把所有报错都改掉。

iconfont 小技巧,编辑 SVG

创建标签成功要返回什么?
create(name:string) {
        this.data.push(name);
        this.save();
        if (this.data.indexOf(name) >= 0) {
            return  ?
        }
        return  ?
    }

如果返回的是 success 和 !success ,但是用户并不知道失败的原因是什么。
如果直接报错,报错时写出原因。那尝试下try和catch,然后打印出错误

if (name) {
        try{
          tagListmodel.create(name)
        }catch(error){
          console.log(error)
          }

报错提示:


控制台打印的报错

发现错误是duplicated,如果改成当错误信息是duplicated就弹出一个alert提示用户是标签名重复呐?于是代码改成

if (name) {
        try{
          tagListmodel.create(name)
        }catch(error){
          if(error.message==='duplicated'){
            window.alert('标签名重复')
          }
create:(name:string) => number
    create(name:string) {
        this.data.push(name);
        this.save();
        if (this.data.indexOf(name) >= 0) {
            return ture;
        }
        return false;
    }

可行,但是不够好,返回值是true或者false不知道返回的具体错误是什么,那如果把返回值改成数字呐?每个数字代表不同的错误,那试一下成功返回0,失败返回1

create:(name:string) => number
    create(name:string) {
        this.data.push(name);
        this.save();
        if (this.data.indexOf(name) >= 0) {
            return 1;
        }
        return 0;
    }

确实可以,可是时间长了,0,1分别代表的意义会被遗忘,那尝试返回字符串吧

create:(name:string) => string
    create(name:string) {
        this.data.push(name);
        this.save();
        if (this.data.indexOf(name) >= 0) {
            return 'duplicated';
        }
        return 'success';
    }

如果是多人团队合作,其他的合作者不知道我的返回值只有success和duplicated两种,我有什么办法让他知道呢?
改前面的声明,声明类型的时候直接写返回值

    create:(name:string) => 'success'|'duplicated'//联合类型

联合类型:是字符串的子类型,不属于7个数据类型,类似于枚举法

 path:'/labels/edit/:id',

:id 表示是我后面会有一个字符串,但是我现在不知道是多少,拿来站位



一般来说,和路由相关用route,和路由器相关用router

custom.d.ts 怎么用

让一个变量在所有文件都可以用它。d的定义的意思, ts发现文件以** .d.ts** 结尾,就知道这个文件是声明,声明变量的。
把希望在全局使用的变量声明写在里面
@click.native 怎么用?
我知道你这个组件没有click属性,但是你对应的组件有这个click属性,所以对应的组件是可以接受这个click的
Vue Router 怎么用
this.$route this为什么有 $route 这个属性,因为安装了一个叫做Vue router 的库,里面的声明是这样的:

declare module 'vue/types/vue' {
  interface Vue {
    $router: VueRouter
    $route: Route
  }
}

用来收集路径的信息

数据不同步问题:两个页面分别写了fetch()获取到用户更改的对象,但是页面之间内无法交换数据
解决:在更高一级上面写fetch() 例如main页面 例如app页面。

全局数据管理/全局状态管理是啥

全局状态管理(也叫全局数据管理)的好处是什么?

解耦:将所有数据相关的逻辑放入 store(也就是 MVC 中的 Model,换了个名字而已)
数据读写更方便:任何组件不管在哪里,都可以直接读写数据
控制力更强:组件对数据的读写只能使用 store 提供的 API 进行(当然也不排除有猪队友直接对 tagList 和 recordList 进行 push 等操作,这是没有办法禁止的)

store和model都是仓库,模板,把model写到store里一起调用吧

this根据函数确定的。函数!在export default 里面返回的是一个key 不是函数,所以调用不了
在定义一个对象的过程中,没有办法使用对象,因为还没定义完

store 怎么模块化

在 store 里const 一个对象 ,然后把model里的模块,写到新对象里,然后exprot default 对象 把他暴露出去

如何封装

把tags,record里的recordListmodel封装成全局变量。也就是window.xxxx()
全局变量太多
过于依赖window(node.js里没有window这个对象)
变量太多解决方法:把所有的东西挂到stroe身上。在custom.d.ts 里声明一个window里的变量,叫store 把刚刚声明的全局变量都写到里面,这样变量依赖的就是store了
依赖window解决:不要window。新建一个index2.ts。把store写在里面成为一个单独的对象,不依赖window

createTag 创建一个tag 看有没有重复 重复了alert "标签重复" return duplicated
如果没有重复 运行创建过程 return success

    this.recordList&&this.recordList.push(record2);///可调换成this.record?.push(record2)

? 写法。(可选链)最新版本的vs code 和TS版本>3.7.5

@Prop({required:true}) dataSource!: string[];

require:true 必须传一个数组,不传就会报错

Vuex重构EditLable页面 里面有获取tag这个操作嘛,之前写的store是直接调用 store.findtag(this.$route,param.id) 因为改写成vuex,mutation读写数据,只能调用,不能return 于是改写 this.tag=this.$store.commit('findtag',this.route.param.id) 结果标红了 不能把viod赋值给tag 于是去查了commit的返回值 index.d.ts

发现 store.commit 没有返回值,还真是void,那就说明没办法通过commit获取到数据啊,那在store上面 填一个currentTag ,要声明类型,不好声明我给了个undefined 感觉写了没啥意义 然后写了个type 里面的currentTag?:Tag 可以是Tag可以是Undefined 没有报错 那我就想办法得到currentTag 在computed里写tag()
{ return this.$store.state.currentTag} 取到了值 取到值之后还得让他改嘛 要让他赋值 肯定是要调用一个commit 然后我又写了一个 setcurrentTag 当调用这个函数的时候,值会修改。



给我一个id我就会让currentTag=tag,然后出现 新的报错。tag不存在????

我看了下之前写的代码,发现computed里面写过的变量,没有在export default class 里用过。试了下其他的变量也都是标红的,是不是TS和VUE不可以这么结合使用?我去翻了Vue-property-decorator文档,结果,没有相关答案!然后我又去翻了原生文档 Vue class comnonent,发现人家用了原生自带的get和set函数



这么一看确实简洁多了,我不用compouted了,直接get tag(){ return this,$store.state.currentTag} 成功了,然后发现,之前所有的computed都是错的。大改吧

mutations:里面用的函数只能有一个变量,有2个就会报错,若果有两个的话,写到object里 再调用

  updateTag(state, object:{ id: string, name: string }) {
       const id =object.id
       const  name=object.name}

为了迎合Vuex的喜好,我还是把object改成payload吧

deep语法

引入组件之后在CSS里写上 scoped 可以防止其他的组件被污染 如果想设置引入组件的属性,因为有了scoped的保护,无法更改内容,解决办法 deep语法

<style scoped lang="scss">
 .x /deep/ li{    /////.x 深入到里面的组件 li  不看外面的组件,只看里面的 
 border:1px solid red.
}
</style>

如果出现了sass 报错,那可能是sass之类的预处理器无法正确解析
可以改成 ::v-deep 取代

ES6 如果你的key里面有变量,可以用中括号 [ ] 把他们包起来
:value.sync=“ ”里的值必须是变量

object.freeze 可以保证里面的变量不可修改


效果图

想做成这样的,2个都用了Tab组件,高度做变更,CSS优先级靠前的会被使用,有两个办法 一个是把第二个的CSS写的更精细 li..interval-tabs-item 这种,缺点就是没办法保证里面的是li标签 还有可能是div
另一个是 在CSS里 改成同级的

.tabs{
&-item{
}}

在li标签上写 class="tabs-item"
两种都有可以 第2种更好一点?
方法3:用JS
在Tabs组件里 声明prop (String,'64px') height!:string 然后在用属性或者CSS写另一个高度

json支持的类型 object array string number "ture" "false" "null" 没有Date

[ ]+String=[{ , }, { , },{ , }]
用计算属性
在TS里 this.$store.state.xxx

数据需要排序!不排序不能保证后插入的数据可以按照正确的顺序显示,所以数据一定是一个有序数组!
sort()会改变数组本身
foreach是没有返回值的map,

$emit的Bug ,$emit无法指定第二个参数的类型


emit的数组返回值类型是any

组件{构造选项+装饰器}
mixin 节约多次代码的重复书写,写一次,继承下就可以了
conputed 获取数据,可以自动根据依赖缓存,节省技术按次数
TS里面需要写getter语法
Watch ,prop ,sync,v-model装饰器写法
《slot》插槽 具名
eslint
localStorage 只可以存5到10M
表驱动编程 :class{key: value:}
模块化思想 store

重构技巧 多写几遍

Vue Router Hash/history模式 是SPA模式,单一页面应用
Vuex window.store

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容