123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- class Utils {
- getHashRoute() {
- let hashDetail = window.location.hash.split('?');
- let hashName = hashDetail[0].split('#')[1];
- let params = hashDetail[1] ? hashDetail[1].split('&') : [];
- let query = {};
- params.map((item) => {
- let temp = item.split('=');
- query[temp[0]] = temp[1];
- });
- return {
- path: hashName,
- query: query
- };
- }
- getHistoryRoute() {
- let path = (window.history.state && window.history.state.path) || '';
- let queryStr = window.location.hash.split('?')[1];
- let params = queryStr ? queryStr.split('&') : [];
- let query = {};
- params.map((item) => {
- let temp = item.split('=');
- query[temp[0]] = temp[1];
- });
- return {
- path: path,
- query: query
- };
- }
- /**
- * 发送Get请求
- *
- * @param {!string} url 请求地址
- * @param {?function} next 回调函数
- */
- static ajaxGet(url, next) {
- let xhr = new XMLHttpRequest();
- if (url.includes('?')) {
- // 在URL有其他参数时,添加一个date参数加入当前时间以避免缓存
- xhr.open('GET', `${url}&date=${new Date().getTime()}`, true);
- } else {
- // 添加一个date参数加入当前时间以避免缓存
- xhr.open('GET', `${url}&date=${new Date().getTime()}`, true);
- }
- xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
- // 更改XMLHttpRequest对象withCredentials属性以支持跨域Cookies
- xhr.withCredentials = true;
- xhr.responseType = 'json';
- xhr.onload = function (res) {
- // 获取请求接口返回值
- let response = res.target.response;
- next && next(response);
- };
- xhr.send();
- }
- /**
- * 发送Post请求
- *
- * @param {!string} url 请求地址
- * @param {?string} data post请求参数
- * @param {?function} next 回调函数
- */
- static ajaxPost(url, data, next) {
- let xhr = new XMLHttpRequest();
- if (url.includes('?')) {
- // 在URL有其他参数时,添加一个date参数加入当前时间以避免缓存
- xhr.open("POST", `${url}&${new Date().getTime()}`, true);
- } else {
- // 添加一个date参数加入当前时间以避免缓存
- xhr.open("POST", `${url}?${new Date().getTime()}`, true);
- }
- xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
- // 更改XMLHttpRequest对象withCredentials属性以支持跨域Cookies
- xhr.withCredentials = true;
- xhr.responseType = 'json';
- xhr.onload = function (res) {
- // 获取请求接口返回值
- let response = res.target.response;
- next && next(response);
- };
- xhr.send(data);
- }
- /**
- * 事件监听处理类
- *
- * @param {string} eventName 表示监听事件类型的字符串
- * @param {object} [{ onElement, withCallback, useCapture = false }={}] 监听对象 回调函数 useCapture
- * @param {function} thisArg
- * @returns function
- */
- static handleEvent(eventName, {
- onElement,
- withCallback,
- useCapture = false
- } = {}, thisArg) {
- const element = onElement || document.documentElement
- function handler(event) {
- if (typeof withCallback === 'function') {
- withCallback.call(thisArg, event)
- }
- }
- handler.destroy = function () {
- return element.removeEventListener(eventName, handler, useCapture)
- }
- element.addEventListener(eventName, handler, useCapture)
- return handler
- }
- }
- /**
- * declare route: { path: '/xx', fileName: 'xxx', initFunc(){}}
- *
- *
- * @class SPARouter
- */
- class SPARouter {
- constructor(el, routers, mode) {
- this.el = el;
- this.mode = mode || 'hash';
- this.utils = new Utils();
- this.currentRoute = {};
- this.beforeFunc = null;
- this.afterFunc = null;
- this.initRouters(routers);
- this.init();
- }
- init() {
- window.SPA_RESOLVE_INIT = null;
- this.initEvent();
- }
- initRouters(routers) {
- this.routers = routers.map((item) => {
- item.$router = this;
- return item;
- });
- }
- initEvent() {
- window.addEventListener('load', () => {
- console.log('load')
- this.routeUpdate();
- });
- if (this.mode === 'history') {
- window.addEventListener('popstate', (e) => {
- console.log('popstate')
- this.routeUpdate();
- });
- // 禁用所有a 链接默认跳转事件
- let self = this;
- document.addEventListener('click', function (e) {
- let target = e.target || e.srcElement;
- if (target.tagName === 'A') {
- e.preventDefault();
- let href = target.getAttribute('href');
- let path = href.split('?')[0];
- window.history.pushState({
- path: path
- }, null, href);
- self.routeUpdate();
- }
- })
- } else {
- window.addEventListener('hashchange', () => {
- console.log('hashchange')
- this.routeUpdate();
- });
- }
- }
- loadComponent() {
- let self = this;
- if (typeof (self.currentRoute.fn) === 'function') {
- self.currentRoute.fn(self.el, self.currentRoute);
- } else {
- if (this.currentRoute.fileName) {
- let _body = document.getElementsByTagName('body')[0];
- let scriptEle = document.createElement('script');
- scriptEle.src = self.currentRoute.fileName;
- scriptEle.async = true;
- scriptEle.type = 'text/javascript';
- window.SPA_ROUTE_INIT = null;
- scriptEle.onload = () => {
- self.afterFunc && self.afterFunc(self.currentRoute);
- self.currentRoute.fn = window.SPA_RESOLVE_INIT;
- self.currentRoute.fn(self.el, self.currentRoute);
- }
- _body.appendChild(scriptEle);
- } else {
- if (self.currentRoute.initFunc) {
- self.currentRoute.initFunc(self.el, self.currentRoute);
- self.afterFunc && self.afterFunc(self.currentRoute);
- } else {
- console.trace('该路由定义出错,fileName 和 initFunc 必须定义一个')
- }
- }
- }
- }
- refresh(currentHash) {
- let self = this;
- if (self.beforeFunc) {
- self.beforeFunc({
- path: self.currentRoute.path,
- query: self.currentRoute.query
- }, () => {
- self.loadComponent();
- })
- } else {
- self.loadComponent();
- }
- }
- routeUpdate() {
- let getLocation = this.mode === 'history' ? this.utils.getHistoryRoute : this.utils.getHashRoute;
- let currentLocation = getLocation();
- this.currentRoute.query = currentLocation['query']
- this.routers.map((item) => {
- if (item.path === currentLocation.path) {
- this.currentRoute = item;
- this.refresh();
- }
- });
- if (!this.currentRoute.path) {
- if (this.mode === 'history') {
- window.history.pushState({
- path: '/index'
- }, null, '/index');
- this.routeUpdate();
- } else {
- location.hash = '/index';
- }
- }
- }
- beforeEach(callback) {
- if (Object.prototype.toString.call(callback) === '[object Function]') {
- this.beforeFunc = callback;
- } else {
- console.trace('路由切换前钩子函数不正确')
- }
- }
- afterEach(callback) {
- if (Object.prototype.toString.call(callback) === '[object Function]') {
- this.afterFunc = callback;
- } else {
- console.trace('路由切换后钩子函数不正确')
- }
- }
- }
|