知识点:
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 参考