Vue 生态篇(二)

用户头像
shirley
关注
发布于: 2020 年 06 月 01 日

Vue Router使用场景

传统开发模式

  • www.xxx.com —— index.html

  • www.xxx.com/about —— about.html

  • www.xxx.com/xxx —— xxx.html



单页面(SPA)开发模式

  • www.xxx.com —— index.html

  • www.xxx.com/about —— index.html

  • www.xxx.com/xxx —— index.html

Vue Router解决的问题

  • 监听URL的变化,并在变化前后执行相应的逻辑

  • 不同的URL对应不同的组件

  • 提供多种方式改变 URL 的 API(URL 的改变不能导致浏览器刷新)

Vue Router使用方式

  • 提供一个路由配置表,不同 URL 对应不同组件的配置

  • 初始化路由实例 new VueRouter()

  • 挂载到Vue实例上

  • 提供一个路由占位,用来挂载 URL 匹配到的组件

Vue Router实践

<router-view>:在路由配置列表中,匹配到path对应路径时,开始渲染RouterDemo组件到<router-view>对应位置。

<router-link>:做路由跳转,底层是一个<a>链接。

//main.js
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({
routes,
})
new Vue({
router,
render: h => h(App),
}).$mount('#app')
//app.vue
<template>
<div id="app">
<h2>router demo</h2>
<router-view></router-view>
</div>
</template>
//routers.js
const routes = [
{ path: '/foo', component: RouterDemo, name: '1' },
// 当 /user/:id 匹配成功,
// RouterDemo 会被渲染在 App 的 <router-view /> 中
{ path: '/user/:id',
component: RouterDemo,
name: '3',
//"props: true"说明把动态id作为属性传给RouterDemo
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
}
]
},
//“redirect”路由重定向
{ path: '/a', redirect: '/bar' },
{ path: '*', component: RouterDemo, name: '404' }
]

路由组件写法:

第一种:异步加载

第二种:异步加载,webpackChunkName是打包时候用的,可以理解为它是给webpack的标志,打包的时候会把相同name标志的路由文件打包进一个文件中。

第三种:这里就相当于一个单文件组件 <router-view/> 而单文件组件的templete的本质就是 render。如果不使用render ,就需要写一个单文件组件,而单文件组件的本质就是render函数,单文件组件通过vue loader都会转成render。

第四种:单文件组件

component: resolve => require(["@/layouts/UserLayout"], resolve),
component: () =>import(/* webpackChunkName: "layout" */ "../layouts/UserLayout"),
component: {render: h => h("router-view")},
component: RenderRouterView,



//routerDemo.vue
<template>
<div>
<router-link to="/foo">Go to Foo</router-link>
<br/>
<router-link to="/user/12">Go to /user/12</router-link>
<br/>
<router-link to="/user/12/profile">Go to /user/12/profile</router-link>
<br/>
<router-link to="/other">Go to 404</router-link>
<br/>
<router-link to="/a">Go to a 重定向到 bar</router-link>
<br/>
<a href="#/foo">Go to Foo</a>
<br/>
<button @click="$router.push('foo')">Go to Foo</button>
<p>id: {{id}}</p>
<p>{{routerInfo}}</p>
<router-view></router-view>
</div>
</template>



路由类型

  • Hash模式:丑,无法使用锚点定位。上面例子使用了Hash模式,路由跳转有个#号。

  • History 模式:需要后端配合,IE9 不兼容(可使用强制刷新处理)。



History 模式路由跳转没有#号,可以在声明实例时使用mode: 'history'形式。但是使用强制刷新处理IE9 不兼容问题时,就没法使用单页面形式。正常情况,我们访问www.xxx.com 后端会定位到index.html,但如果访问www.xxx.com/vue 二级目录、三级目录时,也需要后端配合定位到index.html。history模式,需要让后端把所有路径都指向index.html,hash模式则没有这个刚需,只要一个跟路径指向index.html即可,剩下的直接404。

const router = new VueRouter({
mode: 'history',
routes,
})



路由底层原理



路由通过Vue.util.defineReactive这个API把router信息_route变成了一个响应式的。

router-link、$router.push、a href、浏览器前进后退、手动更改URL 会触发源代码中updateRoute,updateRoute里面会去改变响应式数据_route,响应式数据_route改变后会自动触发router-view的更新。router-view会根据URL去匹配相应的组件。

路由底层原理

单页面(SPA)缺点



  • 不利于搜索引擎优化SEO

搜索引擎优化,即百度等搜索引擎爬取网页,并对网页内容进行分析,进行自然搜索排名。单页面内容都是通过接口的形式获取的,index.html仅仅是一个空壳。搜索引擎爬取页面时,是没有任何内容的。不过目前搜索引擎提供付费服务,可以通过购买排名解决。



  • 首屏渲染时间长

index.html仅仅是一个空壳,没有内容的。等JS加载完,再通过接口形式返回内容,然后再去渲染页面,这样会导致页面的白屏时间长。



上面两个问题可以使用服务端渲染SSR 或 预渲染Prerendering解决。

预渲染Prerendering:适用于静态站点,如关于我们about.html、联系我们contact.html等静态页面。

服务端渲染SSR:适用于动态渲染,但是配置繁琐。可以使用Nuxt简化配置。



SSR流程:

打包业务代码时,提供了两个入口文件,一个是供server服务端使用的,一个是供客户端浏览器使用的入口文件。server entry入口文件主要是返回新创建的vue实例,client entry入口文件主要是将vue实例挂载到指定的dom元素上。webpack打包后,会生成两个bundle文件。服务器会根据用户请求,在Node server去生成预渲染的html,然后返回到请求的客户端,完成初始的渲染。此时,页面上已经展示了渲染的效果,但是页面上的一些如点击按钮依旧不可用,这时需要客户端的bundle 进行混合,将html完全由Vue管理,托管我们的动态dom ,使之能响应后续的动态变化。



SSR流程图



小知识点

  1. 在vue中多个.vue组件,引入一个较大的less库,在ie9中,启动后打开页面样式加载不上。可以使用webpack把css文件分成多个文件 低版本浏览器会对单个css文件里面的样式条数有限制。



  1. IE11不支持箭头函数的写法ES6语法,添加polifill 可以让ie支持。

  2. npm i nprogress 安装动画效果库



用户头像

shirley

关注

还未添加个人签名 2019.04.02 加入

还未添加个人简介

评论

发布
暂无评论
Vue生态篇(二)