使用vue2
https://www.jianshu.com/p/4c5c99abb864
vue-router是可以实现当页应用的工具
路由参数总览
new VueRouter({ routes:[ { path: '/', name: 'Hello', component:{ template: '<div>User</div>' }, children: [ { path: 'profile', component: UserProfile }, { path: 'posts', component: UserPosts } ], redirect:"" } ] })
环境搭建:
npm init --yes //创建默认package.json
安装
npm i vue@2.6.11 vue-router@3.3.4 -S npm i @vue/cli-service@4.4.6 vue-template-compiler@2.6.11 -D npm i html-webpack-plugin@3.2.0 -D
@vue/cli-service //模块基于webpack的 webpack-dev-server又在进行二次开发封装
vue-template-compiler //读取识别vue格式的文件
html-webpack-plugin //指定默认模板 /public/index.html
指定html模板
https://cli.vuejs.org/zh/guide/html-and-static-assets.html#public-%E6%96%87%E4%BB%B6%E5%A4%B9
安装好html-webpack-plugin,在跟目录下创建public/index.html,就默认使用了
//index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="renderer" content="webkit"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <link rel="icon" href="<%= BASE_URL %>favicon.ico"> <title><%= webpackConfig.name %></title> </head> <body> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>
@vue/cli-service
vue项目,打包,开发都是通过命令启动
https://cli.vuejs.org/zh/guide/cli-service.html#%E4%BD%BF%E7%94%A8%E5%91%BD%E4%BB%A4
编辑package.json,添加快捷键:
{ "scripts": { "serve": "vue-cli-service serve", "build": "vue-cli-service build" } }
最基本两个命令是
1,打包 npm run build
2,开发 npm run serve
执行以上两个命令默认都会执行./src/main.js ,说明main.js就是整个项目的入口文件了
新建目录src
创建:/src/main.js //这个就是所有文件的入口
import Vue from 'vue' import VueRouter from 'vue-router' import App from './app.vue' //vue母版页 import Index from './index.vue' //首页html、js Vue.use(VueRouter) var CreateVue = new Vue({ el:'#app', router:new VueRouter({ routes:[ { path: '/', component: Index } ] }), render(createElement){ return createElement(App); }, })
创建:/src/app.vue //视图入口模板
<template> <div id="app"> <router-view/> //所有的html都引入到这里 </div> </template> <script> export default { name: "app" } </script> <style scoped> </style>
<template> <div> 首页 </div> </template> <script> export default { name: "index" } </script> <style scoped> </style>
vue-router模式
有两种模式:hash(默认),history
(1)hash
hash 原理 依靠监听onhashchange事件,获取到#后面的参数,始终都以index.html作为模板页,实现组件切换视图,页面不会去刷新再次请求资源
(2)history
history 模式的原理
H5新推出的两个神器:pushState与replaceState
作用就是将url替换且不刷新,好比挂羊头卖狗肉,http并没有去请求服务器该路径下的资源,缺点就是,一旦刷新就会暴露这个实际不存在的“羊头”,显示404,以下是解决找不到页面的办法。
1,需要后台支持history模式,就需要配置nginx、apache或者IIS,这里以nginx为案例
例如项目地址是:http://localhost:8080/dist/#/
module.exports={ publicPath: '/dist', }
new Router({ mode:'history', base: '/dist' })
location / { try_files $uri $uri/ /dist/index.html; #意思是找不到文件或者目录找到该文件 }
导航钩子 (也就是url)
1.全局的
2.单个路由独享的
3.组件级的
全局:
router.beforeEach((to, from, next) => { //to: Route,代表要进入的目标,它是一个路由对象 // from: Route,代表当前正要离开的路由,同样也是一个路由对象 //next: Function,这是一个必须需要调用的方法,而具体的执行效果则依赖 next 方法调用的参数 }); router.afterEach((to, from) => { // do someting });
路由独享的钩子:
cont router = new VueRouter({ routes: [ { path: '/file', component: File, beforeEnter: (to, from ,next) => { // do someting } } ] });
组建内的导航钩子:
data(){ return(){ } }, beforeRouteEnter(to, from, next) { // do someting // 在渲染该组件的对应路由被 confirm 前调用 }, beforeRouteUpdate(to, from, next) { // do someting // 在当前路由改变,但是依然渲染该组件是调用 }, beforeRouteLeave(to, from ,next) { // do someting // 导航离开该组件的对应路由时被调用 } }, methods:{ }
{ path: '/redirect', component: Layout, hidden: true, children: [ { path: '/redirect/:path(.*)', //import方式引入,只有访问该页面时才会加载该页面资源 component: () => import('@/views/redirect/index') } ] },
同步
以这种方式引入,一开始进入首页时就会全部都加载出来
import Home from '../views/Home.vue' { path: '/redirect/:path(.*)', //import方式引入,只有访问该页面时才会加载该页面资源 component: Home }
跳转方式一: this.$router.push({ name:'guanyu', }) 跳转方式二: <router-link :to="{name:'guanyu'}">关于我们</router-link> 上面的name就是创建路由的name { path: '/about', component: About ,name:'guanyu' }
传参 (页面之间传参)
方式一: params传参 goAbout(){ this.$router.push({ name:'guanyu', //要使用params传参必须使用,name路由跳转才能使用 params:{key:11} }) } <router-link :to="{name:'guanyu',params:{key:11}}">关于我们</router-link> 获取:this.$route.params 优点:可以传大的数据量 缺点:传过来的数据,刷新当前页面参数就被清空 方式二:query传参 <router-link :to="{name:'guanyu',query:{key:11}}">关于我们</router-link> this.$router.push({ name:'guanyu', query:{key:11} }) 获取:this.$route.query 优点:传过来的数据,刷新当前页面参数依然存在 缺点:数据过大会丢失,因为是以get方式提交过来的
公共组件回调
情景:/user/aside导航到 /user/foo,如果加载了公共组件例如<header></header>
因为两个路由都渲染同个组件,比起销毁再创建,复用则更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。
<header></header>组件生命周期钩子created和mounted都不会调用。
但是有些业务逻辑,是需要根据不同路径执行不同业务。
//在header组件添加 watch: { $route: { handler: function(route) { console.log(route) }, immediate: true, deep: true, } },
或者
编辑/src/App.vue (推荐)
<router-view :key="key" /> //添加:key="key" computed: { key() { return this.$route.path } }
有点类似在url加版本上就可以清除缓存,每次跳转,即使加载同一个组件,
也会每次都会去加载渲染,这样created和mounted又能触发了