1.先看配置文件package.json,里面定义了这个项目所需要的各个模块,以及项目的配置信息。scripts
指定了运行脚本命令的npm命令行缩写,比如dev指定了运行npm run dev
时所要执行的命令。
2.我拿到的这个项目在开发环境下通过命令npm run dev来启动的,所以我去package.json文件里找到了scripts配置,其中有设置dev选项,也就是说在运行命令
npm run dev时,启动了webpack-dev-server服务,并指定了配置文件webpack.dev.config.js,所以我们接下来就去看webpack.dev.config.js文件。
"scripts": {
"dev": "npm run clean && cross-env NODE_ENV=development webpack-dev-server --config ./config/webpack.dev.config.js"
}
3.看代码不能从第一行开始看,不然看的时候你无法串起来,看完了也不知道在讲啥。这里我看webpack.dev.config.js文件时先看最后输出了什么模块,然后前面肯定是围绕生成这个模块而写的代码,所以我们直接从模块生成的地方开始。里面的一些配置其实根据属性名就能猜出个大概意思,不懂的可以去查官方文档。我这里publicPath还搞得不是很清楚-_-!
4.找到配置文件webpack.dev.config.js中的入口文件,这里是src目录下的index.js文件,其中引入了一些通用的模块,还有一个重置的样式文件reset.css和一个动态适配移动端的js文件viewPort.js,另外,还创建了一个Vue实例
new Vue({
el: '#root',
router,
store,
render: h => h(App)
})
注意,render是一个方法,h = h(App)是ES6的写法,即
render: function(h) {
return h(App);
}
其中h是createElement的一个别名,关于render和JSX的介绍可以看官方文档https://cn.vuejs.org/v2/guide/render-function.html
render函数这个知识点以前还没接触到过呢,今天看了一下Vue官方文档的描述,发现对于现在的我来说还挺难懂的,任重道远呀。但是多看几遍,就会发现其实文档都写的挺清楚的,只不过我这个人好像跟别人逻辑不一样,老是产生不一样的理解,我是不是多了一根筋。。。
5.h(App)以App组件为参数,它是引入的App.vue,所以我们去看看App.vue,
发现这个组件的模板也是用render生成的,而不是用template来创建的。
上面代码用的是JSX语法,关于JSX 映射到 JavaScript,可以参考https://github.com/vuejs/babel-plugin-transform-vue-jsx#usage
而且上面省略了h参数,因为从ES2015开始会自动注入这个参数。
6.上面可以看出把
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './routes.js'
Vue.use(VueRouter)
export default new VueRouter({
routes
})
发现它就只是引用了当前文件夹下的另一个路由js文件routes.js:
export default [
{
path: '/',
redirect: '/mrReading'
},
{
path: '/mrReading',
component: () => import('../views/mrReading/Index.vue')
}
]
这里用匿名函数的形式引入了Index.vue组件,好像跟按需加载有关,https://router.vuejs.org/zh/guide/advanced/lazy-loading.html
7.Index.vue:就是一个普通的首页组件
8.到这我看的这个模块就差不多没了,我想其他的也可以按照这种顺序一步一步来。我再把项目运行起来看下整体效果
viewPort.js:动态适配
const resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
function refreshRem () {
const clientWidth = docEle.getBoundingClientRect().width
docEle.style.fontSize = props.fontSize * (clientWidth / props.width) + 'px'
}
window.addEventListener(resizeEvt, function () {
clearTimeout(refreshRem.tid)
refreshRem.tid = setTimeout(refreshRem, 300)
}, false)
window.addEventListener('pageshow', function (e) {
if (e.persisted) {
clearTimeout(refreshRem.tid)
refreshRem.tid = setTimeout(refreshRem, 300)
}
}, false)
这里监听了横竖屏或者resize事件,注意,这里并不是在一监听到就对它进行调整(refreshRem),而是有一个300ms的延时,因为按照惯例点击一次也是过300ms去响应。
pageshow事件,onpageshow 事件类似于onload事件,onload 事件在页面第一次加载时触发, onpageshow 事件在每次加载页面时触发,可以使用 PageTransitionEvent 对象的 persisted 属性来判断页面是直接从服务器上载入还是从缓存中读取,如果页面从浏览器的缓存中读取该属性返回 true,否则返回 false。所以上述代码实现了当页面是从缓存中读取时就重新调整一次rem基准值。