写在前面
本人从事前端4个月以来参与了两个移动端项目,本博文是对移动端项目的经验总结,方便后续查找和翻阅,感谢老大的建议。同时也希望自己的项目经验能够帮助到大家,不足之处,烦请大家批评指正,谢谢大家的支持。
项目总结
1. 移动端适配方案(custom-mobile rem.js)
拿到的蓝湖设计稿默认宽度为750px ,使用rem 布局。在750px宽度的屏幕中,1rem = 100px 。根据不同的手机屏幕和蓝湖设计稿之间的宽度比例,动态地改变1rem 对应的像素值。
//rem.js
//需要在main.js中引入rem.js
! function (window) {
var docWidth = 750;
var doc = window.document,
docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
var recalc = (function refreshRem() {
var clientWidth = docEl.getBoundingClientRect().width;
docEl.style.fontSize = 50 * (clientWidth * 2 / docWidth) + 'px';
return refreshRem;
})();
docEl.setAttribute('data-dpr', window.navigator.appVersion.match(/iphone/gi) ? window.devicePixelRatio : 1);
if (/iP(hone|od|ad)/.test(window.navigator.userAgent)) {
doc.documentElement.classList.add('ios');
if (parseInt(window.navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/)[1], 10) >= 8)
doc.documentElement.classList.add('hairline');
}
if (!doc.addEventListener) return;
window.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
}(window);
2. 组件化的思想
在vue项目中,使用组件化的思想设计代码,利用props进行传参。
子组件中定义props:
props: {
type: {
required: false,
type: String,
default: 'colorful',
validator: (val) => {
return ['single', 'colorful'].includes(val)
}
}
}
父组件中调用子组件:
<Category type="single" @select-category="selectedCategory" />
3. 字体翻译
使用vue + vue-i18n库进行字体翻译。
4. 样式穿透
使用 & /deep/ .需要修改的类名 进行穿透
<style lang="stylus" scoped>
.artist-detail-wrap
height 2.74rem !important
& /deep/ .van-sticky--fixed
z-index 1 !important
</style>
5. 设置的style样式未生效
stylus对空格敏感,在VS Code中点击空格,将缩进转换为空格。
6.父子组件之间的数据传递
- 父组件调用子组件的方法 父组件中,
<AddToCartButton ref="toCart" :product="detail" :is_show_button="false" />
methods: {
addToCart() {
this.$refs.toCart.togglePopupStatus(true)
}
}
子组件AddToCartButton.vue中,
methods: {
togglePopupStatus(status, is_check_out) {
this.is_select_specifications = false
this.is_show_popup = status
this.is_check_out = is_check_out
},
}
- 子组件传递事件给父组件
子组件:this.$emit('名称',需要传递的参数)
父组件:@名称 - 子组件传数据给父组件 利用props进行传参,详见2. 组件化的思想
7.具有相同id的产品,点击返回到顶部
- 使用路由守卫
beforeRouteUpdate(to, from, next)(此种方式错误,因为路由并未更新) - window.reload(使用该方法,页面会有闪动,用户体验不好)
- document.documentElement.scrollTop = 0(用户体验较好,因为速度很快,肉眼上看不出是滑动上去的)
methods: {
fetchNewProductData(id) {
this.$swiper.slideTo(0)
// 跳转至相同产品
// vue-router路由没有变化 此时reload
if (id === Number(this.$route.params.id)) {
this.$emit('resetSwiperIndex')
document.documentElement.scrollTop = 0
return
}
this.$router.push({ params: { id } })
},
}
8.同步和异步
- 同步:代码按顺序执行,如单线程的JS。
- 异步:代码不按顺序执行,如CSS。
9.一图读懂clientX、offsetX、screenX、pageX之间的区别
10.网页优化
- 图片:
(1)尽量使用jpg,非必要时,对简单、颜色不丰富的图片使用png格式;
(2)可以将png格式转换为png8;
(3)多使用svg、字体图标,如果CSS可以实现图片效果就用CSS,也可以使用webp格式的文件;
(4)使用picture标签,可以选择不同格式的最优图片。 - CSS: (1)针对具有预加载功能的nuxt-link组件,在nuxt.config.js中添加如下代码,全局禁止预加载;
router: {
prefetchLinks: false,
}
(2) 取消使用@import css(此种方式会影响css的并行下载)
- 只有一个@import css,会优先下载这个css。该css文件被下载、解析之后才会去下载另外的css文件;
- 有多个@import css,会导致支援文件下载顺序被打乱,排在@import css后面的js文件可能会优先下载;
- 解决方法:使用link标签的preload方式,预加载css文件,并通过onload实现资源异步加载。
<link href="https://at.alicdn.com/t/font_1181549_5y7691l57ll.css" rel="preload" as="style" onload="this.rel='stylesheet'" />
-
字体: 将ttf格式可以转换为woff2格式,若自定义图标中使用到了woff2文件,可以预加载woff2文件。如果加载方式中使用到了data uri,由于其无法利用浏览器缓存、过大以及阻塞渲染,可以将其转换为data url类型(可以在woff2文件中删掉项目中未使用到的icon,减小woff2文件体积,再将woff2的文件地址传给data url)。
-
PC端的网页优化: 后续再更新,敬请期待
11.VS Code插件
- Auto Rename Tag
- AutoFileName
- Beautify
- Chinese (Simplified) Language Pack for Visual Studio Code
- Code Runner
- Easy LESS
- HTML CSS Support
- language-stylus
- Live Server
- open in browser
- Path Autocomplete
- Prettier
- Simple icons
- Stylus
- Vetur
- View In Browser
- Vue 3 Snippets
- Vue 3 Support - All In One
写在最后
在网上记录和总结项目经验是一件极其有意义的事,死后还能在网上留下足迹,供后人阅读。移动端的项目经验暂且先总结到这里,后续如果有新的移动端项目再继续总结,此后会陆续总结PC端项目经验、JS定制器开发经验、手写promise以及Element UI的Select组件。