1.uni.navigateTo可以实现页面的普通跳转,
2.uni.redirectTo可以实现页面的重定向跳转
3.uni.reLaunch可以实现关闭所有页面,打开到应用内的某个页面。
uni.onPullDownRefresh方法实现下拉刷新
uni.onReachBottom方法实现上拉加载更多
uni.getLocation()
通过调用后端预支付的接口返回成功的订单参数的写进uni.requestPayment,参数有签名,appId,时间戳,预支付id ,随机字符串等
1.在uniapp官网的开发者后台上开通一键登录会得到账号API密钥apiKey和apiSecret
2.在unicloud云开发环境里写入云函数代码
3.绑定一键登陆的按钮事件中先调预登陆uni.preLogin成功的返回中写入登陆uni.login,成功后会拿到openId和access_token,再调用一键登陆的云函数接口成功后就会获取到手机号
uni.createInnerAudioContext()
// 创建音频实例
const audio = uni.createInnerAudioContext();
// 设置音频资源
audio.src = 'http://example.com/audio.mp3';
// 播放音频
audio.play();
// 暂停音频
audio.pause();
// 停止音频
audio.stop();
uni.lazyLoadImage组件
uni.getSystemInfo方法获取设备信息,包括设备型号、操作系统版本
uni.setStorageSync(‘key’, ‘value’);
uni.getStorageSync(‘key’);
异步存储:uni.setStorageSync,获取:uni.getStorageSync
同步存储:uni.setStorage,获取:uni.getStorage
关于uniapp项目中页面之间传递数据的三种方式?
1.uni.navigateTo方法的url参数中添加query参数 跳转到的页面里onload接收
需要传递的参数有很多时,由于uniapp跳转页面api 的 url 有长度限制,使用以下数据传递:
encodeURIComponent(JSON.stringify(item))获取JSON.parse(decodeURIComponent(option.item))
2.利用uni.setStorageSync和uni.getStorageSync进行数据的缓存
3.传值页面使用uni. e m i t 和接收页面在 o n l o a d 里使用 u n i . emit 和接收页面在onload里使用 uni. emit和接收页面在onload里使用uni.on接收参数
uni.previewImage方法实现图片预览功能,通过设置urls参数来指定要预览的图片地址。urls里可放数组
uni.showShareMenu方法开启页面的分享功能,使用uni.onShareAppMessage方法设置分享的标题、路径等。
Uni-app就是用着vue的指令和小程序的组件和API
vue和uni-app动态绑定一个变量的值为元素的某个属性的时候,会在属性前面加上冒号":";
小程序绑定某个变量的值为元素属性时,会用两个大括号{{}}括起来,如果不加括号,为被认为是字符串。
在app.js的globalData设置,在需要的地方getApp().globalData()
应用生命周期:
1.onLaunch——当uni-app 初始化完成时触发(全局只触发一次)
2.onShow——当 uni-app 启动,或从后台进入前台显示
3.onHide——当 uni-app 从前台进入后台
4.onError——当 uni-app 报错时触发
5.onUniNViewMessage——对 nvue 页面发送的数据进行监听
6.onUnhandledRejection——对未处理的 Promise 拒绝事件监听函数
7.onPageNotFound——页面不存在监听函数
8.onThemeChange——监听系统主题变化
页面生命周期:
1.onInit——监听页面初始化,其参数同 onLoad 参数,触发时机早于 onLoad
2.onLoad——监听页面加载,其参数为上个页面传递的数据,
3.onShow——监听页面显示。页面每次出现在屏幕上都触发,
4.onReady——监听页面初次渲染完成。注意如果渲染速度快,会在页面进入动画完成前触发
5.onHide——监听页面隐藏
6.onUnload——监听页面卸载
7.onResize——监听窗口尺寸变化
组件生命周期:就是vue生命周期
1.beforeCreate——在实例初始化之后被调用。
2.created——在实例创建完成后被立即调用。
3.beforeMount——在挂载开始之前被调用。
4.mounted——挂载到实例上去之后调用。如果需要子组件完全挂载之后在执行操作可以使用$nextTickVue
5.beforeUpdate——数据更新时调用,发生在虚拟 DOM 打补丁之前。
6.updated——由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
7.beforeDestroy——实例销毁之前调用。在这一步,实例仍然完全可用。
8.destroyed——Vue 实例销毁后调用。
整个小程序所有分包不能超过20M
单个分包不超过2M
需要在page文件下创建一个subpack文件里面放分包的文件,之后在pages.json文件写入分包加载配置subpackages,里面根page配置差不多会多一个root用来放子包的根目录
preloadRule可以进行分包预载配置,可以配置不同网络环境下进入页面会预先下载subpack分包
uni.login()
通过配置provider参数来实现微信,或支付宝等第三方登录
uni.getUserInfo(OBJECT)
获取用户信息。
uni.getUserProfile(OBJECT)
获取用户信息。每次请求都会弹出授权窗口,用户同意后返回 userInfo。
uni.preLogin(OBJECT)
预登录。用于App手机号一键登录。
uni.closeAuthView()
关闭一键登录页面。
Viewmodel 中的Domlisteners 工具会帮我们检测页面上Dom元素的变化,如果有变化,则更改Model中的数据,更新model中的数据时,数据事件绑定工具会帮我们更新页面中的Dom元素
vue会遍历data数据对象,使用Object.definedProperty()将每个属性都转换为getter和
setter,每个Vue组件实例都有一个对应的watcher实例,在组件初次渲染的时候会记录组件用到
了那些数据,当数据发生改变的时候,会触发setter方法,并通知所有依赖这个数据的watcher实
例调用update方法去触发组件的compile渲染方法,进行渲染数据。
响应式原理
vue2的响应式原理的基础是Object.defineProperty,每个数据属性被定义成可观察具有getter和setter方法,当这些属性被修改后,vue会自动追踪并重新计算相关的渲染函数,并更新视图。
vue3响应式原理基础是使用了ES6中的Proxy代理对象来代替Object.defineProperty()方法,proxy对象可以拦截对象上的一些操作,从而实现更加灵活的响应式更新。
diff原理
vue2 diff算法是通过比较新旧虚拟DOM树来确定必须更新的DOM元素的最小集合
vue3 diff采用了编译时优化的动态标记,只需要对动态节点进行比较,避免了对静态节点不必要操作,从而提高了性能
Vue2 Options API (选项式API)存在的问题, 新增或者修改一个需求,就需要分别在data,methods,computed里修改
Vue3 Componsition API (组合式API) 只需要在特定的代码块新增修改,代码维护性更强开发者可以只需关注实际的业务逻辑,
ref 和 reactive 区别?
原理:ref通过Object.defineProperty()的get与set来实现响应式(数据劫持)。
reactive通过使用Proxy来实现响应式(数据劫持), 并通过Reflect操作源对象内部的数据。
ref通常用来定义基本类型数据, reactive用来定义引用类型数据
因为JavaScript的特性所导致,在component中,data必须以函数的形式存在,不可以是对象。
组建中的data写成一个函数,数据以函数返回值的形式定义,这样每次复用组件的时候,都会返回一份新的data,相当于每个组件实例都有自己私有的数据空间,它们只负责各自维护的数据,不会造成混乱。而单纯的写成对象形式,就是所有的组件实例共用了一个data,这样改一个全都改了。
默认插槽,具名插槽,作用域插槽
vue中的插槽,指的是子组件中提供给父组件使用的一个占位符;
用标签表示,父组件可以在这个占位符中填充任何模板代码,比如HTML、组件等,填充的内容会替换掉子组件的标签
其实区别并不大,都是一种设计思想,主要就是mvc中的controller 变成了mvvm中的view-model 。mvvm解决了mvc中大量的DOM操作,使页面性能降低,加载速度变慢,影响用户体验。
vuex是为vue.js应用程序开发的状态管理模式了。作用项目数据状态集中管理
state 存放数据状态
mutations定义的方法动态修改vuex中state中的状态或数据 store.commit可触发mutation函数
getters类似vue的计算属性,主要用来过滤一些数据
action异步操作数据 不能直接修改状态。需要通过提交mutation才能变更状态 store.dispatch异步触发action函数
module 将store分割成模块,每个模块都有自己的state,mutations,action,getter
vuex本身就不是持久化存储,是一个状态管理仓库,方便组件之间通信一个组件的数据变化是会映射到使用这个数据的其他的组件,并且能够触发响应式的渲染页面更新,localstorage本地存储,是将数据存到浏览器的方法,一般是在跨页面传递数据时使用。
实现持久化存储:使用本地存储,使用插件vuex- presistedState插件
全局守卫beforeEach afterEach
路由独享守卫 beforeEnter
组件内守卫beforeRouteEnter beforeRouteUpdate beforeRouteLeave
使用场景
在用户进入某个页面之前判断用户身份登录状态,未登录需要跳转到登陆页面
vue router中mode默认为hash模式,会有#号,hash模式在单页面应用中切换路由,页面不会刷新,只是hash部分变化,根据hash不同来渲染内容。
history模式下刷新就会导致页面404,服务器无法找到对应的文件,就会404,需要在nginx服务器配置文件
//在nginx的配置文件里放入下面代码
server {
listen
server_name
root
location / {
try_files $uri $uri/ /index.html;
}
}
父传子时通过给子组件定义属性传值prop
子传父:子组件发射事件通过 e m i t , 父组件执行事件,父组件定义事件兄弟之间:定义一个 v u e 实例作为中间层传递数据,通过中间层发送数据,再通过 c r e a t e 监听事件建立一个 b u s 文件,创建一个 v u e 实例并暴露出去,子组建分别引入 b u s 文件,子组建一通过 b u s . emit,父组件执行事件,父组件定义事件 兄弟之间:定义一个vue实例作为中间层传递数据,通过中间层发送数据,再通过create监听事件 建立一个bus文件,创建一个vue实例并暴露出去,子组建分别引入bus文件,子组建一通过bus. emit,父组件执行事件,父组件定义事件兄弟之间:定义一个vue实例作为中间层传递数据,通过中间层发送数据,再通过create监听事件建立一个bus文件,创建一个vue实例并暴露出去,子组建分别引入bus文件,子组建一通过bus.emit发送数据。 子组件二通过在create里bus.$on接收参数
$refs
对象层级不要过深,否则性能就会差
不需要响应式的数据不要放到 data 中(可以用 Object.freeze() 冻结数据)
v-if 和 v-show 区分使用场景
computed 和 watch 区分使用场景
v-for 遍历必须加 key,key 最好是 id 值,且避免同时使用 v-if
大数据列表和表格性能优化 - 虚拟列表 / 虚拟表格
防止内部泄漏,组件销毁后把全局变量和事件销毁
图片懒加载
路由懒加载
第三方插件的按需引入
适当采用 keep-alive 缓存组件
防抖、节流运用
服务端渲染 SSR or 预渲染
借助webpack的import实现异步组件
适当采用 keep-alive 缓存组件,避免重复创建组建实例保留缓存组件状态
v-for循环数组和对象
v-model实现数据的双向绑定
v-html可以解析文本和标签
v-text只能解析文本
v-bind响应并更新dom特性
v-on监听DOM事件
V-if
V-show
用watch监听路由的变化,让组件做出对应更改
computed支持缓存,相依赖的数据发生改变才会重新计算;watch不支持缓存,只要监听的数据变化就会触发相应操作
computed不支持异步,当computed内有异步操作时是无法监听数据变化的;watch支持异步操作
computed属性的属性值是一函数,函数返回值为属性的属性值,computed中每个属性都可以设置set与get方法。
watch监听的数据必须是data中声明过或父组件传递过来的props中的数据,当数据变化时,触发监听器
答:created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。
mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。
权限有按钮权限和页面权限
页面权限后端把所有的路由信息通过前端的菜单页面保存到数据库,用户登陆后根据不同的角色去查询访问到的页面返回给前端,前端通过addRoute动态添加路由信息
按钮权限通常是一个指令v-permission,在mounted中判断当前用户角色和按钮是否存在交集 存在就显示
一般要实现按钮权限控制都是使用封装指令 v-permission 指令,但是类似“Tabs”这类组件不能使用 v-permission 指令实现权限控制。
v-permission 底层是实现 dom 的删除,而不是像 el-tab-pane 这种组件删除,这种组件后面渲染可能会产生更多的 dom 或者是容器。所以,这种可以使用 v-if 来删除
定义一个变量来判断是否有权限
Tree shaking 是一种通过清除多余代码方式来优化项目打包体积的技术
Tree shaking是基于ES6模板语法(import与exports),主要是借助ES6模块的静态编译思想,在编译时就能确定模块的依赖关系,以及输入和输出的变量
编译阶段利用ES6 Module判断哪些模块已经加载
判断那些模块和变量未被使用或者引用,进而删除对应代码
ssr全称server side render, 前端页面的产生是由服务器端生成的,我们就称之为服务端渲染。SSR执行流程:浏览器加载html文件 -> 服务端装填好内容 -> 返回浏览器渲染
SPA就是CSR客户端渲染client side render, CSR执行流程:浏览器加载html文件 -> 浏览器下载js文件 -> 浏览器运行vue代码 -> 渲染页面
使用SSR的好处?
一.对SEO有利:搜索引擎的爬虫爬取你的页面信息,因为大多数爬虫并不支持等待前端获取数据后再爬取数据的,而有了SSR以后,这些抓取工具就可以立刻得到完整的HTML结构化数据,从而被纳入搜索引擎。
二.更短的白屏时间:服务端渲染并不需要加载和执行大量的js脚本, 直接渲染服务端给出的html字符串, 从而缩短首屏加载时间
不好的地方: 前后端分工搭配复杂, 原本一个页面, 同时由前后端绘制填充
vue.extend可以创建一个组件的构造函数,这个构造函数可以继承父级组件的数据和方法,也可以添加自己的属性和方法,然后用这个构造函数去创建一个子组件
1.组件复用
2.自定义指令
会改变原数组:
pop (删除数组的最后一个元素并返回删除的元素)
push(向数组的末尾添加一个或更多元素,并返回新的长度)
shift(删除并返回数组的第一个元素)
unshift(向数组的开头添加一个或更多元素,并返回新的长度)
reverse(反转数组的元素顺序)
sort(对数组的元素进行排序)
splice(用于插入、删除或替换数组的元素)
不会改变原数组:
concat—连接两个或更多的数组,并返回结果。
every—检测数组元素的每个元素是否都符合条件。
some—检测数组元素中是否有元素符合指定条件。
filter—检测数组元素,并返回符合条件所有元素的数组。
indexOf—搜索数组中的元素,并返回它所在的位置。
join—把数组的所有元素放入一个字符串。
lastIndexOf—返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。
map—通过指定函数处理数组的每个元素,并返回处理后的数组。
slice—选取数组的的一部分,并返回一个新数组。
valueOf—返回数组对象的原始值
git init 初始化仓库
git clone 克隆
git status 检查文件状态
git add. 将文件添加到暂存区
git commit -m 描述信息
git pull
git merge
防抖和节流都是防止某一时间频繁触发,但是原理却不一样。
防抖是将多次执行变为只执行一次,节流是将多次执行变为每隔一段时间执行。
防抖(debounce):
search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
节流(throttle):
鼠标不断点击触发,mousedown(单位时间内只触发一次)
监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
基本数据类型:string、number、boolean、undefined、null、Symbol(ES6,符号类型)
引用数据类型:object、array、function
JS数据类型分为基本数据类型和引用数据类型,基本数据类型保存的是值,引用类型保存的是引用地址(this指针)。浅拷贝共用一个引用地址,深拷贝会创建新的内存地址。
1、get请求一般用来请求获取数据
post请求一般作为发送数据到后台,传递数据,创建数据
2、get请求也可以传参到后台,但是传递的参数则显示在地址栏,安全性低,且参数的长度也有限制(2048字符)
post请求则是将传递的参数放在request body中,不会在地址栏显示,安全性比get请求高,参数没有长度限制
3、get请求刷新浏览器或者回退没有影响
post请求则会重新请求一遍
4、get请求可以被缓存,也会保留在浏览器的历史记录中
post请求不会被缓存,也不好保留在浏览器的历史记录中
5、get请求通常是通过url地址请求
post常见的则是form表单请求
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
em 和 rem 相对于 px 更具灵活性,它们都是相对长度单位,它 们之间的区别:em 相对于父元素,rem 相对于根元素。
em: 文本相对长度单位。相对于当前对象内文本的字体尺寸。如果 当前行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体 尺寸(默认 16px)。(相对父元素的字体大小倍数)。
rem: rem 是 CSS3 新增的一个相对单位,相对于根元素(html 元素) 的 font-size 的倍数。作用:利用 rem 可以实现简单的响应式布局, 可以利用 html 元素中字体的大小与屏幕间的比值来设置 font-size 的值,以此实现当屏幕分辨率变化时让元素也随之变化。
(4)vw/vh 是与视图窗口有关的单位,vw 表示相对于视图窗口的宽 度,vh 表示相对于视图窗口高度
vw:相对于视窗的宽度,视窗宽度是 100vw;
vh:相对于视窗的高度,视窗高度是 100vh;
相同点都可以动态控制页面的显示或者隐藏,但本质上是由很大的区别的
v-if按条件是否渲染
v-show条件为假时将DOM设置成display:none
原型作用是让实例可以共享某些数据
原型链是指一个对象继承的所有对
函数内嵌套函数,内部函数被外部函数返回并且保存下来时,就会产生闭包。闭包可以访问外部的变量,但外部的变量不能访问内部的,闭包可以保持对定义时的作用域的引用,使之不能被销毁。
特点:可以重复利用变量,并且这个变量不会被污染全局的一种机制,这个变量是一直保存在内存中,不会被垃圾回收机制和回收。
缺点:闭包多的时候,会消耗内存,导致页面性能的下降,在IE浏览器中会导致内存泄露。
作用:就是保护变量,防止命名冲突,保护作用域
使用场景:防抖,节流,函数嵌套函数避免全局污染。
JS里已经分配内存地址的对象,但由于长时间没有释放或者没办法清除,造成长期占用内存的现象,会让内存资源大幅度的浪费,最终导致运行速度变慢,甚至崩溃的情况。
垃圾回收机制
因素:一些为生命直接赋值的变量,一些未清空的定时器,过度的闭包
Cookie在浏览器和服务器间来回传递,默认关闭浏览器后失效
Sessionstorage仅在当前网页下有效,关闭页面或者浏览器就会被清除
Localstorage需要手动清除,否则将会永久保存
Sessionstorage和loaclstorage的存储空间更大
Sessionstorage和loaclstorage有更多丰富易用的接口
Sessionstorage和loaclstorage各自独立的存储空间
是一个webpack的loader,将可编写的vue组建转换为JavaScript模块
vue文件的一个加载器,将template/js/style转换成js模块。
用途:js可以写es6、style样式可以scss或less、template可以加jade等
js里常用的原型继承和构造函数继承,主要原理是call和apply 可将子级this对象改变成指向父级
又叫事件代理,原理就是利用事件冒泡的机制来实现。
事件委托是把每个子元素事件绑定到父元素身上,只需要给元素的父级绑定一个监听器,当触 发子元素时,事件会冒泡到父元素上,监听器就会被激发。
阻止事件冒泡:event.stopPropagation()
addEventListener(click,函数名,true/false)默认是false事件冒泡。true事件捕获
好处就是减少内存占用
$router主要是路由实例对象包括路由跳转方法,钩子函数
$route为当前路由跳转对象里面可以获取到name,path,query,params(路由信息对象)
传参query(类似get)
params(类似post)
router-link
this.$router.push()
this.$router.replace()同push
this.$router.go()
取参this.$router.params.id
http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议
http和https使用的是完全不同的链接方式,端口号也不一样前者是80后者是443
http连接很简单,是无状态的,https协议是由ssl+http协议构建的可进行加密传输,身份认证的网络协议,比http协议安全
var会变量提升
let声名的变量只在他所在的代码块有效
const声明后不能再修改其指向的目标
同源策略指的是协议,域名,端口相同,同源策略是一种安全协议。一段脚本只能读取来自同一来源的窗口和文档的属性
typeof用来说明变量的数据类型
instanceof判断一个变量是否属于某个对象的实例
beforecreate created beforemount mounted
.prevent提交事件不再重载页面
.stop阻止单机事件冒泡
.self当事件发生在该元素本身而不是子元素的时候会触发
.capture事件监听,事件发生时会调用
可以在钩子函数created beforemount mounted中进行调用,因为这三个钩子函数中data已经创建,可以将服务端返回的数据进行赋值。
提高页面加载速度
用户行为预测
减少默认data的大小
组件化方案
assets文件夹是放静态资源;components是放组件;router是定义路由相关的配置; app.vue是一个应用主组件;main.js是入口文件。
相同点:
assets和static两个都是存放静态资源文件。项目中所需要的资源文件图片,字体图标,样式文件等都可以放在这两个文件下,这是相同点
不相同点:
assets中存放的静态资源文件在项目打包时,也就是运行npm run build时会将assets中放置的静态资源文件进行打包上传,代码格式化。而压缩后的静态资源文件最终也都会放置在static文件中跟着index.html一同上传至服务器。
static中放置的静态资源文件就不会要走打包压缩格式化等流程,而是直接进入打包好的目录,直接上传至服务器。
建议:将项目中template需要的样式文件js文件等都可以放置在assets中,走打包这一流程。减少体积。而项目中引入的第三方的资源文件如iconfoont.css等文件可以放置在static中,因为这些引入的第三方文件已经经过处理,我们不再需要处理,直接上传。
答:delete只是被删除的元素变成了 empty/undefined 其他的元素的键值还是不变。Vue.delete 直接删除了数组 改变了数组的键值。
安装动态懒加载所需插件;使用CDN资源;异步组件;优化组件加载时机
cdn是指⼀种通过互联⽹互相连接的电脑⽹络系统,利 ⽤最靠近每位⽤户的服务器,更快、更可靠地将⾳乐、图⽚、视频、应⽤程序及其他⽂件发送给⽤户, 来提供⾼性能、可扩展性及低成本的⽹络内容传递给⽤户。
CDN⼀般会⽤来托管Web资源(包括⽂本、图⽚和脚本等),可供下载的资源(媒体⽂件、软件、⽂档 等),应⽤程序(⻔户⽹站等)。使⽤CDN来加速这些资源的访问。
Vue路由在Android机上有问题,babel问题,安装babel polypill插件解决。
用法:query要用path来引入,params要用name来引入,接收参数都是类似的,分别是this. r o u t e . q u e r y . n a m e 和 t h i s . route.query.name和this. route.query.name和this.route.params.name。
url地址显示:query更加类似于我们ajax中get传参,params则类似于post,说的再简单一点,前者在浏览器地址栏中显示参数,后者则不显示
注意点:query刷新不会丢失query里面的数据
params刷新 会 丢失 params里面的数据。
使用vue开发时,在vue初始化之前,由于div是不归vue管的,所以我们写的代码在还没有解析的情况下会容易出现花屏现象,看到类似于{{message}}的字样,虽然一般情况下这个时间很短暂,但是我们还是有必要让解决这个问题的。
首先:在css里加上[v-cloak] {
display: none;
}。
如果没有彻底解决问题,则在根元素加上style=“display: none;” :style=“{display: ‘block’}”
push();pop();shift();unshift();splice(); sort();reverse()
cli2版本:将 config/index.js 里的 assetsPublicPath 的值改为 ‘./’ 。
build: {
…
assetsPublicPath: ‘./’,
…
}
cli3版本:在根目录下新建vue.config.js 文件,然后加上以下内容:(如果已经有此文件就直接修改)
module.exports = {
publicPath: ‘’, // 相对于 HTML 页面(目录相同) }
一般 created/beforeMount/mounted 皆可.比如如果你要操作 DOM , 那肯定 mounted 时候才能操作
1.原型链继承
让一个构造函数的原型是另一个类型的实例,那么这个构造函数new出来的实例就具有该实例的属性。
优点:写法简单易理解
缺点:对象实例共享所有继承的属性和方法。无法向父类构造函数传参
2.构造函数继承
在子类型构造函数的内部调用父类型构造函数,使用apply()或call()方法将父对象的构造函数绑定在子对象上。
优点:解决了原型链实现继承的不能传参的问题和父类的原型共享的问题。
缺点:借用构造函数的缺点是方法都在构造函数中定义, 因此无法实现函数复用。
在父类型的原型中定义的方法,对子类型而言也是不可见的,结果所有类型都只能使用构造函数模式。
3.组合继承
将原型链和构造函数的组合到一块,使用原型链实现对原型属性和方法的继承,而通过构造函数来实现对实例的继承。这样,既通过了原型在定义方法实现了函数复用,又能保证每一个实例都有自己的属性。
优点:解决了原型链继承和构造函数继承造成的影响
缺点:无论在什么情况下,都会调用两次父类构造函数,一次是在创建子类原型的时候,另一次是在子类构造函数内部
4.ES6、Class实现继承
class通过extends关键字实现继承,其实质是创造出父类的this对象,然后用子类的构造函数修改this子类的构造方法中必须调用super 方法,且只有在调用了super 之后才能使用this, 因为子类的this对象是继承父类的this对像,然后对其进行加工,而super方法表示的是父类的构造函数,用来新建父类的this对象。
vue router中mode默认为hash模式,会有#号,hash模式在单页面应用中切换路由,页面不会刷新,只是hash部分变化,根据hash不同来渲染内容。
history模式下刷新就会导致页面404,服务器无法找到对应的文件,就会404,需要在nginx服务器配置文件
解决方案
1.1、箭头函数的this是定义时决定的,普通函数是看调用方法。
1.2、箭头函数不能成为构造函数
1.3、箭头函数不能使用call、apply、bind来修改this指向
1.4、箭头函数不绑定arguments ,…剩余参数
1.5、箭头函数不具有prototype原型对象,不具有super,不有new
把一切都视为模块:不管是 css、JS、Image 还是 html 都可以互相引用,通过定义 entry.js,对所有依赖的文件进行跟踪,将各个模块通过 loader 和 plugins 处理,然后打包在一起。
按需加载:打包过程中 Webpack 通过 Code Splitting 功能将文件分为多个 chunks,还可以将重复的部分单独提取出来作为 commonChunk,从而实现按需加载。把所有依赖打包成一个 bundle.js 文件,通过代码分割成单元片段并按需加载
WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Sass,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。
Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。告诉webpack要使用哪个模块作为构建项目的起点,默认为./src/index.js
output :出口,告诉webpack在哪里输出它打包好的代码以及如何命名,默认为./dist
Module:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。
Loader:模块转换器,用于把模块原内容按照需求转换成新内容。
Plugin:扩展插件,在 Webpack 构建流程中的特定时机会广播出对应的事件,插件可以监听这些事件的发生,在特定时机做对应的事情。
代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等等
文件优化:压缩 JavaScript、CSS、html 代码,压缩合并图片等
代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载
模块合并:在采用模块化的项目有很多模块和文件,需要构建功能把模块分类合并成一个文件
自动刷新:监听本地源代码的变化,自动构建,刷新浏览器
代码校验:在代码被提交到仓库前需要检测代码是否符合规范,以及单元测试是否通过
自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。
1.使用 webpack 的 production 模式,production 模式是专门用于生产环境的,它会自动开启一些优化,比如代码压缩
2.优化 loader 配置
3.按需加载
4.关闭生产环境的sourceMap
5.CDN优化
1、let 和 const
let 表示申明变量。const 表示申明常量
常量定义了就不能改了。对象除外,因为对象指向的地址没变。
两者都为块级作用
2、模板字符串,定义多行字符串,或者在字符串中嵌入变量。
3、解构,可以将数组或对象“拆包”至一系列变量中
6、箭头函数
7、for of
for of遍历的是键值对中的值
for in遍历的是键值对中的键
8、class类,原型链的语法糖表现形式
9、导入导出
导入improt
导出export default
10、promise
Promise 用于更优雅地处理异步请求。
11、async/await
比promise更好的解决了回调地狱
12、Symbol,新的基本类型
13、Set集合
存储任何类型的唯一值,即集合中所保存的元素是不重复的。类数组结构。
let arrNew = new Set(待去重的数组)
14、Object.keys()方法,获取对象的所有属性名或方法名
15、Object.assign ()原对象的属性和方法都合并到了目标对象
1.forEach()
1)对数组进行遍历循环,对数组中的每一项运行给定函数。
2)这个方法没有返回值。参数都是function类型,默认有传参,参数分别为:遍历的数组内容;第对应的数组索引,数组本身。
2.map()
1)指“映射”,对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。
2)必须要return,返回一个新数组
3.filter()
1)“过滤”功能,数组中的每一项运行给定函数,返回满足过滤条件组成的数组。
4.some()
1)判断数组中是否存在满足条件的项,只要有一项满足条件,就会返回true。
Promise.all()子任务是并发执行的,适用于前后没有依赖关系的,可以将多个实例组装个成一个新实例,成功的时候返回一个成功的数组;失败的时候则返回最先被reject失败状态的值。
适用场景:比如当一个页面需要在很多个模块的数据都返回回来时才正常显示,否则loading。
Promise.race()意为赛跑的意思,也就是数组中的任务哪个获取的块,就返回哪个,不管结果本身是成功还是失败。一般用于和定时器绑定,比如将一个请求和三秒的定时器包装成Promise实例,加入到Promise队列中,请求三秒中还没有回应时,给用户一些提示或相应的操作。
微任务:Promise 回调函数,宏任务:setTimeout 回调函数
微任务和宏任务的执行顺序不同,微任务是指在当前任务执行结束后立即执行的任务,宏任务只有在所有微任务执行完毕后才会执行。将一些耗时的操作放入宏任务队列中,从而避免阻塞当前任务的执行,这样可以使页面在执行这些代码的同时仍然保持响应,提高用户体验
一、核心思想不同
Vue是一个灵活易用的渐进式双向绑定的MVVM框架。
React的核心思想是声明式渲染和组件化、单向数据流,React既不属于MVC也不属于MVVM架构。
注:React的单向数据流指的是数据主要从父节点通过props传递到子节点,
如果顶层某个props改变了,React会重新渲染所有的子节点,但是单向数据流并非单向绑定,
React想要从一个组件去更新另一个组件的状态,需要进行状态提升,即将状态提升到他们最近的
祖先组件中,触发父组件的状态变更,从而影响另一个组件的显示。单向数据流的好处是能够保证
状态改变的可追溯性,假如,父组件维护了一个状态,子组件如果能够随意更改父组件的状态,那
么各组件的状态改变就会变得难以追溯
二、组件写法上不同
Vue的组件写法是通过template的单文件组件格式。
React的组件写法是JSX+inline style,也就是吧HTML和CSS全部写进JavaScript中。
三、Diff算法不同
Diff算法是一种对比算法,主要是对比旧的虚拟DOM和新的虚拟DOM,找出发生更改的节点,并只
更新这些接地那,而不更新未发生变化的节点,从而准确的更新DOM,减少操作真实DOM的次数,
提高性能。
vue对比节点,如果节点元素类型相同,但是className不同,认为是不同类型的元素,会进行删
除重建,但是react则会认为是同类型的节点,只会修改节点属性。
vue的列表比对采用的是首尾指针法,而react采用的是从左到右依次比对的方式,当一个集合只
是把最后一个节点移动到了第一个,react会把前面的节点依次移动,而vue只会把最后一个节点
移动到最后一个,从这点上来说vue的对比方式更加高效。
四、响应式原理不同
React的响应式原理
React主要是通过setState()方法来更新状态,状态更新之后,组件也会重新渲染。
componentDidMount:在组件添加到 DOM 后调用。
shouldComponentUpdate:在组件更新之前调用,让你避免不必要的更新。
componentDidUpdate:在组件更新后调用。
componentWillUnmount:在组件从 DOM 中移除之前调用。
// 1. 声明一个以use打头的函数
// 2. 在函数体内封装可复用的逻辑(只要是可复用的逻辑)
// 3. 把组件中用到的状态或者回调return出去(以对象或者数组)
// 4. 在哪个组件中要用到这个逻辑,就执行这个函数,解构出来状态和回调进行使用
//父传子
//1. 父组件传递数据 - 在子组件标签上绑定属性
//2. 子组件接收数据 - 子组件通过props参数接收数据
//子传父
//在子组件中调用父组件中的函数并传递参数
//兄弟传值
// 实现思路: 借助 `状态提升` 机制,通过共同的父组件进行兄弟之间的数据传递
// 1. A组件先通过子传父的方式把数据传递给父组件App
// 2. App拿到数据之后通过父传子的方式再传递给B组件
//跨层级传值
//1. 使用 `createContext`方法创建一个上下文对象Ctx
//2. 在顶层组件(App)中通过 `Ctx.Provider` 组件提供数据
//3. 在底层组件(B)中通过 `useContext` 钩子函数获取消费数据
1. state: 一个对象 存放着我们管理的数据
2. action: 一个对象 用来描述你想怎么改数据
3. reducer: 一个函数 根据action的描述更新state
1. 独立于组件,无视组件之间的层级关系,简化通信问题
2. 单项数据流清晰,易于定位bug
3. 调试工具配套良好,方便调试
1.什么是路由懒加载
路由懒加载是指路由的js资源只有在被访问时才会动态获取,目的是为了优化项目首次打开的时间
2.如何配置路由懒加载
1️⃣ 使用 lazy 方法导入路由组件
2️⃣ 使用内置的 Suspense 组件渲染路由组件