知识点:

keep-alive

是Vue提供的一个抽象组件,用来对组件进行缓存,从而节省性能用,由于是一个抽象组件,所以在v页面渲染完毕后不会被渲染成一个DOM元素。
当组件在keep-alive内被切换时组件的activated、deactiveed这两个生命周期钩子会被执行。
被包裹在keep-alive中的组件状态会被保留,例如我们将某个列表类内容滑动到第100条位置,那么我们在切换到一个组件后,再次切换回到该组件,该组件的状态依旧会保持在第100条列表处。

用法
<keep-alive>    <component>     <!--该组件将被缓存-->    </component></keep-alive>

props:
include-字符串或正则表达式,只有匹配的组件会被缓存
exclude-字符串或正则表达式,任何匹配的组件都不会被缓存
eg:

export default{    name:'a',    data(){      return {}    }}
<keep-alive include="a">    <component>        <!---name为a的组件将被缓存-->    </component></keep-alive>
<keep-alive exclude="a">    <component>        <!--除了name为a的组件都将被缓存-->    </component></keep-alive>

遇见vue-router:
router-view也是一个组件,如果直接被包在keep-alive里面,所有匹配到的视图组件都会被缓存:

<keep-alive>    <router-view>    <!--所有路径匹配到的视图组件都会被缓存-->    </router-view></keep-alive>

假如只想router-view里面某个组件被缓存,有两种办法,
1.使用include/exclude
2.增加router.meta属性
增加router-meta属性

//routes配置export default{    {        path:'/',        name:'home',        component:Home,        meta:{            //需要被缓存            keepAlive:true        }    },    {        path:'/:id',        name:'edit',        component:Edit,        meta:{           //不需要被缓存            keepAlive:false        }            }}
<keep-alive>    <router-view v-if="$router.meta.keepAlive">        <!--这里会被缓存的视图组件,比如Home-->    </router-view></keep-alive><router-view v-if="!$route.meta.keepAlive">    <!--这里是不被缓存的视图组件,比如Edit--></router-view>

扩展:
假设这里有3个路由:A,B,C
默认显示A
B跳到A,A不刷新
C跳到A,A刷新
实现方式:
在A路由里设置meta属性

