vue
1. 是什么
是一套构建用户界面的渐进式的自底向上增量开发MVVM框架,Vue 的核心库只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。
渐进式:
可以在原有大系统的上面,把一两个组件改用vue实现,也可以整个用vue全家桶开发,不会做职责之外的事
自底向上增量开发的设计先写一个基础的页面,把基础的东西写好,再逐一去添加功能和效果,由简单到繁琐的这么一个过程。
2. 目的
- 解决数据绑定问题
- Vue.js主要的目的是为了开发大型单页面应用。
- 支持组件化,也就是可以把页面封装成为若干个组件,把组件进行拼装,这样是让页面的复用性达到最高。
3. 对于MVVM的理解?
MVVM 是 Model-View-ViewModel 的缩写。
Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。
View 代表UI 组件,它负责将数据模型转化成UI 展现出来。
ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View 和 Model的对象,连接Model和View。
在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
4. Vue实现数据双向绑定的原理
vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。
5. 生命周期
beforeCreate:(创建前) 在数据观测和初始化事件还未开始
created:(创建后)完成数据观测,属性和方法的运算,初始化事件, e l 属 性 还 没 有 显 示 出 来 ∗ ∗ b e f o r e M o u n t ∗ ∗ : ( 载 入 前 ) 在 挂 载 开 始 之 前 被 调 用 , 相 关 的 r e n d e r 函 数 首 次 被 调 用 。 实 例 已 完 成 以 下 的 配 置 : 编 译 模 板 , 把 d a t a 里 面 的 数 据 和 模 板 生 成 h t m l 。 注 意 此 时 还 没 有 挂 载 h t m l 到 页 面 上 。 ∗ ∗ m o u n t e d ∗ ∗ : ( 载 入 后 ) 在 e l 被 新 创 建 的 v m . el属性还没有显示出来 **beforeMount**:(载入前) 在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。 **mounted**:(载入后) 在el 被新创建的 vm. el属性还没有显示出来∗∗beforeMount∗∗:(载入前)在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。∗∗mounted∗∗:(载入后)在el被新创建的vm.el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。
beforeUpdate:(更新前) 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
updated:(更新后) 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
beforeDestroy:(销毁前) 在实例销毁之前调用。实例仍然完全可用。
destroyed:(销毁后) 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。
6. 什么是vue生命周期?
Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。
7. vue生命周期的作用是什么?
它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。
8. 生命周期总共有几个阶段?
它可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后。
9. 第一次页面加载会触发哪几个钩子?
会触发 下面这几个beforeCreate, created, beforeMount, mounted 。
10. DOM 渲染在 哪个周期中就已经完成?
答:DOM 渲染在 mounted 中就已经完成了。
11. vue常用的修饰符?
.prevent: 提交事件不再重载页面;
.stop: 阻止单击事件冒泡;
.self: 当事件发生在该元素本身而不是子元素的时候会触发;
.capture: 事件侦听,事件发生的时候会调用
12. 什么是vue的计算属性?
在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可能多次使用的情况下,尽量采取计算属性的方式。
好处:
- 使得数据处理结构清晰;
- 依赖于数据,数据更新,处理结果自动更新;
- 计算属性内部this指向vm实例;
- 在template调用时,直接写计算属性名即可;
- 常用的是getter方法,获取数据,也可以使用set方法改变数据;
- 相较于methods,不管依赖的数据变不变,methods都会重新计算,但是依赖数据不变的时候computed从缓存中获取,不会重新计算。
13. Vue 组件中 data 为什么必须是函数
在 new Vue() 中,data 是可以作为一个对象进行操作的,然而在 component 中,data 只能以函数的形式存在,不能直接将对象赋值给它。因为对象是引用数据类型,如果不用function返回,那么每个组件的data都是内存中的同一个地址,一个数据改变了其他也改变了;data是一个函数时,每个组件实例都有自己的作用域,每个实例相互独立,不会相互影响
14. 计算属性和watch的区别
computed计算属性是用来声明式的描述一个值依赖了其它的值。当你在模板里把数据绑定到一个计算属性上时,Vue 会在其依赖的任何值导致该计算属性改变时更新 DOM。这个功能非常强大,它可以让你的代码更加声明式、数据驱动并且易于维护。
watch监听的是你定义的变量,当你定义的变量的值发生变化时,调用对应的方法。
14. prop 验证,和默认值
我们在父组件给子组件传值得时候,为了避免不必要的错误,可以给prop的值进行类型设定,让父组件给子组件传值得时候,更加准确,prop可以传一个数字,一个布尔值,一个数组,一个对象,以及一个对象的所有属性。
组件可以为 props 指定验证要求。如果未指定验证要求,Vue 会发出警告
比如传一个number类型的数据,用defalt设置它的默认值,如果验证失败的话就会发出警告。
15. vue中 key 值的作用
使用key来给每个节点做一个唯一标识
key的作用主要是为了高效的更新虚拟DOM。
16. 嵌套路由怎么定义?
在实际项目中我们会碰到多层嵌套的组件组合而成,但是我们如何实现嵌套路由呢?因此我们需要在 VueRouter 的参数中使用 children 配置,这样就可以很好的实现路由嵌套。
17. vue-router有哪几种导航钩子?
三种
- 全局导航钩子:router.beforeEach(to,from,next),作用:跳转前进行判断拦截。
- 组件内的钩子
- 单独路由独享组件
vuex
1. vuex的State特性是?
- Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于与一般Vue对象里面的data
- state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新
- 它通过mapState把全局的 state 和 getters 映射到当前组件的 computed 计算属性中
2. vuex的Getter特性是?
- getters 可以对State进行计算操作,它就是Store的计算属性
- 虽然在组件内也可以做计算属性,但是getters 可以在多组件之间复用
- 如果一个状态只在一个组件内使用,是可以不用getters
3. vuex的Mutation特性是?
- Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作
4. Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中?
- 如果请求来的数据是不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入vuex 的state里。
- 如果被其他地方复用,这个很大几率上是需要的,如果需要,请将请求放入action里,方便复用,
5. 什么是JSX?
JSX 是JavaScript XML 的简写。是 React 使用的一种文件,它利用 JavaScript 的表现力和类似 HTML 的模板语法。这使得 HTML 文件非常容易理解。
6. 为什么浏览器无法读取JSX?
浏览器只能处理 JavaScript 对象,而不能读取常规 JavaScript 对象中的 JSX。所以为了使浏览器能够读取 JSX,首先,需要用像 Babel 这样的 JSX 转换器将 JSX 文件转换为 JavaScript 对象,然后再将其传给浏览器。
7. vuex有哪几种属性?
有五种,分别是 State、 Getter、Mutation 、Action、 Module
8. vuex的State特性是?
- Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于与一般Vue对象里面的data
- state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新
- 它通过mapState把全局的 state 和 getters 映射到当前组件的 computed 计算属性中
9. vuex的Getter特性是?
- getters 可以对State进行计算操作,它就是Store的计算属性
- 虽然在组件内也可以做计算属性,但是getters 可以在多组件之间复用
- 如果一个状态只在一个组件内使用,是可以不用getters
10. vuex的Mutation特性是?
- Action 类似于 mutation
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作
11. Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中?
- 如果请求来的数据是不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入vuex 的state里。
- 如果被其他地方复用,这个很大几率上是需要的,如果需要,请将请求放入action里,方便复用,并包装成promise返回,在调用处用async await处理返回的数据。如果不要复用这个请求,那么直接写在vue文件里很方便。
12. 不用Vuex会带来什么问题?
- 可维护性会下降,你要想修改数据,你得维护三个地方
- 可读性会下降,因为一个组件里的数据,你根本就看不出来是从哪来的
- 增加耦合,大量的上传派发,会让耦合性大大的增加,本来Vue用Component就是为了减少耦合,现在这么用,和组件化的初衷相背。
13. 谈谈你对对vuex的理解
1. vuex是什么?
vuex是一个专为vue.js应用程序开发的状态管理模式(它采用集中式存贮管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化)。
2. vuex的核心概念;
- vuex的属性;
vuex五大核心属性:state,getter,mutation,action,module
- state:存储数据,存储状态;在根实例中注册了store 后,用 this.$store.state 来访问;对应vue里面的data;存放数据方式为响应式,vue组件从store中读取数据,如数据发生变化,组件也会对应的更新。
- getter:可以认为是 store 的计算属性,它的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
- mutation:更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。
- action:包含任意异步操作,通过提交 mutation 间接更变状态。
- module:将 store 分割成模块,每个模块都具有state、mutation、action、getter、甚至是嵌套子模块。
- vuex的数据传递流程;
当组件进行数据修改的时候我们需要调用dispatch来触发actions里面的方法。actions里面的每个方法中都会有一个commit方法,当方法执行的时候会通过commit来触发mutations里面的方法进行数据的修改。mutations里面的每个函数都会有一个state参数,这样就可以在mutations里面进行state的数据修改,当数据修改完毕后,会传导给页面。页面的数据也会发生改变。
3. 为什么要用vuex?
由于传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致代码无法维护。所以我们需要把组件的共享状态抽取出来,以一个全局单例模式管理。在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!另外,通过定义和隔离状态管理中的各种概念并强制遵守一定的规则,我们的代码将会变得更结构化且易维护。
axios
1. axios的特点有哪些?
- Axios 是一个基于 promise 的 HTTP 库,支持promise所有的API
- 它可以拦截请求和响应
- 它可以转换请求数据和响应数据,并对响应回来的内容自动转换成 JSON类型的数据
- 安全性更高,客户端支持防御 XSRF
2. axios有哪些常用方法?
- axios.get(url[, config]) //get请求用于列表和信息查询
- axios.delete(url[, config]) //删除
- axios.post(url[, data[, config]]) //post请求用于信息的添加
- axios.put(url[, data[, config]]) //更新操作
3. 说下你了解的axios相关配置属性?
url
是用于请求的服务器URL
method
是创建请求时使用的方法,默认是get
baseURL
将自动加在url
前面,除非url
是一个绝对URL。它可以通过设置一个baseURL
便于为axios实例的方法传递相对URL
transformRequest
允许在向服务器发送前,修改请求数据,只能用在’PUT’,'POST’和’PATCH’这几个请求方法
headers
是即将被发送的自定义请求头
promise
1. 什么是Promise
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理,让开发者不用再关注于时序和底层的结果。Promise的状态具有不受外界影响和不可逆两个特点。
2. 传统的回调式异步操作有什么缺点
- 调用回调太早
- 调用回调过晚(或没有被调用)
- 调用回调次数过少或过多
- 未能传递所需的环境和参数
- 吞掉可能出现的错误和异常
3. Promise的解决办法:
- 调用回调过早
对于Promise来说,即使是立即完成的Promise也无法被同步观察到,也就是说一个Promise调用then()的时候,即使这个Promise已经决议了,提供给then的回调也总会被异步调用。
- 调用回调过晚(或没有被调用)
对于一个Promise对象注册的每一个观察回调都是相对独立、互不干预的。而Promise对象调用resolve()和reject()时,每个注册的观察回调也都会被自动调度。所以这些观察回调的任意一个都无法影响或延误对其他回调的调用。
- 调用回调次数过少或过多
Promise的定义方式使得它只能被决议一次。即使代码中出现多次决议,这个Promise也会接受第一次决议,并会忽略掉其他任何后续调用。所以任何通过then()注册的回调只会被调用一次。
- 未能传递所需的环境和参数
凡是被决议的值都会传递到观察回调中,如果没有显示的决议值也会传递一个undefined给观察回调。需要注意的是,Promise只允许传一个决议值,其他值将会被默默忽略掉。
- 吞掉可能出现的错误和异常
如果在创建Promise时,存在JavaScript代码错误,会直接导致该Promise的拒绝决议,那么你可以通过reject()来捕获异常,代码中的任何异常都不会吞掉。
4. Promise.all()和Promise.race()的区别
- all会将传入的数组中的所有promise全部决议以后,将决议值以数组的形式传入到观察回调中,任何一个promise决议为拒绝,那么就会调用拒绝回调。
- race会将传入的数组中的所有promise中第一个决议的决议值传递给观察回调,即使决议结果是拒绝。
5. 如果向Promise.all()和Promise.race()传递空数组,运行结果会有什么不同?
- all会立即决议,决议结果是fullfilled,值是undefined
- race会永远都不决议,程序卡住……
6. 如何确保一个变量是可信任的Promise(Promise.resolve方法传入不同值的不同处理有哪些)
- 可以通过Promise.resolve()方法对不确定的值进行Promise化,返回一个Promise对象。
- 如果是一个立即值,如一个普通变量,那么该Promise会立即决议为成功。
- 如果是一个Promise值,那么会将该Promise直接返回赋值给这个Promise,不会有额外开销。
- 如果是一个类Promise值, 比如其中含有名称为then的成员变量,那么会将then展开形成一个新的Promise对象。
7. Promise是如何捕获异常的?与传统的try/catch相比有什么优势?
- 传统的try/catch捕获异常方式是无法捕获异步的异常的。
- 而对于Promise对象来说,构造Promise实例时的代码如果出错,则会被认为是一个拒绝的决议,并会向观察回调中传递异常信息。所以即使是一个异步的请求,Promise也是可以捕获异常的。此外,Promise还可以通过catch回调来捕获回调中的异常。
8. 总结
Promise是一个不错异步操作解决方案,他解决了传统的通过回调和事件来解决异步操作的诸多问题,如“竞争”,回调信任度低的问题。ES6中也提供了标准的Promise供大家使用。
koa
1. 基本用法
- 架设HTTP服务
const Koa = require('koa');
const app = new Koa();
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(3000);
- Content对象
- Koa提供一个Context对象,表示一次对话的上下文(包括HTTP 请求和HTTP回复)。通过加工这个对象,就可以控制返回给用户的内容。
- Context.response.body属性就是发送给用户的内容
- main函数用来设置ctx.response.body。然后app.use方法加载main函数
- ctx.response代表HTTP Response ,同样地ctx.request代表HTTP Request.
- HTTP Response的类型
Koa默认的返回类型是text/plain,如果想返回其他类型的内容,可以利用ctx.request.accepts判断一下,客户端希望接受什么数据(根据HTTP Request的Accept字段),然后使用ctx.response.type指定返回类型。
- 网页模板
实际开发中,返回给用户的网页往往都写成模板文件,我们可以让Koa先读取模板文件,然后将这个模板返回给用户。
- POST请求如何接收
(1)获取POST请求的步骤
解析上下文ctx中的原生node.js对象req。
将POST表单数据解析成query string-字符串。
将字符串转换成JSON格式
(2)ctx.request和ctx.req的区别
ctx.request:是Koa2中的Context经过封装的请求对象,它用起来更直观和简单。
ctx.req:是content提供的node.js原生HTTP请求对象。这个虽然不那么直观,但是可以得到更多的内容,适合我们深度编程。
(3)ctx.method得到请求类型
Koa2中提供了ctx.method属性,可以轻松的得到请求的类型,然后根据请求类型编写不同的相应方法,这在工作中非常常用。
注意,POST必须写成POST,post不可以(必须大写,小写不行)
(4)解析Node原生POST参数
声明一个方法,然后用Promise对象进行解析。这里我们使用了ctx.req.on来接收事件。
(5)POST字符串解析JSON对象
写一个字符串封装JSON兑现对象的方法。
- get请求的接收
query和querystring区别
- 在koa2中GET请求通过request接收,但是接受的方法有两种:query和querystring。
- query:返回的是格式化好的参数对象。
- querystring:返回的是请求字符串
直接从ctx中获取get请求
- 直接在ctx中得到get请求,ctx中也分为query和querystring
总结:获得GET请求的方式有两种,一种是从request中获得,一种是一直从上下文中获得。获得的格式也有两种:query和querystring。
2. 路由
- 原生路由
- 网站一般都有多个页面。通过ctx.request.path可以获取用户请求的路径,由此实现简单的路由
- koa-route模块
原生路由用起来不太方便,我们可以使用封装好的koa-route模块
根路径/的处理函数是main,/about路径的处理函数是about
- 静态资源
如果网站提供静态资源(图片、字体、样式、脚本…),为它们一个个写路由就很麻烦,也没必要。koa-static模块封装了这部分的请求。
- 安装koa-static
npm install --save koa-static
- 新建static文件夹
在static文件夹中让人图片、css和js文件
- 使用koa-static中间件
- 重定向
有些场合,服务器需要重定向(redirect)访问请求。比如,用户登录以后,将他重定向到登录前的页面。ctx.response.redirect()方法可以发出一个302跳转,将用户导向另一个路由
- ctx.request.url
要想实现原生路由,需要得到地址栏输入的路径,然后根据路径的不同进行跳转。用ctx.request.url就可以实现
3. 中间件
- Logger功能
- Koa的最大特色,也是最重要的一个设计,就是中间件(middleware)
- 访问 http://127.0.0.1:3000 ,命令行就会输出日志。
- 1534751382271 GET /
- 上一个例子里面的Logger功能,可以拆分成一个独立函数
- 像上面代码中的logger函数就叫做’中间件’(middleware),因为它处在HTTP Request和HTTP Response中间,用来实现某种中间功能。app.use()用来加载中间件。
- 基本上,Koa所有的功能都是通过中间件实现的,前面例子里面的main也是中间件。每个中间件默认接受两个参数,第一个参数是Context对象,第一个参数是next函数。只要调用next函数,就可以把执行权转交给下一个中间件。
- 中间件栈
- 多个中间件会形成一个栈结构(middle stack),以’先进后出’(first-in-last-out)的顺序执行
- 如果中间件内部调用next函数,那么执行权就不会传递下去
- 异步中间件
- 迄今为止,所有例子的中间件都是同步的,不包含异步操作。如果有异步操作(比如读取数据库),中间件就必须写成async函数
- fs.readFile是一个异步操作,必须写成await fs.readFile(),然后中间件必须写成async函数
- 中间件的合成
koa-compose模块可以将多个中间件合成为一个
- koa-bodyparser中间件
对于POST请求的处理,koa-bodyparser中间件可以把koa2上下文的formData数据解析到ctx.request.body中
- 安装中间件
- 使用npm进行安装,需要注意的是我们这里要用–save,因为它在生产环境中需要使用。
- npm install --save koa-bodyparser@3
- 引入使用
- 安装完成后,需要在代码中引入并使用。我们在代码顶部用require进行引入。
- const bodyParser = require(‘koa-bodyparser’);
- 然后进行使用,如果不使用是没办法调用的,使用代码如下。
- app.use(bodyParser());
- 在代码中使用后,直接可以用ctx.request.body进行获取POST请求参数,中间件自动给我们作了解析。
4. 错误处理
- 500错误
如果代码运行过程中发生错误,我们需要吧错误信息返回给用户。HTTP协定约定这时要返回500状态码。Koa提供了ctx.throw()方法,用来抛出错误,ctx.throw(500)错误。
- 404错误
如果将ctx.response.status设置成404,就相当于ctx.throw(404),返回404错误
- 处理错误的中间件
为了方便处理错误,最好使用try…catch将其捕获。但是,为每个中间件都写try…catch太麻烦,我们可以让最外层的中间件,负责所有中间件的错误处理
- error事件的监听
运行过程中一旦出错,Koa会触发一个error事件。监听这个事件,也可以处理错误
- 释放error事件
- 需要注意的是,如果被try…catch捕获,就不会触发error事件。这时,必须调用ctx.app.emit(),手动释放error事件,才能让监听函数生效。
- main函数抛出错误,被handler函数捕获。catch代码块里面使用ctx.app.emit()手动释放error事件,才能让监听函数监听到
5. Web App的功能
1. Cookies
- ctx.cookies 用来读写Cookie
- ctx.cookies.get(name,[options]) 读取上下文请求中的cookie
- ctx.cookies.set(name,value,[options]) 在上下文中写入cookie
cookie 选项
- domain : 写入cookie所在的域名
- path : 写入cookie所在的路径
- maxAge: cookie最大有效时长
- expires: cookie失效时间
- httpOnly: 是否只用http请求中获得
- overwirte: 是否允许重写
2. 表单
- Web应用离不开处理表单。本质上,表单就是POST方法发送到服务器的键值对。koa-body模块可以用来从POST请求的数据体里面提取键值对。
3. 文件上传
- koa-body 模块还可以用来处理文件上传
- 打开另一个命令行窗口,运行下面的命令,上传一个文件。注意,/path/to/file要更换为真实的文件路径。
vue-server-render
1. 安装
npm install vue-server-renderer
2. API
- createRenderer([rendererOptions])
const renderer = require('vue-server-renderer').createRenderer()
- enderer.renderToString(vm, cb)
将Vue实例呈现为字符串。 回调是一个标准的Node.js回调,它接收错误作为第一个参数:
- renderer.renderToStream(vm)
以流模式呈现Vue实例。 返回一个Node.js可读流。
- createBundleRenderer(bundle, [rendererOptions])
使用预编译的应用程序包创建 bundleRenderer . bundle 参数可以是以下之一:
- 生成的bundle文件( .js或.json )的绝对路径。 文件路径必须以/开头
- 由 vue-ssr-webpack-plugin生成的bundle对象.
- 一个JavaScript代码字符串.
对于每个render调用,代码将使用Node.js的 vm模块在一个新的上下文中重新运行。 这确保您的应用程序状态在请求之间是离散的,并且您不需要担心为了SSR而以限制模式构造应用程序。
- bundleRenderer.renderToString([context], cb)
将捆绑的应用程序复制到字符串。 与renderer.renderToString相同的回调。 可选的上下文对象将被传递到bundle的导出函数。
- bundleRenderer.renderToStream([context])
将捆绑的应用程序呈现到流。 与renderer.renderToStream相同的流。 可选的上下文对象将被传递到bundle的导出函数。
3. 渲染器选项
- 缓存
提供组件缓存实现。 缓存对象必须实现以下接口(使用流标记):
type RenderCache = {
get: (key: string, cb?: Function) => string | void;
set: (key: string, val: string) => void;
has?: (key: string, cb?: Function) => boolean | void;
};
一个典型的用法是传递一个 lru-cache:
const LRU = require('lru-cache')
const renderer = createRenderer({
cache: LRU({
max: 10000
})
})
注意,缓存对象应该至少实现get 和set 。 此外, get和has接受第二个参数作为回调,可以选择异步。 这允许缓存使用异步API,例如redis客户端:
const renderer = createRenderer({
cache: {
get: (key, cb) => {
redisClient.get(key, (err, res) => {
// handle error if any
cb(res)
})
},
set: (key, val) => {
redisClient.set(key, val)
}
}
})
APiCloud
- 优点
APICloud平台文档、视频较多,很适合新手学习,在线社区可以随时问,解答还是蛮快的;
- APICloud平台同时支持安卓和iOS的模块开发,可以自己进行原生模块开发,并应用到APP中。简单、便捷、可根据自己的需求定制。
- 对于移动端开发来说,比较麻烦的就是调试;APICloud有自己的编译器,可通过相同WIFI环境下,与测试机同步
- 支持主流的IDE开发,无需APICloud Studio(APICloud自己的编译器)。
- APICloud自己封装了自己的前端框架,包含的方法比较全,还是挺好用的。