服务器上的window的问题
通过JSDOM来模拟浏览器环境
import * as jsdom from 'jsdom'
const { JSDOM } = jsdom
const resourceLoader = new jsdom.ResourceLoader({
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'
})
const dom = new JSDOM('', {
url: 'http://192.168.10.120:3001/index.template.html',
resources: resourceLoader
})
global.window = dom.window
global.document = window.document
global.navigator = window.navigator
global.sessionStorage = window.sessionStorage
global.location = window.location
global.localStorage = window.localStorage
// @ts-ignore
global.CD = window.CD
// @ts-ignore
window.isNode = true
特殊组件进行客户端渲染
有些组件需要依赖浏览器环境,需要使用vue-no-ssr
插件进行渲染,如富文本,地图等
npm i vue-no-ssr --save
impoer NoSSR form 'vue-no-ssr';
export default {
components: {
'no-ssr': NoSSR
}
}
<no-ssr>
<editor-component></editor-component>
</no-ssr>
服务端渲染HTML标签与客户端不一致
在开发模式下,vue将推断客户端生成的虚拟DOM树,是否与服务器渲染的DOM结构匹配。如果无法匹配,它将退出混合模式,丢弃现有的DOM并从头开始渲染,在生产模式下,此检测会被跳过,以避免性能损耗。
The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.
使用【ssr + 客户端混合】时,需要了解的一件事,浏览器可能会更改的一些特殊的html结构。如
<table>
<tr><td>hi</td></tr>
</table>
浏览器会在table 内部自动注入tbody,然而,由于 Vue 生成的虚拟 DOM (virtual DOM) 不包含 tbody,所以会导致无法匹配。为能够正确匹配,请确保在模板中写入有效的 HTML。
<table>
<tbody>
<tr><td>hi</td></tr>
</tbody>
</table>
node中没有FormData这个类
使用qs.stringify
import qs from 'qs'
const promise = function(fn){
return new Promise((resolve, reject) => {
fn
.then(res => {
resolve(res);
})
.catch(err => {
const errMsg = err.response && err.response.data.msg || ''
reject(errMsg.replace(/[errs]/, '').replace(/[erre]/, ''))
});
});
}
export default {
getData(data) {
return promise(
axios.post('/system/getData', qs.stringify(data))
);
},
}