1.Vue Router的使用场景
传统的开发模式:
www.xxx.com——index.html;
www.xxx.com/about——about.html;
www.xxx.com/xxx——xxx.html.
以前传统的开发就是每个 html 或其他文件对应一个 url,但是每次切换 url 都需要重新加载页面,影响用户体验。
单页面(SPA)开发模式:
www.xxx.com——index.html;
www.xxx.com/about——index.html;
www.xxx.com/xxx——index.html
这种则是不管什么 url 都对应同一个文件(不是很严谨,依然可以定位到不同的文件,只不过没必要)。用户切换 url 不再是重新加载页面,而是通过一些逻辑找到对应接口返回不
同的数据/组件。
解决的问题:
监听URL的变化,并在变化前后执行相应的逻辑;
不同的URL对应不同的不同的组件;
提供多种方式概念URL的API(URL的改变不能导致浏览器刷新)
使用方法:
提供一个路由配置表,不同的URL对应不同组件的配置;
初始化路由实例new VueRouter();
挂载到Vue实例上面;
提供一个路由占位,用来挂载URL匹配的组件
main.js
import Vue from 'vue' import VueRouter from 'vue-router" import App from './App.vue' import routes from './routes' Vue.config.productionTip = false vue.use(VueRouter) const router =new VueRouter( { //mode: 'history', routes, }) new Vue({ router, render: h > h(App), }).$mount('#app')
安装引入使用 Vue router,将路由表写到一个文件里实例化router 的时候把表丢进去就行。
<template> <div id="app"> <h2>router demo</h2> <router-view></router-view> </div> </template> <script> export default{name: 'app',components:{), } </script> <style>#app{ font-family: 'Avenir', Helvetica,Arial, sans-serif;一webkit-font-smoothing: antialiased; 一moz-osx-font-smoothing: grayscale;text-align: center; color:O#2c3e50;margin-top:60px;} </style>
router.js
import RouterDemo from './components/RouterDemo' import RouterChildrenDemo from './components/RouterChildrenDemo' const routes =[ { path: '/foo' , component: RouterDemo,name: '1'}, { path: '/bar' , component: RouterDemo,name: '2'}, //当/user/:id匹配成功, // RouterDemO会被渲染在App的<router-view/>中 { path: '/user/:id', component: RouterDemo, name: '3', props: true, children: [ { //当/user/:id/profile匹配成功, // RouterchildrenDemo会被渲染在 RouterDemo的<router-view/>中 path: 'profile', component: RouterchildrenDemo, name: '3-1' }, { //当/user/: id/posts 匹配成功 // RouterChildrenDemo 会被瀘染在RouterDemo 的<router-view/> 中 path:'posts', component: RouterChildrenDemo } ] } , { path: '/a', redirect:'/bar' }, { path: '*', component: RouterDemo, name: '404' } ] export default routes
我们可以看到路由表引入了两个组件,匹配到对应的路由则使用对应组件,渲染到前面的 router-view 中。 props 的意思是运行动态路由作为一个参数传递给组件,组件通过props:[xxx]接受。路径为 * 是当前面都匹配不到才走的,一般是到 404 页面.
路由跳转可以有 router-link 也可以用 API 的方式($route.xxx)
2.选择什么样的模式的路由和底层原理
路由类型:
Hash模式:丑,没办法使用锚点定位;
History模式:需要后端配合,IE9不兼容(可以使用强制刷新处理)
Url 里面有#就是哈希模式。无法使用锚点定位是因为哈希是在路由。
import Vue from 'vue ' import VueRouter from 'vue- router' import App from ' ./App. vue ' import routes from ' ./ routes' Vue.config. productionTip = false Vue.use (VueRouter) const router = new VueRouter({ node: 'history', routes, }) new Vue({ router, render: h => h(App), }). $mount( '#app' )
解决哈希存在的问题就是改用 history ,只需要在配置表那加 上 mode 为 history 就行。 关于 IE9 的不兼容是可以解决,只不过就无法使用这种单页的形式了。就是当 url 修改的话不再是通过 ajax 拿到数据去渲染而是选择强制刷新当前 url 。
其实路由是通过蓝色那边的 API 把 router 的信息变成一个响应式的,触发 router-view 的更新
3.Nuxt 用来解决什么问题
并不是官方维护的,用的也比较少,实战也不会用,但是可以了解。
SPA 缺点:
不利于SEO;服务端渲染SSR;首次屏渲染时间长;预渲染Prerenderirng
SEO 就是搜索引擎优化(因为内容都是通过接口获取的,搜索引擎爬取我们的网页即 index.html 是没有什么内容的,就很难出现在搜索结果排名中)。 因为我们需要加载数据请求接口所以白屏时间会长一些。解决的方法就是 SSR 和 Prerendering.
静态站点比如联系我们、关于我们等一些不常变动的页面.SSR 的话生命周期钩子一些是不能用的,路由配置、webpack 配置也都有所不同,所以是比较繁琐。
Nuxt:
静态站点;动态渲染;简化配置
Nuxt 就是帮我们解决这些问题。
4.Nuxt核心原理
Nuxt的核心原理是什么,或者是SSR的核心原理/流程是什么?
打包业务代码的时候,提供两个入口文件,一个给服务端使用(返回新创建的 Vue 实例)一个给客户端/浏览器使用(将 Vue 实例挂载到指定的 DOM 上)。 经过 webpack 打包后会生成两个 bundle 文件,服务器的bundle 渲染了 html 什么的到我们页面上,但是具体的点击什么的还要靠客户端的 bundle 混合将 html 完全由 Vue 管理托管为 DOM,响应后续的变化。(所以不管服务端搞什么,客户端都是要渲染的)。
上面是不用 SSR 只返回一个空壳的 html,下面是使用 SSR,根据 url 返回对应字符串什么的给客户端。
5.UI组件库的对比
Element UI、Ant Design Vue、View组件库的对比;
建议是使用单测比较高覆盖率的,这些都是组件库,里面包含一个个组件,然后合起来做一个模板的就是 admin 了。
6.提升开发效率和体验的常用工具
一般有:ESLint、Prettier、Veter、vue-devtools;
Vuter:
- 语法高亮;
- 标签补全、模版生成;
- Lint检查;
- 格式化
这个其实是 vscode 的插件。
ESLint:
- 代码规范;
- 错误检查
安装 eslint 相关的包然后做一下配置(建议开那个被注释了的强烈建议)即可。
Prettier:
- 格式化
可以看到我们配置 eslint 的时候也顺便配了个 prettier 就是防止两者冲突。直接按下保存即可更改。
module.export = { singleQuote:ture, //trailingComma:'all' };
Vue DevTools:
- 集成Vuex
- 可远程调试
- 性能分析
7.单元测试的重要性和使用
开源一般都是要覆盖到所有的代码,底层组件库什么的单测也是很重要,而业务的话可以选择性的单测部分代码。短期来看,单测会影响开发速度,但是后续迭代需求什么的还可以及时更改问题。
重要性:
- 保证研发质量
- 提高项目的稳定性
- 提高开发速度
使用方法:
- jest或mocha
- @vue/test-utils
- sinon
jest 和 mocha 是两个测试运行环境 / 测试运行器,jest 比较全, 配置也比较少。 mocha 是 vue 提供的,比较实用。 sinon 是辅助测试库,不是必要的。vue create 创建一个 test1-demo,选择自定义,勾上 unit Testing 单测,选上 prettier,选择 jest,可以放到独立的文件不要让 package.json 太大.
创建完成我们发现多了一个 tests 文件夹和 jest 的配置,配置的话第一个是指定测试的文件类型,第二个是类似 loade ( r 通过各种包处理我们的一些文件),第三个是要忽略测试的文件,第四个是类似那个指定快捷键符号的(@ 符号),第五个是快照的格式化,第六个是对哪些文件走单测,第七个是给js DOM 使用的,本质上它还是跑在浏览器的环境中。
我们看看给的单测例子,是对 hello 组件的测试, describe 就是定义一个测试集,第一个参数是名称,每一个 it 是单测的最小集,里面第一个参数是名称,第二个就是函数了,里面写我们的校验。里面是用 shallowMount 浅渲染(就是只是渲染这一层,里面还有东西就不管了),正常渲染就是 mount(第一个是组件,第二个是参数)。这个太简单了,我们写一个计数器 Counter.vue 来丰富一下测试,能够加就行了。
建一个属于 counter 的测试,无需接收参数只需要组件渲染后的 html () .toMatchSnapshot ()。生成快照就是自动在文件夹下新建一个快照储存的地方(就无需一个个去 test 了, 如果修改了代码我们再次生成快照就会失败,因为已经与之前的 html 不一样了,所以就很方便对比代码),里面就是具体渲染的内容.
当然单测是可以监听的, run 的时候加上 -- -- watchAll 就会每次修改都自动 watch 。 当然这个还不行,肯定不能只是测试一下我的快照,核心功能是要测试点击后数据的变化,再写一个 it ,要执行点击的话需要找到按钮(通过渲染后组件的 find API ),按钮通过点击触发,然后拿到这个值希望是 xxx 。还希望再复杂一点,在组件那再加一个点击事件,修改 count 值同时$emit 抛出一个事件和参数,回到测试,我们想要监听这个事件是否被抛出了,可以在组件渲染的时候加一个listeners 对象,里面监听抛出的事件,在外面起一个标志位,抛出的事件中改变这个标志位,判断的话是希望我们的标志位被改变了,从而判断是否走了这个事件。 但是如果是想要判断点击的次数,可以在外面定义一个变量来存储,不过这样子不是很友好,我们可以利用刚才提到的辅助库 sinon ,在测试中引入,利用 spy ()生成一个替身指向我们抛出的事件,其它关于事件的就可删掉了,最后是期望事件的 called 为 true 。希望事件的 callCount 次数为 xxx 。