vue
1.static和assets的区别
assets和static两个都是用于存放静态资源文件。
放在static中的文件不会进行构建编译处理,也就不会压缩体积,在打包时效率会更高,但体积更大在服务器中就会占据更大的空间。
放在assets中的文件会进行压缩体积、代码格式化,压缩后会放置在static中一同上传服务器。
因此建议样式文件放在assets中进行打包,引入的第三方文件放到static中,因为引入的文件已经做过打包处理。
2.vuex
// index.js import Vue from "vue"; import Vuex from "vuex"; import { ADDCOUNT } from "./mutation-types" Vue.use(Vuex); export default new Vuex.Store({ state: { // data(变量) count: 0, books: [{ id: 1, name: '钢铁是怎样炼成的', price: 15 }, { id: 2, name: '老人与海', price: 6 }, { id: 3, name: '简爱', price: 12 }, { id: 4, name: '巴黎圣母院', price: 24 }] }, mutations: { // 同步methods(方法) [ADDCOUNT](state, count) { state.count += count }, subCount(state) { state.count-- }, addAttr(state) { Vue.set(state.books[0], 'lunguage', '中文') }, deleteAttr(state) { Vue.delete(state.books[0], 'lunguage') }, upData(state, count) { state.count += count } }, getters: { // computed(计算属性) books1(state) { return state.books[1] }, oldPeple(state, getters) { return `《${state.books[1].name}》售价${getters.books1.price}元` }, wantPrice(state) { return function (price) { let want = state.books.filter(v => v.price === price) return `《${want[0].name}》售价${want[0].price}元` } } }, actions: { // 异步methods(方法) // context 执行上下文 upData(context, count) { return new Promise((resolve) => { setTimeout(() => { context.commit('upData', count) resolve('成功加了' + count) }, 3000); }) } }, modules: { // 可以将store分为模块化,每个模块内都有state,mutations,getter,actions属性 a: { state: { count: 0 }, mutations: { addCountA(state, count) { state.count += count } }, getters: { countA(state) { return state.count += 10 } }, actions: { // 一样 } }, b: { state: {}, mutations: {}, getters: {}, actions: {} } } }); // mutation-types.js export const ADDCOUNT = 'addCount'; // 使用 1.使用this.$store.state.count来获取state里面的值 2.使用this.$store.commit("addCount")来调用mutations里面的方法,并且可以在commit("addCount",count)传递参数count 3.使用$store.getters.oldPeple相当于一个单例的计算属性来获取state的值 3.1.使用getters返回一个方法来接受参数 $store.getters.wantPrice(12) 5.可以在store文件夹下创建一个mutation-types的js文件,专门用来管理mutations里面的方法名 6.actions使用:通过this.$store.dispatch('upData', count) 7.modules 获取模块a里面的值:{{ $store.state.a.count }}--{{ $store.getters.countA }} 触发模块a的方法:$store.commit('addCountA', 100)
3.封装一个input输入框
1.子组件 <template> <div> <input type="text" @input="$emit('input', $event.target.value)" :value="value" /> </div> </template> <script> export default { name: "Form", props: ["value"], }; </script> 2.父组件 <template> <div> <p>{{ value }}</p> <Form v-model="value"/> </div> </template> <script> import Form from "./components/Form"; export default { name: "Home", components: { Form, }, data() { return { value: "", }; }, created() { console.log(this.$route.path); }, }; </script>
3.v-model实现原理
<input v-model="sth" /> 等同于 <input :value="sth" @input="sth = $event.target.value" />
4.bus
1.定义Bus const Bus = new Vue(); 2.挂载Bus Vue.prototype.$bus = Bus; 3.调用 组件一email.vue <template> <div class="email"><button @click="handleClick">按我</button></div> </template> <script> export default { methods: { handleClick () { this.$bus.$emit('on-click','hello') } } } </script> 组件二tel.vue <template> <div class="tel">{{ message }}</div> </template> <script> export default { data () { return { message: '' } }, mounted () { this.$bus.$on('on-click',mes => { this.message = mes }) } } </script>
5.vue白屏
vue项目有个缺点,首次渲染会有一段时间的白屏原因是首次渲染时需要加载一堆资源,如js、css、图片。很多优化策略,最终目的是提高这些资源的加载速度。但是如果遇上网络慢的情况,无论优化到极致还是需要一定加载时间, 这时就会出现白屏现象。首先加载是index.html页面,其是没有内容,就会出现白屏。如果<div id="app"></div>里面有内容,就不会出现白屏。所以我们可以在<div id="app"></div>里添加首屏的静态页面。 等真正的首屏加载出来后就会把<div id="app"></div>这块结构都替换掉,给人一种视觉上的误差,就不会产生白屏。
js
1.函数防抖节流
//防抖
function debounce(func, wait) {
let timeout;
return function () {
if (timeout) {
clearTimeout(timeout)
}
timeout = setTimeout(() => {
func.apply(this, arguments)
}, wait)
}
}
//节流
function throttle(func, wait) {
let timeout;
return function () {
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(this, arguments)
}, wait)
}
}
}
function say() {
console.log('hi haha')
}
document.onmousemove = debounce(say, 1000)
document.onmousemove = throttle(say, 1000)
2.闭包
没有被引用的闭包会被自动回收,但还存在全局变量中,则依然会内存泄漏。 在 JavaScript 中,根据词法作用域的规则,内部函数总是可以访问其外部函数中声明的变量,当通过调用一个外部函数返回一个内部函数后,即使该外部函数已经执行结束了,但是内部函数引用外部函数的变量依然保存在内存中,
我们就把这些变量的集合称为闭包。
比如外部函数是 foo,那么这些变量的集合就称为 foo 函数的闭包。
function getNum() { let n = 1 return function() { n++ } } getNum() // 2 getNum() // 3 getNum() // 4 getNum() // 5
3.new操作符
function createThis(fn) { let obj = {}; // 创建一个新的对象 let [constructor, ...args] = [...arguments]; obj.__proto__ = fn.prototype; // 把obj的__proto__指向fn的prototype,实现继承 constructor.apply(obj, args); // 改变this的指向,执行构造函数、传递参数,fn.apply(obj,) 或者 fn.call() -- constructor是fn的构造函数 args 是传递的参数 return obj; // 返回新的对象obj } let App = function () { Object.assign(this, { age: 18, sey() { console.log(this.age); }, }); }; let a = createThis(App, 415); a.sey(); // 18
4.函数柯里化
const curry = fn => { if (typeof fn !== "function") { throw Error("No function provided") } return function curriedFn(...args) { if (args.length < fn.length) { return function () { return curriedFn.apply(null, args.concat([].slice.call(arguments))) } } return fn.apply(null, args) } } function add(a, b, c) { console.log(a + b + c) } let ad = curry(add) ad(1)(1)(1) // 复用几次取决于有多少参数
5.拷贝
浅拷贝指拷贝引用对象,仍指向同一个地址,修改时原对象也会受到影响.。 深拷贝完全拷贝一个新对象,修改时原对象不再受到任何影响 浅拷贝:扩展运算符、Object.assign、contact、slice等 深拷贝: 1.使用JSON.parse(JSON.stringify(obj))。性能最快。其弊端也必将明显,首先无法拷贝函数、undefined、或symbol等值。其二对象要是有自身循环调用,会报错。 2.利用递归来实现每一层都重新创建对象并赋值 3.如何用jquery,可以考虑,$.extend()
5.1简单的深拷贝-递归实现
function copy(obj) { let result = Array.isArray(obj) ? [] : {} for (let key in obj) { if (obj.hasOwnProperty(key)) { if (typeof obj[key] === 'object') { result[key] = deepCopy(obj[key]) // 递归复制 } else { result[key] = obj[key] } } } return result } let a = { name: 'lj' }, b = copy(a) b.name = 'lc' console.log(a, b) // {name: "lj"} {name: "lc"}
6.js运行机制
宏任务(macro-task):整体代码script、setTimeOut、setInterval 微任务(mincro-task):promise.then、promise.nextTick(node) 需要注意的是new Promise是会进入到主线程中立刻执行,而promise.then则属于微任务 function add(x, y) { console.log(1) setTimeout(function() { // timer1 console.log(2) }, 1000) } add() setTimeout(function() { // timer2 console.log(3) }) new Promise(function(resolve) { console.log(4) setTimeout(function() { // timer3 console.log(5) }, 100) for(var i = 0; i < 100; i++) { i == 99 && resolve() } }).then(function() { setTimeout(function() { // timer4 console.log(6) }, 0) console.log(7) }) console.log(8) 执行结果 //1,4,8,7,3,6,5,2
7.从输入URL到页面显示的过程
1. 发送URL,请求IP地址 2. TCP三次握手 第一次握手:建立连接,第二次握手:服务器收到SYN报文段,第三次握手:客户端收到SYN+ACK报文段 3.服务器响应200 4.生成Render Tree 5.渲染页面
8.原型链
8.1创建对象的几种方式
//1.字面量 let obj1 = { name: '阿成' } //2.new Object let obj2 = new Object({ name: '阿成' }) //3.构造函数创建 let M = function (name) { this.name = name } let obj3 = new M('阿成') //4.Object.create let obj4 = Object.create({ name: '阿成' })
8.2原型、构造函数、实例、原型链
构造函数、原型对象、实例的关系可以参照下图:
构造函数.prototype.constructor === 构造函数
构造函数.prototype === 实例对象.proto
9.页面性能优化
1.资源压缩合并,减少 HTTP 请求 2.非核心代码异步加载(异步加载的方式,异步加载的区别) 3.利用浏览器缓存(缓存的分类,缓存原理) 4.使用 CDN 5.预解析 DNS
html5
1.良好的移动性,以移动端设备为主。 2.响应式设计,以适应自动变化的屏幕尺寸。 3.支持离线缓存技术,webStorage本地缓存。 4.新增canvas,video,audio等新。标签元素。新增特殊内容元素:article ,footer ,header,nav ,section等,新增表单控件:calendar,date,time,email,url,search。 5.地理定位..... 6.新增webSocket/webWork技术。
es6
1 let 和 const let 在块级作用域内有效,不会污染全局变量 const 一经声明不能改变。注意保证的是它指向的内存地址不能改变,如果是对象或者数组里面的属性或元素可以改变的。 存在暂时性死区,不能变量提升。 只能先声明再使用,且不能重复声明 2 字符模板 用作字符串拼接:`你好,${name}` 3 变量的解构赋值 let [a,b,c] = [1,2,3] 交换变量的值:[a,b] = [b,a] 提取 JSON 数据,获取服务器返回数据时有用:let {data, code} = res 输入模块的指定方法: const { SourceMapConsumer, SourceNode } = require("source-map"); 从函数返回多个值: 返回个数组或对象 4 扩展运算符 扩展运算符(spread)是三个点(...)。 复制数组:let arr2 = [...arr1] 合并数组:[...arr1, ...arr2, ...arr3] 5 Promise 成功调用 resolve,失败调用 reject .then 获取结果,.catch 捕获异常。捕获异常还可通过 .then 的第二个参数 .finally 无论成功失败都一定会调用 多个并发的请求,用 Promise.all() 只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。 只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。 let p = Promise.all([p1,p2,p3]) p.then(([res1, res2,res3]) => {}; 复制代码Promise 示例: new Promise(){ if (/* 异步操作成功 */){ resolve(value); } else { reject(error); } }.then().catch().finally() 6 async await async 函数是什么?一句话,它就是 Generator 函数的语法糖。 async 函数对 Generator 函数的改进: 内置执行器,直接调用即可。Generator 还需要调用 next()才能执行 更好的语义。async 和 await 比 * 和 yield 更好理解 返回值是 Promise 7 箭头函数 箭头函数 () => {} 的 this 是在定义函数时绑定的,不是在执行过程中绑定的。简单的说,函数在定义时,this 就继承了定义函数的对象。this 一旦确定以后不会改变。 普通函数的 this 指向的是调用它的对象。