使用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又能触发了