编码阶段
不要在模板里面写过多表达式
<template>
<div id="app">
<p>{{ flag?'a:'b' }}</p> //少一点
<button @click="exchange">转换</button>
</div>
</template>
尽量减少 data 中的数据。 data 中的数据都会增加getter 和 setter,会收集对应的watcher,值改变时整个应用会重新渲染,可以使用computed (当新的值需要大量计算才能得到,缓存的意义就非常大)
data后续不使用的数据,使用Object.freeze()。这样可以避免vue初始化时候,做一些无用的操作,从而提高性能。
data(){
return{
//直接调用为浅冻结
list:Object.freeze({'我不需要改变'})
}
}
//深冻结
//Object.freeze()原理
//Object.definedProperty()
Object.defineProperty(person, 'name', {
configurable: false,//能否修改属性的特性
enumerable: false,// 是否可以枚举。默认true
writable: false,// 能否修改属性值。默认true
value: 'xm'// 表示属性的值。访问属性时从这里读取,修改属性时,也保存在这里。
})
//Object.seal()
//实现不能删除,不能新增对象属性
function myFreeze(obj) {
if (obj instanceof Object) {
Object.seal(obj);
let p;
for (p in obj) {
if (obj.hasOwnProperty(p)) {
Object.defineProperty(obj, p, {
writable: false
});
myFreeze(obj[p]);
}
}
}
}
对象层级不要过深,否则性能就会差
computed 和 watch 区分使用场景
- v-if 和 v-for 不能连用
当和 v-for 一起使用时,v-for 的优先级比 v-if 更高;
<div v-for="item in list"
v-if="item .show"
:key="item.id">
</div>
//每一次都这样运算
this.list.map( item=> {
if (item.active) {
return item.name
}
});
//解决办法
//1.使用空标签 template.
<template v-for="item in list" >
<div v-if="show" :key="item .id">
{{item.name}}
</div >
</template>
//2.使用compted过滤属性
computed:{
items:function(){
return this.list.filter(item=>{
return item.show
})
}
}
SPA 页面采用 keep-alive 缓存组件 两个生命周期钩子:activated 与 deactivated activated在组件第一次渲染时会被调用,之后在每次缓存组件被激活时调用 deactivated:组件被停用(离开路由)时调用 注意:使用了keep-alive就不会调用beforeDestroy(组件销毁前钩子)和destroyed(组件销毁),因为组件没被销毁,被缓存起来了。
mounted: function() {
this.loaddata(1)
},
activated: function () {
this.productclass.name=""//查询条件
this.loaddata(1) //查询结果的方法
}
频繁切换的使用 v-show,不频繁切换的使用 v-if v-for 遍历必须加 key,key 最好是 id 值,且避免同时使用 v-if key存在意义:为了跟踪每个节点的特征,使其具有唯一性,高效更新虚拟dom vue在更新已经渲染的元素序列时,会采用就地复用策略,都会在对顺序进行破坏时,不仅会产生真实dom更新,浪费资源,耿永导致产生错误更新。 比如两个inputAB输入值,在头部添加一个InputC,结果按顺序,CA有值,B无值。
使用路由懒加载、异步组件 路由懒加载
{ path:'./about', name:'About', component:() => import('../views/Aboout.vue')//在此处引入为懒加载 }
只有在使用该路由时才加载路由。可缩减首屏加载时间。
搜索引擎 SEO 优化
预渲染
vue是一个单页面应用(spa),只有一个 html 文件(内容只有一个#app根节点),通过加载js脚本来填充页面要渲染的内容,然而这种方式无法被爬虫和百度搜索到。 构建阶段生成匹配预渲染路径的 html 文件(注意:每个需要预渲染的路由都有一个对应的 html)。构建出来的 html 文件已经有静态数据,需要ajax数据的部分未构建
解决问题
SEO:单页应用的网站内容是根据当前路径动态渲染的,html 文件中往往没有内容,网络爬虫不会等到页面脚本执行完再抓取; 弱网环境:当用户在一个弱环境中访问你的站点时,你会想要尽可能快的将内容呈现给他们。甚至是在 js 脚本被加载和解析前; 低版本浏览器:用户的浏览器可能不支持你使用的 js 特性,预渲染或服务端渲染能够让用户至少能够看到首屏的内容,而不是一个空白的网页。
//1.安装预渲染插件
npm install prerender-spa-plugin -D #安装或者编译出错,npm换成cnpm
//一个 webpack 插件用于在单页应用中预渲染静态 html 内容。因此,该插件限定了你的单页应用必须使用 webpack 构建,且它是框架无关的,无论你是使用 React 或 Vue 甚至不使用框架,都能用来进行预渲染。
//原理:在 webpack 构建阶段的最后,在本地启动一个 phantomjs,访问配置了预渲染的路由,再将 phantomjs 中渲染的页面输出到 html 文件中,并建立路由对应的目录。
//2.配置vue.config.js
const path = require('path')
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
module.exports = {
configureWebpack: {
plugins: [
new PrerenderSPAPlugin({
// 生成文件的路径,与webpack打包一致即可
// 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。
staticDir: path.join(__dirname, 'dist'),
// 需要预渲染的路由
// 对应自己的路由文件
routes: ['/', '/about'],
// 这个很重要,如果没有配置这段,也不会进行预编译
renderer: new Renderer({
inject: {
foo: 'bar'
},
//renderer.headless为表示是否以无头模式运行,无头即不展示界面,如果设置为false,则会在浏览器加载页面时候展示出来,一般用于调试
headless: false,
//renderer.renderAfterTime可以让控制页面加载好后等一段时间再截图,保证数据已经都拿到,页面渲染完毕
renderAfterTime: 5000,
// 在 main.js 中 document.dispatchEvent(new Event('render-event')),
//两者的事件名称要对应上。在程序入口执行
renderAfterDocumentEvent: 'render-event',
})
})
]
}
}
//4.修改main.js
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>',
// 添加mounted,不然不会执行预编译
mounted () {
document.dispatchEvent(new Event('render-event'))
}
})
//5.相关路由文件
export default new Router({
<!-- 要用history模式 -->
mode: 'history',
routes
})
//npm run build
看一下生成的 dist 的目录里是不是有每个路由名称对应的文件,有就对了
小知识:seo为啥对vue单页面不友好?
爬虫在爬取的过程中,不会去执行js,所以隐藏在js中的跳转也不会获取到。 vue通过js控制路由然后渲染出对应的页面,而搜索引擎蜘蛛是不会去执行页面的js的,导致搜索引擎蜘蛛只能收录index.html一个页面,在百度中就搜索不到相关的子页面的内容。 我们加载页面的时候,浏览器的渲染包含:html的解析、dom树的构建、cssom构建、javascript解析、布局、绘制,当解析到javascript的时候才回去触发vue的渲染,然后元素挂载到id为app的div上,这个时候我们才能看到我们页面的内容,所以即使vue渲染机制很快我们仍然能够看到一段时间的白屏情况,用户体验不好。 服务端渲染 SSR,nuxt.js 服务端渲染:网页上面呈现的内容在服务器端就已经生成好了,当用户浏览网页时,服务器把这个在服务端生成好的完整的html结构内容响应给浏览器,而浏览器拿到这个完整的html结构内容后直接显示(渲染)在页面上的过程 SSR=> 后端把.vue文件编译成.html文件返回给前端渲染,它的好处就是有利于SEO