1. 项目搭建过程要用到

      ①Node.js 10版本, node —version如果不是10的话,要卸载去Node.js官网重新下载。注意重装Node.js后,以前用的npm 或 yarn命令可能会消失不见,如果需要的话,可重新安装这些命令。为加快下载速度,建议用镜像淘宝源(运行如下代码)
      npm install -g nrm —registry=https://registry.npm.taobao.org
      nrm use taobao
      ②要安装vue/cli@4.1.2 ``` vue —version # 如果这个命令打印出一个版本号,而版本号又不是 4.1.2 就说明你需要卸载 yarn global remove @vue/cli //然后就可以安装了,命令如下 yarn global add @vue/cli@4.1.2 vue —version # 版本号应该是 4.1.2 安装成功后,可以初始化一个项目

    1. ③初始化一个项目<br />在项目文件夹目录下运行如下代码

    vue create xxx(项目的名字) 需要选择很多的配置,请仔细选 cd xxx yarn serve

    1. 开启服务器看到如下界面的话,就表示基础搭建成功啦,一般Vue会替我们开一个8080端口。<br />![Screen Shot 2020-07-15 at 3.51.15 PM.png](https://cdn.nlark.com/yuque/0/2020/png/912821/1594799481596-869b66d8-e451-44a9-8a9d-5432739ed29d.png#align=left&display=inline&height=793&margin=%5Bobject%20Object%5D&name=Screen%20Shot%202020-07-15%20at%203.51.15%20PM.png&originHeight=793&originWidth=831&size=86465&status=done&style=none&width=831)
    2. 2. 使用webstorm开发,快捷高效,在创建vue文件时,自定义它初始化的内容
    3. ![Screen Shot 2020-07-15 at 3.58.36 PM.png](https://cdn.nlark.com/yuque/0/2020/png/912821/1594799978066-0b0d9587-122d-42b2-afda-0d2c8a839ab3.png#align=left&display=inline&height=287&margin=%5Bobject%20Object%5D&name=Screen%20Shot%202020-07-15%20at%203.58.36%20PM.png&originHeight=287&originWidth=431&size=69685&status=done&style=none&width=431)![Screen Shot 2020-07-15 at 3.59.09 PM.png](https://cdn.nlark.com/yuque/0/2020/png/912821/1594799982201-fedc6953-889b-4978-a97e-8407d295315d.png#align=left&display=inline&height=335&margin=%5Bobject%20Object%5D&name=Screen%20Shot%202020-07-15%20at%203.59.09%20PM.png&originHeight=335&originWidth=277&size=27602&status=done&style=none&width=277)<br />那如果我们自定义它初始化的内容怎么操作呢(如图)?需要在settings里设置。<br />![Screen Shot 2020-07-15 at 4.17.13 PM.png](https://cdn.nlark.com/yuque/0/2020/png/912821/1594801042171-4841a000-7606-4658-a9e1-fef8aaf0eca4.png#align=left&display=inline&height=284&margin=%5Bobject%20Object%5D&name=Screen%20Shot%202020-07-15%20at%204.17.13%20PM.png&originHeight=284&originWidth=243&size=27592&status=done&style=none&width=243)<br />![Screen Shot 2020-07-15 at 4.04.40 PM.png](https://cdn.nlark.com/yuque/0/2020/png/912821/1594800282757-942e6c27-9dc6-4e6a-9279-966cd62badf3.png#align=left&display=inline&height=542&margin=%5Bobject%20Object%5D&name=Screen%20Shot%202020-07-15%20at%204.04.40%20PM.png&originHeight=722&originWidth=952&size=146379&status=done&style=none&width=714)<br />在上图模板中修改。
    4. 3. js ,ts里面,引用路径要怎样写才方便?
    5. 直接写 `import x from '@/xxx/xxx'` ,这里的@就代表src目录。
    6. 4. css里面使用@来代替src的方式?
    7. ![Screen Shot 2020-07-15 at 4.30.47 PM.png](https://cdn.nlark.com/yuque/0/2020/png/912821/1594801853662-a054082b-5b86-45d5-ba90-8a8dc80384de.png#align=left&display=inline&height=220&margin=%5Bobject%20Object%5D&name=Screen%20Shot%202020-07-15%20at%204.30.47%20PM.png&originHeight=220&originWidth=558&size=31847&status=done&style=none&width=558)<br />如果此时我们想在app里引用这个颜色,怎么写呢?<br />![Screen Shot 2020-07-15 at 4.34.43 PM.png](https://cdn.nlark.com/yuque/0/2020/png/912821/1594802088094-0f0bad92-52b5-4df7-8ff4-cb4714b51464.png#align=left&display=inline&height=104&margin=%5Bobject%20Object%5D&name=Screen%20Shot%202020-07-15%20at%204.34.43%20PM.png&originHeight=104&originWidth=423&size=36251&status=done&style=none&width=423)<br />这里的~@就代表src了,但webstorm并不认识(因为如图有画红波浪线),我们需要设置一下<br />![Screen Shot 2020-07-15 at 4.38.06 PM.png](https://cdn.nlark.com/yuque/0/2020/png/912821/1594802389606-d575cf77-cc35-4c34-82d7-61e23dddbaf4.png#align=left&display=inline&height=306&margin=%5Bobject%20Object%5D&name=Screen%20Shot%202020-07-15%20at%204.38.06%20PM.png&originHeight=306&originWidth=881&size=37587&status=done&style=none&width=881)<br />点击右边文件夹,找到如下图的项目里的webpack配置文件,点确定即可。<br />![Screen Shot 2020-07-15 at 4.39.11 PM.png](https://cdn.nlark.com/yuque/0/2020/png/912821/1594802393186-49cb8464-0f12-4411-9b06-b307afbd718e.png#align=left&display=inline&height=332&margin=%5Bobject%20Object%5D&name=Screen%20Shot%202020-07-15%20at%204.39.11%20PM.png&originHeight=332&originWidth=753&size=108198&status=done&style=none&width=753)<br />![Screen Shot 2020-07-15 at 4.41.12 PM.png](https://cdn.nlark.com/yuque/0/2020/png/912821/1594802476239-af9da493-8197-4adf-96e4-b764e2fcf3a6.png#align=left&display=inline&height=98&margin=%5Bobject%20Object%5D&name=Screen%20Shot%202020-07-15%20at%204.41.12%20PM.png&originHeight=98&originWidth=410&size=33373&status=done&style=none&width=410)之前的红色报错消失了。
    8. 5. `git reset --hard HEAD` 这句话会把当前所有的变动都删掉,无法返回。
    9. 5. router文件夹中设置对应路由
    10. ![Screen Shot 2020-07-19 at 5.18.21 PM.png](https://cdn.nlark.com/yuque/0/2020/png/912821/1595150313923-af960625-619a-473f-8da6-cfecaa812d1d.png#align=left&display=inline&height=560&margin=%5Bobject%20Object%5D&name=Screen%20Shot%202020-07-19%20at%205.18.21%20PM.png&originHeight=560&originWidth=723&size=109164&status=done&style=none&width=723)
    11. 7. 导航栏小问题
    12. 在一开始的时候,直接把导航栏放在了App.vue里面,后面发现实际上有一些页面并不需要导航栏,比如404页面,所以想到放在全局的App.vue里面并不妥,干脆写成一个组件,就哪个页面想用导航栏的就调用导航栏,后来又发现要引用的页面也挺多的,如果每个页面的script里都引用,会显得很啰嗦重复,于是后来引用直接放到了main.js里面,全局引入,这样一个页面想用Nav导航栏,直接用就可以,非常方便。
    13. 8. 经验之谈,千万不要在手机上使用fixed定位。尽量用flex布局。
    14. 8. scoped的用法意义。
    15. 如果不想命名冲突,可以再组件里style标签上加上scoped属性,其表明(如下图),这个navstyle只在这个组件范围内管用。实际上, 这个scoped其实是Vue替我们做了两件事情,第一,会在class上自动加一个随机数,data-set-x1,就是在template中的第一行变为 `<div class="nav data-set-x1" ` 第二件事情,它会在CSS上面加上这个属性选择器,也即 `.nav[data-set-x1]{border:1px solid red}` ,这的确是一个聪明简单的做法。所以只要加上scoped,这个nav只会影响当前template里的nav。<br /> ![Screen Shot 2020-07-19 at 8.56.04 PM.png](https://cdn.nlark.com/yuque/0/2020/png/912821/1595163371677-93d6b879-3c06-4700-a94d-34ed12b89715.png#align=left&display=inline&height=447&margin=%5Bobject%20Object%5D&name=Screen%20Shot%202020-07-19%20at%208.56.04%20PM.png&originHeight=447&originWidth=346&size=128320&status=done&style=none&width=346)<br />所以只要能加scoped的时候都加上。
    16. 10. 当引入svg时,需要在.d.ts结尾文杰中写入如下代码,方可引用svg图片成功。
    17. ![Screen Shot 2020-07-19 at 10.47.56 PM.png](https://cdn.nlark.com/yuque/0/2020/png/912821/1595170149572-b7bb89da-92ca-4ba8-88a2-e234949fb2a3.png#align=left&display=inline&height=211&margin=%5Bobject%20Object%5D&name=Screen%20Shot%202020-07-19%20at%2010.47.56%20PM.png&originHeight=211&originWidth=595&size=93945&status=done&style=none&width=595)
    18. 11. 想使用svg-sprite-loader得需要改webpack配置文件,但我们只有Vue.config,js文件,所以需要我们把webpack修改的内容,翻译一下写到Vue.config.js里,过程有些复杂,需写入如下代码。
    19. ```javascript
    20. const path = require('path')
    21. module.exports = {
    22. lintOnSave: false,
    23. chainWebpack:config=>{
    24. const dir = path.resolve(__dirname,'src/assets/icons')
    25. config.module
    26. .rule('svg-sprite')
    27. .test(/\.svg$/)
    28. .include.add(dir).end()//包含icons目录
    29. .use('svg-sprite-loader').loader('svg-sprite-loader'),options({extract:false}).end()
    30. config.plugin('svg-sprite').use(require('svg-sprite-loader/plugin'),[{plainSprite:true}])
    31. config.module.rule('svg').exclude.add(dir)//其他svg loader 排除 icons 目录
    32. }
    33. }

    svg-sprite-loader会把先在body里生成一个svg标签,然后再把图片都变成symbol标签,从而显示到页面上,而我们使用图片的时候也很方便,只要用<svg> <use xlink:href="#index"/></svg> 就可以使用。
    Screen Shot 2020-07-19 at 11.36.22 PM.png

    1. 那如果每次引用一个图片就要在script里写一次import x from “@/xxx”,那如果有100个图片怎么办?有没有什么办法可以一次性引入一个icons文件夹呢?有的,如下

      1. let importAll = (requireContext:__WebpackModuleApi.RequireContext)=> requireContext.keys().forEach(requireContext);
      2. try {
      3. importAll(require.context('../assets/icons', true, /\.svg$/));
      4. }catch (error) {
      5. console.log(error);
      6. }
    2. 那可是使用svg标签放入图片时候也会非常重复,如下

    Screen Shot 2020-07-20 at 2.31.07 PM.png
    这时我们就又要考虑封装了,把重复的部分都写道Icon的组件里,再在main.js全局引入Icon组件,当需要引用图片是就用Icon标签就可以,如下图,
    Screen Shot 2020-07-20 at 2.49.18 PM.png

    1. 遇到的较难的问题

    ——svgo删除fill
    在做导航栏点击后,图标变色的时候,我遇到了一个bug,有一些icon本身带有颜色,导致无法使用SCSS给它再上颜色,于是我就打开了这个svg图标的源代码看了一下,发现它其实就里面有fill这个属性,只要把fill删掉,本身颜色就会消失。但是又有一个问题,如果每个图标都要手动去找fill属性再删除,那会是非常麻烦的一件事,于是我又上google搜索了相关的信息,发现有一个叫svgo-loader的加载器,它可以对svg形式的文件进行操作,我就去阅读了它的源文档,因为猜想它应该可以有和颜色相关的功能,果然找到了一个叫removeAttrs的属性,它可以删除fill,于是我就是下载了这个svgo-loader,并且在Vue.config.js中配置了svgo-loader的一些功能。最后成功地解决了这个问题,只要浏览器在加载svg文件时,他们本身的颜色都会被去掉,从而可以让我们自己通过css去操作它的颜色。

    1. CSS有用小知识

    ——@extend %x用法
    在helper.scss里写上 如下代码,即可在别的想用的地方去占位。

    1. //helper.scss
    2. %x{
    3. &::after {
    4. content:'';
    5. clear:both;
    6. display:block;
    7. }
    8. }
    9. //在style中可以这样写来引用
    10. . output{
    11. @extend %x;
    12. font-size:36px;
    13. ....
    14. }
    15. .buttons{
    16. @extend %x;
    17. > button {
    18. ....
    19. }
    20. }
    21. //这样写的意思就是x的位置被.output 和.buttons占位。即意味着
    22. .buttons::after, .output::after{
    23. content:"";
    24. clear:both;
    25. display:block;
    26. }
    27. //就不需要每个地方都再写一样的三行代码
    1. TS组件 @Prop 装饰器

    Screen Shot 2020-07-31 at 11.02.21 AM.png
    图中引入的vue-property-decorator是另一个叫kaorun343的github用户上传的库,比原始的vue要好用一些,在用typescript时,需要引入prop的过程中,我们需要提前表明传入参数属性。如图所示 @Prop(Number) xxx: number | undefined ,这句代码前后两个地方的Number表明的目的不一样,前面是告诉Vue xxx是个number,后面的number|undefined是告诉Typescript这是number | undefined。
    那有什么意义呢?为什么要这样声明两次呢?
    这就要牵扯到TS的不同之处了,它其实有一个预编译的compiler。与JS是如下图这样合作的:
    2020-2-5-20-47-35.png
    由于有预编译的能力,ts会在一开始你还没运行代码就能告诉你哪里写错了,它会强调让你写类型,其实如果你不管TS的报错,继续运行,也能正常运行。Typescript的好处有如下

    1. 类型提示:更智能的提示
    2. 编译时报错:还没运行代码就知道自己写错了
    3. 类型检查:无法点出错误的属性

    4. 一个很方便的class=”selected”判断写法

      1. <li v-for="tag in dataSouce" :key="tag"
      2. :class="{selected: selectedTags.indexOf(tag)>=0}"
      3. //用这种对象的方式写,简洁一些,后面是true的话就展现,是false的话就不展现。
      4. @click="toggle(tag)"
      5. >{{tag}}</li>
    5. v-model

    可以用 v-model 指令在表单 <input><textarea><select> 元素上创建双向数据绑定。v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:

    • text 和 textarea 元素使用 value property 和 input 事件;
    • checkbox 和 radio 使用 checked property 和 change 事件;
    • select 字段将 value 作为 prop 并将 change 作为事件。
      1. <input type="text"
      2. :value="x" @input="x=$event.target.value"//这里可以直接写成v-model="x"
      3. placehoder="在这里输入备注">
      4. export default class Notes extends Vue{
      5. value='';
      6. }
    1. mvc模型思想很重要

    当编写好Money页面的主要逻辑后,就需要用MVC的视角来审视它,需要把跟Model相关的数据提炼出来,避免单独在页面中一次又一次的重复写调用代码。新建model.js文件,写入如下
    Screen Shot 2020-08-02 at 8.17.45 AM.png
    当ts文件需要引入js文件的时候怎么办呢?
    一般的引入方法是不会成功的,我们需要用reqire,如图
    Screen Shot 2020-08-02 at 8.20.34 AM.png
    并且我们需要在后面加上.default,如果我们在上面图片最后一行导出时,是 export {model} 这样写的话,我们就不需要在引入时候加上.default,而是加上.model。Screen Shot 2020-08-02 at 8.23.00 AM.png

    1. 但是我们Money页面用ts写的,为何model文件不能用ts写呢,所以我们改写成model.ts,这就涉及到需要变量声明,有一些变量需要编程全局的变量,如图片中的type Record,我们需全局声明它,但Record是一个默认就有的类型,我们自己定义的类型不能相同,需要换个名字。

    其次,我们需创建一个custom.d.ts,d就是declaration,只要typescript发现是.d.ts结尾的就知道你是声明。把type Record内容复制过去就可以。
    21..native用法
    在抽离一个Button组件时,别处引用这个Button组件时,若想绑定一个监听一个行为,通常我们会这样写:

    1. //Button.vue
    2. <button class="button"
    3. @click="$emit('click', $event)"
    4. >
    5. <slot/>
    6. </button>
    7. //Labels.vue
    8. <Button class="createTag" @click="createTag">新建标签</Button>
    9. //但若需要绑定的行为很多呢?不止点击,怎么办?
    10. //可以这样写
    11. //Labels.vue
    12. <Button class="createTag" @click.native="createTag">新建标签</Button>
    1. Vuex ——全局数据管理 ```javascript //初始化store/index.ts import import Vue from ‘vue’ import Vuex from ‘vuex’

    Vue.use(Vuex)//别忘引入

    const store = new Vuex.Store({ state:{ count:0, tagList:[], }, mutations:{ addCount(state){state.count += 1} //mutations里面的函数没有返回值!! }

    })

    1. 组件使用时,
    2. ```javascript
    3. //读:对象
    4. computed: {
    5. tagList(){
    6. return this.$store.fetchTag()
    7. }
    8. }
    9. //读:类
    10. export default class Tags extends mixins(TagHelper){
    11. get tagList(){
    12. return this.$store.state.tagList;
    13. }
    14. //更推荐使用下面这种方法

    更推荐使用get 方法,因为当类里面需要引用组件里的computed的属性时,是无法使用读取的

    1. Vue的/deep/用法 ```javascript //当statistics页面要用到某一个type组件时,
    //这么写页面是不会有反应的,因为是scoped,但如果去掉了scoped又会影响别的地方 //此时我们需要使用如下

    //于是我们需查文档发现还有一种写法,非常高兼容性

    //成功

    ```