vue路由守卫与菜单高亮
思路:
1、router.js中注册 路由,路由的(path&name),导出router实例
2、在beforeEach钩子中,使用vuex去双向绑定菜单索引(数据驱动)。
vue日志
import Vue from 'vue'
import Vuex from 'vuex'
import * as actions from './actions'
import * as getters from './getters'
import state from './state'
import mutations from './mutations'
import createLogger from 'vuex/dist/logger' // log出修改记录
Vue.use(Vuex)
const debug = process.env.NODE_ENV !== 'production'
export default new Vuex.Store({
actions,
getters,
state,
mutations,
strict: debug,
plugins: debug ? [createLogger()] : []
})
element树案例
案例结构:
案例代码:
<span>…</span> 可以替换成如下:
扁平化&树形数据
1、生成树形
var arr = [
{
id: 1,
pid: null,
title: '洋葱A'
},
{
id: 2,
pid: 1,
title: '洋葱AA'
},
{
id: 3,
pid: 2,
title: '洋葱AAA'
},
{
id: 4,
pid: 3,
title: '洋葱AAAA'
},
{
id: 5,
pid: 3,
title: '洋葱AAAA'
},
{
id: 6,
pid: 4,
title: '洋葱AAAAA'
},
{
id: 7,
pid: 4,
title: '洋葱AAAAA'
},
];
/**
* 树形递归算法的思路:
* 初想是传入数组,但是数组(并不能生成递归主体),它不具备递归遍历的条件。
* 故分析递归传参,因为...五六七...级树形,其实都需要重新遍历所有数组,
* 而生成树形的依据,是 传入id 和 遍历项的pid 的匹配,生成item.children,
* 故传入id最为合适。
*/
var _tree = (id) => {
// 针对某一个ID生成二级树形
let treeArr = arr.filter(item => item.pid === id);
// 针对二级树形,进行递归遍历(多级树形)
treeArr.forEach(item => item.children = _tree(item.id));
return treeArr;
};
// 对每个一级节点,生成树
var showAllTree = (arr) => {
arr.map((item) => {
item.children = _tree(item.id);
return item;
});
return arr;
}
console.log(JSON.stringify(showAllTree(arr)[0]));
2、扁平化
// 此处偷懒 将案例树形直接JSON.stringify拿来用
var obj = { "id": 1, "pid": null, "title": "洋葱A", "children": [{ "id": 2, "pid": 1, "title": "洋葱AA", "children": [{ "id": 3, "pid": 2, "title": "洋葱AAA", "children": [{ "id": 4, "pid": 3, "title": "洋葱AAAA", "children": [{ "id": 6, "pid": 4, "title": "洋葱AAAAA", "children": [] }, { "id": 7, "pid": 4, "title": "洋葱AAAAA", "children": [] }] }, { "id": 5, "pid": 3, "title": "洋葱AAAA", "children": [] }] }] }] };
/**
* 扁平化数组思路1: 传入对象
*/
var _flatten = (item) => {
return [item].concat(...item.children.map(subitem => _flatten(subitem)));
};
/**
* 扁平化数组思路2: 传入数组
*/
// var _flatten = (arr) => {
// return [].concat(...arr.map(item => [item].concat(_flatten(item.children))));
// };
/**
* 总结:
* 无论是传入对象还是数组,都是通过map方式,生成子集,子集再递归,并合并。
*/
console.log(_flatten(obj));
注:树形数据添加或删除,前端渲染直接插入数据,赋予pid即可。
赋值回顾:
1、Vue变异方法(可双向pusp,pop,也可单向slice)。
2、React新数组(单向驱动)。(即保证对象immutable)
react&原生监听路由变化
// react-router-dom 注入history
this.props.history.listen(route => {
console.log(route)
})
// 原生JS监听路由变化
window.addEventListener('hashchange', () => {
console.log('cow!!!!!!')
})
路由跳转滚动条置顶
Vue,路由守卫触发
router.afterEach(function () {
//置顶
})
React,路由listener触发
原生JS,hashchange触发
// 跳转方式一: API
window.scrollTo(0, 0);
// 跳转方式二:原生
document.documentElement.scrollTop = document.body.scrollTop = 0;
CSS定位知识
针对position: absolute
right,top,起始位置
与父元素的margin有关,与padding无关
构造器返回return
类中的constructor方法用于构造类的属性,但是当constructor中比如NodeList类中通过return返回一个对象(如Node类),那么会自动生成该对象类(Node类)的实例
// 创建链表的数据结构:
class Node {
constructor(value) {
this.val = value;
this.next = undefined;
}
}
class NodeList {
constructor(arr) {
let head = new Node(arr.shift()); // head 指向的是 Node类,是一个实例
let next = head;
arr.forEach(item => {
next.next = new Node(item);
next = next.next;
});
return head; // 投机取巧,返回一个Node类,和NodeList没关系
}
}
console.log(new NodeList(head));