{    path:'/',    name:'A',    component:A,    meta:{        //需要被缓存        keepAlive:true    }}

在B组件里面设置beforeRouteLeave:

export default{    data(){        return {};    },    methods:{},    beforeRouteLeave(to,from,next){        //设置下一个路由的meta        //让A缓存,即不刷新        to.meta.keepAlive=true;        next();    }}

在C组件里面设置beforeRouteLeave:

export default{    data(){        return {};    },    methods:{},    beforeRouteLeave(to,from,next){        //设置下一个路由的meta        //让A不缓存,即刷新        to.meta.keepAlive=false;        next();    }}

这样便能实现B回到A,A不刷新;而C回到A则刷新。~~~~

路由的过渡动画

想让路由有过渡动画,需要在<router-view>标签外部添加<transition>标签,标签还需要一个name属性

<transition name="fade">    <router-view></router-view></transition>

组件过渡过程中,会有四个CSS类名进行切换,这四个类名与transition的name属性有关,
比如name='fade',会有如下四个CSS类名:
1.fade-enter:进入过渡的开始状态,元素被插入时生效,只应用一帧后立刻删除
2.fade-enter-active:进入过渡的结束状态,元素被插入时就生效,在过渡过程完成后移除
3.fade-leave:离开过渡的开始状态,元素被删除时触发,只应用一帧后立刻删除
4.fade-leave-active:离开过渡的结束状态,元素被删除时生效,离开过渡完成后被删除
过渡模式mode:
in-out:新元素先进入过渡,完成之后当前元素过渡离开
out-in:当前元素先进入离开过渡,离开完成后新元素过渡进入

slot

slot是对组件的扩展,通过slot插槽向组件内部指定位置传递内容,
通过slot可以父子传参。
通俗理解就是“占坑”,在组件模板中占好了位置,当使用该组件标签时候,组件标签里面的内容就会自动填坑,当插槽也就是坑<slot name="mySlot">有命名时~~~~,组件标签中使用slot="mySlot"的元素就会替换该对应位置内容。

webpack开发环境process.env.NODE_ENV

在工作中,根据开发环境的不同,设置不同的变量、参数、和引入依赖,使打包更加的自动化。

获取当前城市

fetch.js:

import {  baseUrl} from './env'export default async (url = '', data = {}, type = 'GET', method = 'fetch') => {  type = type.toUpperCase();  url = baseUrl + url;  if (type == 'GET') {    let dataStr = ''; //数据拼接字符串    Object.keys(data).forEach(key => {      dataStr += key + '=' + data[key] + '&';    })    if (dataStr !== '') {      dataStr = dataStr.substr(0, dataStr.lastIndexOf('&'));      url = url + '?' + dataStr;    }  }  if (window.fetch && method == 'fetch') {    let requestConfig = {      credentials: 'include',      method: type,      headers: {        'Accept': 'application/json',        'Content-Type': 'application/json'      },      mode: "cors",      cache: "force-cache"    }    if (type == 'POST') {      Object.defineProperty(requestConfig, 'body', {        value: JSON.stringify(data)      })    }    try {      const response = await fetch(url, requestConfig);      const responseJson = await response.json();      return responseJson    } catch (error) {      throw new Error(error)    }  } else {    return new Promise((resolve, reject) => {      let requestObj;      if (window.XMLHttpRequest) {        requestObj = new XMLHttpRequest();      } else {        requestObj = new ActiveXObject;      }      let sendData = '';      if (type == 'POST') {        sendData = JSON.stringify(data);      }      requestObj.open(type, url, true);      requestObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");      requestObj.send(sendData);      requestObj.onreadystatechange = () => {        if (requestObj.readyState == 4) {          if (requestObj.status == 200) {            let obj = requestObj.response            if (typeof obj !== 'object') {              obj = JSON.parse(obj);            }            resolve(obj)          } else {            reject(requestObj)          }        }      }    })  }}

getData.js:

import fetch from '../config/fetch';import { getStore } from '../config/mUtils';/** 获取首页默认地址*/export const cityGuess = () => fetch('/v1/cities', {  type: 'guess'})

展示部分home.vue:


ps:baseUrl为elm.cangdu.org

String.fromCharCode

将Unicode编码转化为一个字符
var n=String.fromCharCode(65);

遇到的问题

1.sass-loader安装后报错
错误代码:
Module build failed: TypeError: this.getResolve is not a function at Object.loader
问题解决:


执行安装之后的sass版本太高,webpack编译时出现了错误,这个时候只需要换成低版本就行,找到package.json文件,里面的"sass-loader"的版本更换掉就行了。
"sass-loader": "^8.0.0",更换成了 "sass-loader": "^7.3.1"
重启项目就行了。

2.将获取的数据按照A-Z字母开头排序

通过JS的fromCharCode()方法类实现:

computed:{    //将获取的数据按照A-Z字母开头排序    sortgroupcity(){     let sortobj={};     for(let i=65;i<=90;i++){        //this.groupcity为正常请求返回来的数据        if(this.groupcity[String.fromChartCode(i)]){            sortobj[String.fromCharCode(i)]=            this.groupcity[String.fromCharCode(i)];        }     }     return sortobj;        }}

fromCharCode()可接受一个指定的Unicode值,然后返回一个字符串。
处理后的groupcity是一个新对象,key值为城市首字母,这样在遍历groupcity的时候,key即时首字母。

<ul class="letter_classify">   <li v-for="(value,key,index) in sortgroupcity" :key="key">      <h4 class="city_title">        {{key}} //此处即为首字母        <span v-if="index==0">(按字母排序)</span>      </h4>      <ul>        <router-link tag="li" v-for="item in value"        :to="'/city/'+item.id" :key="item.id">            {{item.name}}        </router-link>      </ul>   </li></ul>

Demo学习链接:vue-eleDemo参考