-
JS的原型链?
原型: 在 JS 中,每当定义一个对象(函数也是对象)时,对象中都会包含一些预定义的属性。其中每个函数对象都有一个prototype 属性,这个属性指向函数的原型对象。
原型链:原型对象除了有原型属性外,为了实现继承,还有一个原型链指针__proto__,该指针是指向上一层的原型对象,而上一层的原型对象的结构依然类似。因此可以利用__proto__一直指向Object的原型对象上,而Object原型对象用Object.prototype.__ proto__ = null表示原型链顶端。如此形成了js的原型链继承
简单来说,为了实现继承,就是每个js对象都会有一个原型__proto__,这个原型也会有自己的原型,每层的结构都类似,如果寻找特有属性,现在自己的对象里找,如果没有,原型对象里找,如果在没有,就一直往原型对象的原型对象里找,直到找到最顶部的Object对象,它的原型对象指向null。这个就是我们常说的原型链。
-
ES6新增了什么?
1、定义变量加入了 let const,新增块级作用域
2、ES6中引入了类(class)来代替构造函数(constructor)
3、新增了箭头函数
4、新增了一种基本数据类型(Symbol)(表示独一无二的值)
5、对象和数组新增了扩展运算符(...)
用于函数传参、合并数组、复制对象、合并对象
6、ES6新增了模块化(import / export)
7、新增了解构赋值
var[a,b,c]=[1,2,3];//把数组的值分别赋给下面的变量; console.log(a);//a的值为1 console.log(b);//b的值为2 console.log(c);//c的值为3
8、新增对象Set
数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
9、新增了map,reduce,filter,forEach
map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。不会改变原数组的值。
reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
forEach()可以认为是增强版的for循环。
forEach方法中的function回调有三个参数:
第一个参数是遍历的数组内容,
第二个参数是对应的数组索引,
第三个参数是数组本身var arr = [1,2,3,4]; var sum =0; arr.forEach(function(value,index,array){ array[index] == value; //结果为true sum+=value; }); console.log(sum); //结果为 10
-
ES5和ES6的类有什么区别?
在 ES5 中主要是通过构造函数方式和原型方式来定义一个类,但是在 ES6 新引入了 class 关键字,使之具有了正式类的能力,ES6中的类只是语法糖,它并没有改变类实现的本质。实际上它背后使用的仍然是原型和构造函数的概念。
- 使用 ES5 定义一个类并调用
function Person(name, age, job) { this.name = "Totora"; this.age = 19; this.job = "student"; this.sayName = function() { console.log(this.name); }; } let person = new Person(); person.sayName();
使用 ES6 定义一个类并调用
ES6中有两种定义类的方式:类声明和类表达式
class Person {}
和const Person = class {};
class Person { constructor() { this.name = "Totora"; this.age = 19; this.job = "student"; } sayName() { console.log(this.name); } } let person = new Person(); person.sayName(); //当我们使用typeof检测Person的类型时: console.log(typeof Person); //function,它的本质仍然是函数
继承
- ES5中的继承实质上是先创建子类的实例对象,再将父类的方法添加到this上(Parent.apply(this)),通过原型或构造函数机制来实现。
- ES6的继承实际上是先创建父类的实例对象this,然后再用子类的构造函数修改this。
-
Ajax、Fetch和Axios的区别
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。前端最流行的 ajax 请求库,主要作用是向后台发起请求的。
Axios是通过promise实现对ajax技术的一种封装,就像jquery对ajax的封装一样。(ajax技术实现了局部数据的刷新,axios实现了对ajax的封装。);
axios是ajax,ajax不止axios;axios有的ajax都有,ajax有的axios不一定有。
Ajax:
- Ajax 全名 async javascript and XML(异步JavaScript和XML),我们常说的 Ajax 默认是指以 XHR 为核心的技术合集
- 是前后台交互的能⼒ 也就是我们客户端给服务端发送消息的⼯具,以及接受响应的⼯具
- AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
- AJAX可以在不重新加载整个网页的情况下,对网页的某部分进行更新(无刷新技术)。
- 是⼀个 默认异步执⾏机制的功能,AJAX分为同步(async = false)和异步(async = true)
Fetch:
fetch号称是AJAX的替代品,是在ES6出现的,使用了ES6中的promise对象。Fetch是基于promise设计的。Fetch的代码结构比起ajax简单多了。但是,一定记住fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象。因为使用的是原生的JS,所以使用起来更加灵活。
Axios特点:
- 支持浏览器和node.js
- 支持promise
- 能拦截请求和响应
- 能转换请求和响应数据
- 能取消请求
- 自动转换JSON数据
- 浏览器支持防止CSRF(跨站请求伪造)
优缺点:
ajax:本身是针对MVC的编程,不符合现在前端MVVM的浪潮
基于原生的XHR开发,XHR本身的架构不清晰,已经有了fetch的替代方案
JQuery整个项目太大,单纯使用ajax却要引入整个JQuery非常的不合理。
axios:
从 node.js 创建 http 请求
支持 Promise API
客户端支持防止CSRF
提供了一些并发请求的接口(重要,方便了很多的操作)
axios 常用语法
- axios(config): 通用/最本质的发任意类型请求的方式
- axios(url[, config]): 可以只指定 url 发 get 请求
- axios.request(config): 等同于 axios(config)
- axios.get(url[, config]): 发 get 请求
- axios.delete(url[, config]): 发 delete 请求
- axios.post(url[, data, config]): 发 post 请求
- axios.put(url[, data, config]): 发 put 请求
- axios.defaults.xxx: 请求的默认全局配置
- axios.interceptors.request.use(): 添加请求拦截器
- axios.interceptors.response.use(): 添加响应拦截器
-
Vue脚手架2 和3的区别
一、生成项目命令不同
1、安装3.x版本的Vue脚手架:npm install -g @vue/cli
创建Vue项目命令:vue create 项目名称
或基于ui界面创建Vue项目,命令:vue ui2、安装了vue-cli 3.x 需要安装一个桥接工具才能使用 vue-cli 2.x创建项目
npm install -g @vue/cli-init
创建Vue项目命令:vue init webpack 项目名称
二、目录的区别
vue-cli 3.0的项目摈弃了 config 、 build 、 static 目录,新增了 public 目录,将根目录下的 index.html 放置在 public 目录下。
新增 webpack 的配置文件 vue.config.js ,可以在该文件中进行webpack的相关配置,例如 loader、开发环境等等。
新增 .browserslistrc 文件,指定了项目的目标浏览器的范围,用来确定需要转译的JavaScript 特性和需要添加的 CSS 浏览器前缀,可以理解为浏览器兼容。
新增 babel.config.js 替代原先的.babelrc,具备和原先.babelrc一样的作用。(如果需要实现向后兼容,支持低版本的浏览器,如把ES6转为ES5,就要用到babel,作用于整个项目)
src文件夹中多了 views 文件夹,相比2.0,在 index.js 变为了 router.js
2.0版本相比3.0版本 有build和config文件夹等,src文件夹中有router文件夹,里面有index.js
三、启动项目
3.x启动项目:
npm run serve2.x启动项目:
npm run dev 或 npm run start四、配置项
vue-cli2.0的域名配置,分为开发环境和生产环境,所以配置域名时,需要在config中的dev.env.js和prod.env.js中分别配置前面说过,到了3.0 config文件已经被移除,除了文件位置,实际配置起来和2.0没什么不同
没了config文件,跨域需要配置域名时,从config/index.js 挪到了vue.config.js中,配置方法不变。
-
Vue的config.js配置了什么
// 后端服务器地址
let url = 'http://localhost:8888'
module.exports = {
publicPath: './', // 【必要】静态文件使用相对路径
outputDir: "./dist", //打包后的文件夹名字及路径
devServer: { // 开发环境跨域情况的代理配置
proxy: {
// 【必要】访问自己搭建的后端服务器
'/api': {
target: url,
changOrigin: true,
ws: true,
secure: false,
pathRewrite: {
'^/api': '/'
}
},
// 【范例】访问百度地图的API
// vue文件中使用方法 this.$http.get("/baiduMapAPI/place/v2/search"
// 最终实际访问的接口为 http://api.map.baidu.com/place/v2/search
// 遇到以/baiduMapAPI开头的接口便使用此代理
'/baiduMapAPI': {
// 实际访问的服务器地址
target: 'http://api.map.baidu.com',
//开启代理:在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样客户端和服务端进行数据的交互就不会有跨域问题
changOrigin: true,
ws: true, // 是否启用websockets
secure: false, // 使用的是http协议则设置为false,https协议则设置为true
// 将接口中的/baiduMapAPI去掉(必要)
pathRewrite: {
'^/baiduMapAPI': ''
}
},
}
}
}
原文链接:https://blog.csdn.net/weixin_41192489/article/details/112635196
-
父子组件传参
父组件使用v-bind进行绑定,在子组件里面定义props来做接收,接受父组件传来的数据并指定类型,这是比较常见的情况。
-
ElmentUI表单验证
Elment-UI 的 Form 组件提供了表单验证的功能:
1.将 el-form-Item 的
prop
属性设置为需校验的字段名<el-form-item label="姓名" prop="name"> <el-input v-model="simpleForm.name" placeholder="请输入您的姓名" /> </el-form-item>
2.通过
rules
属性传入约定的验证规则rules: { name: [ { required: true, //非空校验 message: '提示信息', //校验提示信息 trigger: 'blur'//触发条件:blur、change } ]
-
数组常用方法
1、concat()---连接数组(不改变原数组)
2、join()---将数组转为字符串(不改变原数组)
3、unshift()/push()---加入一个或多个元素,unshift()从头部加,push()从尾部加,返回加入元素后数组的新长度。(改变)
3、shift()/pop()---删除数组,shift()删头部,pop()删尾部。(改变)
4、sort()---数组排序(改变)
5、reverse()---反转数组(改变)
6、slice()---截取数组(不改变)
7、splice()---更新数组,添加或删除数组(改变)
8、indexOf()/lastindexOf()---返回查找项在数组中首次出现的位置,没找到就返回-1,indexOf从头找,lastindexOf从尾部向前找。
9、find()---查找一个值,返回符合条件的第一个元素
10、filter()---筛选,把符合条件的都找出来
11、forEach()---for循环增强版
12、some()/every()---数组迭代方法,some是任意一项符合就返回true,erery是每一项都符合才返回true
13、map()---返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。(不改变)
14、reduce()---接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。(不改变)
-
Vue组件封装过程:
Vue组件封装过程
● 首先,使用Vue.extend()创建一个组件
● 然后,使用Vue.component()方法注册组件
● 接着,如果子组件需要数据,可以在props中接受定义
● 最后,子组件修改好数据之后,想把数据传递给父组件,可以使用emit()方法
-
Vue防抖和节流:
防抖:防止重复点击触发事件
典型应用就是防止用户多次重复点击请求数据。
使用clearTimeout和setTimeout来封装一个函数放到util.js公共数据库中。
function debounce(fn, time) { let _arguments = arguments let timeout = null return function () { if (timeout) { clearTimeout(timeout) } timeout = setTimeout(() => { fn.call(this, _arguments) }, time); } }
然后在需要用到防抖的页面引入
import { simpleDebounce } from '@/utils/util'
放到methods中
methods: { test: simpleDebounce( function () { console.log("测试"); },1000), }
函数节流(throttle)
解释:当持续触发事件时,有规律的每隔一个时间间隔执行一次事件处理函数。
案例:持续触发scroll事件时,并不立即执行handle函数,每隔1000毫秒才会执行一次handle函数。
-
移动端适配
1、viewprot适配方法
这种方式其实是动态设置缩放比例,动态创建meta标签,并且将计算出来的initial-scale(缩放比例)放到这个标签的content属性里面
2、使用rem方法适配
rem:CSS的长度单位, 根元素字体大小的倍数,也就是说rem是基于font-size来设置的。html 中的根元素即 html 元素。
rem适配最主要的就是html根元素字体大小设置屏幕区域的宽度,这样整个屏幕就变成了1rem为基准,然后在设置每个元素的时候试用rem来做单位。
简单地说就是将px单位改成rem即可。比如说1rem=100px,则当width=640px时,设置为6.4rem即可。