🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
#### 各大框架里面的核心内容 **vue** * vue-cli 3.0 (2.0向3.0的过渡) * 配置 * 优化 * vue基础知识 * 双向数据绑定 * template模板渲染语法和原理(vue-loader 、 虚拟DOM) * 指令和自定义指令 * methods computed watch filters * class / style * 条件和循环渲染 * 事件处理 * 表单处理 * 组件(属性) * ref * 生命周期 * 插槽 * transition * 渲染函数和jsx * 插件编写 * 混入 * devtools * …… * vue-router * 基础知识 * 动态路由 * 编程式导航 * 命名路由和命名容器 * 导航守卫 * HASH和BROWSER路由 * 路由原理 * …… * vuex * state * getter * mutation * action * module * mapXxx * 实现原理 * …… * 单元测试 * SSR服务器渲染 nuxt.js * UI组件库 * …… **react** * create-react-app * 配置 * 优化 * react基础 * JSX语法(虚拟DOM) * 状态 * 属性 * ref * 组件 * 生命周期 * PureComponent * Hooks * …… * react-router-dom * redux * redux * react-redux * 中间件 * …… * dva * umi * typescript * UI组件 * SSR服务器渲染 next.js * …… 第二天作业讲解 ~~~ // TO-STRING /* var a = { i: 0, toString() { //或者valueOf return ++this.i; } }; if (a == 1 && a == 2 && a == 3) { console.log('条件成立'); } */ /* var a = [1, 2, 3]; a.toString = a.shift; if (a == 1 && a == 2 && a == 3) { console.log('条件成立'); } */ /* 数据劫持实现 */ /* var i = 0; Object.defineProperty(window, 'a', { get() { return ++i; } }); if (a == 1 && a == 2 && a == 3) { console.log('条件成立'); } */ /* var a = 0; Object.defineProperty(window, 'a', { get() { // Uncaught TypeError: Cannot redefine property: a // defineProperty GETER拦截器中不能再次获取当前属性 return ++a; } }); console.log(a); */ ~~~ == 1、对象和字符串,对象转为字符串; 2、null和undefined相等,和其他都不等; 3、NaN和任何都不相等,包含和自己不相等; 4、剩下的都转为数字; ## 1. Vue2.0/3.0双向数据绑定的实现原理 ~~~ ES5:Object.defineProperty <body> 姓名:<span id="spanName"></span> <br> <input type="text" id="inpName"> <!-- IMPORT JS --> <script> let obj = { name: '' }; let newObj = { ...obj }; // let newObj = JSON.parse(JSON.stringify(obj)); Object.defineProperty(obj, 'name', { get() { return newObj.name; }, set(val) { newObj.name = val; observe(); } }); function observe() { spanName.innerHTML = newObj.name; } inpName.oninput = function () { obj.name = this.value; }; </script> </body> ~~~ ~~~ /* 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 = "珠峰培训"; }, 1000); inpName.oninput = function () { obj.name = this.value; }; */ /* * 1. 对原始数据克隆 * 2. 需要分别给对象中而定每一个属性设置监听 */ ~~~ ~~~ let obj = {}; obj = new Proxy(obj, { get(target, prop) { return target[prop]; }, set(target, prop, value) { target[prop] = value; observer(); } }); function observer() { spanName.innerHTML = obj.name; inpName.value = obj.name; } setTimeout(() => { obj.name = "珠峰培训"; }, 1000); inpName.oninput = function () { obj.name = this.value; }; ~~~ ## 2. MVC和MVVM的区别 ![](https://img.kancloud.cn/16/9e/169e58828f4d8ff30bc7ee7db264575d_321x163.png) ![](https://img.kancloud.cn/54/c7/54c76b9bcab8923ced41f2eb50bb4f8c_386x181.png) ~~~ import React from 'react'; import ReactDOM from 'react-dom'; import axios from './axios'; class A extends React.Component { state = { name: '' }; render() { let { name } = this.state; return <> 姓名:<span>{name}</span> <br /> <input type="text" value={name} onChange={ev => { this.setState({ name: ev.target.value }); }} /> </>; } async componentDidMount() { setTimeout(_ => { this.setState({ name: '珠峰培训' }); }, 1000); let data = await axios.get('/product/banner'); console.log(data); } } ReactDOM.render(<> <A /> </>, document.getElementById('root')); ~~~ ## 3\. 跨域问题的解决方案和实现原理 **跨域问题的产生及其价值意义** 前后端分离导致出现跨域 **JSONP跨域解决方案的底层原理** 只能get请求,不安全 客户端 ![](https://img.kancloud.cn/c6/b3/c6b3c31eef2333a24586a6ddae78fcb3_849x433.png) ~~~javascript <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script> $.ajax({ url: 'http://127.0.0.1:8001/list', method: 'get', dataType: 'jsonp', success: res => { console.log(res); } }); </script> ~~~ 后台 ~~~javascript let express = require('express'), app = express(); app.listen(8001, _ => { console.log('OK!'); }); app.get('/list', (req, res) => { let { callback = Function.prototype } = req.query; let data = { code: 0, message: '珠峰培训' }; res.send(`${callback}(${JSON.stringify(data)})`); }); ~~~ **基于iframe的跨域解决方案** * window.name * document.domin * location.hash * post message **CORS跨域资源共享** 客户端 ~~~javascript import axios from 'axios'; import qs from 'qs'; axios.defaults.baseURL = "http://127.0.0.1:3000"; axios.defaults.timeout = 10000; axios.defaults.withCredentials = true; /* * 设置请求传递数据的格式(看服务器要求什么格式) * x-www-form-urlencoded */ axios.defaults.headers['Content-Type'] = 'application/x-www-form-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 config; }, error => { return Promise.reject(error); }); /* * 响应拦截器 */ axios.interceptors.response.use(response => { return response.data; }, error => {}); export default axios; ~~~ 服务器端 ~~~javascript app.use((req, res, next) => { res.header("Access-Control-Allow-Origin", ""; res.header("Access-Control-Allow-Credentials", true); res.header("Access-Control-Allow-Headers", "PUT,POST,GET,DELETE,OPTIONS,HEAD"); res.header("Access-Control-Allow-Methods", "Content-Type,Content-Length,Authorization, Accept,X-Requested-With"); req.method === 'OPTIONS' ? res.send('CURRENT SERVICES SUPPORT CROSS DOMAIN REQUESTS!') : next(); }); ~~~ **基于http proxy实现跨域请求** webpack 在package.js中有proxy:"http://127.0.0.1:9999" 开发的时候用这个,但是服务器还要nginx反向代理 **nginx反向代理** 4.Vue/React框架中关于组件信息通信引发的面试题 * vue 属性传递 发布订阅(EventBus):$on / $emit Provide / inject slot $parent / $children vuex * react 属性 发布订阅 React.createContext redux / react-redux / mobix / dva 本地存储,redux存在虚拟内存中了,redux不光能状态管理,还能存储数据。 > 服务器设置session,服务器返回给客户端的信息,在响应头中带着set-cookie = ‘connect.sid’ 客户端会把信息种植到本地的cookie中的HTTPonly,客户端再次向服务器发送请求的时候,会默认在请求头中cookie把connect.sid传递发给服务器。 ![](https://img.kancloud.cn/03/4e/034e9f2a314f282a04cf8facd0bd41da_246x123.png) ![](https://img.kancloud.cn/05/4c/054ca75e91201c5425fc39d3a6105e6d_833x450.png)