一、vue2.0/3.0 双向数据绑定的实现原理
vue2.0
ES5:Object.defineProperty
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
姓名: <span id='spanName'></span>
<br/>
<input type='text' id='inpName' />
</body>
<script>
let obj = {name: ''}
let newObj = JSON.parse(JSON.stringify(obj))
Object.defineProperty(obj, 'name', {get(){return newObj.name},
set(val){if(val === newObj.name) return
newObj.name = val;
observer();},
})
function observer(){
spanName.innerHTML = obj.name;
inpName.value = obj.name
}
setTimeout(() => {obj.name = '我是 eternity';}, 1000)
// 以下相似于 v -model
inpName.oninput = function () {obj.name = this.value;}
</script>
</html>
存在的问题:
1、须要对原始数据克隆
2、须要别离给对象中每一个属性设置监听
3、对于对象和数组的监听不是很无效,可用 $set, 或者原生的办法;
vue3.0
ES6: proxy
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
姓名: <span id='spanName'></span>
<br/>
<input type='text' id='inpName' />
</body>
<script>
let obj = {}
obj = new Proxy(obj, {get(target, prop){ // 指标: obj prop: 属性 obj.name
console.log('eternity')
return target[prop]
},
set(target, prop, value){console.log('zjh')
target[prop] = value
observe()}
})
function observer(){
spanName.innerHTML = obj.name;
inpName.value = obj.name
}
setTimeout(() => {obj.name = '我是 eternity^zjh';}, 1000)
// 以下相似于 v -model
inpName.oninput = function () {obj.name = this.value;}
</script>
</html>
二、MVC 和 MVVM 的区别
MVVM: 视图更改影响视图,视图更改数据(双向数据绑定,双向影响)vue 的 onChange,onInput 事件曾经处理完毕
MVC: 数据更改影响视图,少了一层 onChange
三、跨域问题和解决办法
1、JSONP 跨域
callback 问号传参的形式
本地写入 callback 函数,后盾将数据返回作为 callback 的参数
缺点:不平安,只能用 get,还须要服务独自反对
2、基于 iframe 的跨域解决方案
3、CORS 跨域资源共享
import axios from 'axios';
import qs from 'qs';
axios.defaults.baseUrl = 'http://127.0.0.1:300';
axios.defaults.timeout = 10000;
axios.defaults.withCredentials = true;
// 容许跨域携带 cookie 申请
/*
* 设置申请传递数据的格局(看服务器要求什么格局)*x-www-urlencoded
*/
axios.defaults.headers['Content-Type'] = 'application/x-www-urlencoded';
axios.defaults.transformRequest = data => qs.stringify(data);
/*
* 设置申请拦截器
* TOKEN 校验(JWT): 接管服务器返回的 token,存储到 vuex、本地存储中,每一次拜访服务器的时候,咱们应该吧 token 带上
*/
axios.interceptors.request.use(config => {let token = localStorage.getItem('token');
token && (config.headers.Authorization = token);
return token;
},error => {return Promise.reject(error);
});
/*
* 响应拦截器
*/
axios.interceptors.response.use(response => {return response.data;}, err => {})
export default axios;
后端:access-control-allow-origin:’*’