Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

把需要多个组件共享的变量全部存储在一个对象里面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const store = new Vuex.Store({
state: {
count: 0
}, //全局变量
mutations: {
increment (state,counter) {
state.count++;
state.count= counter;
}
}, //用于修改state里的数据的方法
actions: {}, //用于异步操作
getters: {}, //相当于computed计算属性
modules: {}
})

//vue组件内访问
this.$store.state.count
this.$store.commit('increment',counter)
  1. Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
  2. 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

https://vuex.vuejs.org/zh/


Promise

ECMAscript 6 原生提供了 Promise 对象,Promise 对象代表了未来将要发生的事件,用来传递异步操作的消息。

⑴Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。

⑵所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。

⑶从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。

⑷Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

Promise 优缺点

有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise 对象提供统一的接口,使得控制异步操作更加容易。

Promise 也有一些缺点。首先,无法取消 Promise,一旦新建它就会立即执行,无法中途取消。其次,如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。第三,当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

ES6 规定,Promise对象是一个构造函数,用来生成Promise实例。Promise是一个构造函数,自己身上有all、reject、resolve这几个眼熟的方法,原型上有then、catch等方法

1
2
3
4
5
6
7
8
9
const promise = new Promise(function(resolve, reject) {
// ... some code

if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});

Promise 新建后就会立即执行

Promise对象代表一个异步操作,它有三种状态:

①pending:进行中

②fulfilled :已经成功

③rejected:已经失败

只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。

Promise对象实现的 Ajax 操作的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function ajax(URL) {
return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function () {
if (req.status === 200) {
resolve(req.responseText);
} else {
reject(new Error(req.statusText));
}
};
req.onerror = function () {
reject(new Error(req.statusText));
};
req.send();
});
}
var URL = "/try/ajax/testpromise.php";
ajax(URL).then(function onFulfilled(value){
document.write('内容是:' + value);
}).catch(function onRejected(error){
document.write('错误:' + error);
});

Promise.all方法

Promise.all 方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

1
var p = Promise.all([p1,p2,p3]);

Promise.all 方法接受一个数组作为参数,p1、p2、p3 都是 Promise 对象的实例。(Promise.all 方法的参数不一定是数组,但是必须具有 iterator 接口,且返回的每个成员都是 Promise 实例。)

  • (1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
  • (2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

Promise.race方法

Promise.race 方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的Promise实例的返回值,就传递给p的返回值。

参考:

https://www.cnblogs.com/shihaiying/p/12130875.html

https://www.runoob.com/w3cnote/javascript-promise-object.html


axios

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

特性

  • 从浏览器中创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF

http://www.axios-js.com/zh-cn/docs/


vue导航守卫

全局守卫

  • 全局前置守卫 router.beforeEach
1
2
3
4
5
6
const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
// ...
next()
})
  • 全局解析守卫 router.beforeResolve

router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用

  • 全局后置钩子 router.afterEach
1
2
3
router.afterEach((to, from) => {
// ...
})

然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身

路由独享的守卫

  • 路由独享的守卫 beforeEnter
1
2
3
4
5
6
7
8
9
10
11
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})

组件内的守卫

  • beforeRouteEnter
  • beforeRouteUpdate
  • beforeRouteLeave
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const Foo = {
template: `...`,
beforeRouteEnter(to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate(to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave(to, from, next) {
// 导航离开该组件的对应路由时调用,离开守卫通常用来禁止用户在还未保存修改前突然离开
// 可以访问组件实例 `this`
}
}

https://router.vuejs.org/zh/guide/advanced/navigation-guards.html


防抖和节流

函数防抖(debounce):触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。

函数节流(throttle):高频事件触发,但在n秒内只会执行一次,节流会稀释函数的执行频率。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//防抖debounce代码:
function debounce(fn,delay) {
var timeout = null; // 创建一个标记用来存放定时器的返回值
return function (e) {
// 每当用户输入的时候把前一个 setTimeout clear 掉
clearTimeout(timeout);
// 然后又创建一个新的 setTimeout, 这样就能保证interval 间隔内如果时间持续触发,就不会执行 fn 函数
timeout = setTimeout(() => {
fn.apply(this, arguments);
}, delay);
};
}
// 处理函数
function handle() {
console.log('防抖:', Math.random());
}

//滚动事件
window.addEventListener('scroll', debounce(handle,500));

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//节流throttle代码:
function throttle(fn,delay) {
let canRun = true; // 通过闭包保存一个标记
return function () {
// 在函数开头判断标记是否为true,不为true则return
if (!canRun) return;
// 立即设置为false
canRun = false;
// 将外部传入的函数的执行放在setTimeout中
setTimeout(() => {
// 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。
// 当定时器没有执行的时候标记永远是false,在开头被return掉
fn.apply(this, arguments);
canRun = true;
}, delay);
};
}

function sayHi(e) {
console.log('节流:', e.target.innerWidth, e.target.innerHeight);
}
window.addEventListener('resize', throttle(sayHi,500));

生命周期

从vue实例创建,运行到销毁期间,总伴随着各种各样的事件,这些事件叫生命周期


MVVM

MVVM是Model-View-ViewModel的简写。它本质上就是MVC (Model-View- Controller)的改进版。即模型-视图-视图模型。

【模型】指的是后端传递的数据。【视图】指的是所看到的页面。【视图模型】mvvm模式的核心,它是连接view和model的桥梁。它有两个方向:

(1)是将【模型】转化成【视图】,即将后端传递的数据转化成所看到的页面。实现的方式是:数据绑定。

(2)是将【视图】转化成【模型】,即将所看到的页面转化成后端的数据。实现的方式是:DOM 事件监听。这两个方向都实现的,我们称之为数据的双向绑定。

在MVVM的框架下视图和模型是不能直接通信的。它们通过ViewModel来通信,ViewModel通常要实现一个observer观察者,当数据发生变化,ViewModel能够监听到数据的这种变化,然后通知到对应的视图做自动更新,而当用户操作视图,ViewModel也能监听到视图的变化,然后通知数据做改动,这实际上就实现了数据的双向绑定。并且MVVM中的View 和 ViewModel可以互相通信。

img


双向绑定