js 刷新div_vue.js备忘记录(五) vue-router

如果我们采用SPA(单网页应用)的设计方式,服务器会把前端文件一次性发过来,前端通过监听url的改变,选择展示那些内容,也就是前端路由

一. 如何改变url但是页面不刷新?

方式一: 改变哈希值hash

比如,我们随便找一个网页

e6938c9ff993f67bcc3b34ccc110b147.png

我们在浏览器控制台输入

08e96193dfa1764a350598acc59d14e4.png

发现网站的url有了些改变

b02ce224aeb692c2f1753edc95bcc1d6.png

查看network却没有任何请求

97aed763b0beb791f211e388eaf71794.png

方式二 history模式的方法

(1). history.pushState()压栈式

比如,我们随便找一个网页

e6938c9ff993f67bcc3b34ccc110b147.png

我们在浏览器控制台输入

history.pushState({},'','home')

13a6e2c3c405b3f11b6e33e44a21f6bf.png

发现网站的url有了些改变

f239628bf835816411504301052dedcc.png

查看network却没有任何请求

456daa3f3feb5c181af3af512d69e6f1.png

这种压栈式方法,可以使用浏览器返回上一页按钮弹栈,实际上是在调用

history.back()

也可以使用history.go() 操作栈

history.forward()  等价于  history.go(1)
history.back()  等价于  history.go(-1)

(2): history.replaceState()非压栈式

history.replaceState({},'','home')

二. 认识vue-router

1.安装 vue-router

cnpm install vue-router --save

我们也可以在用CLi项目创建时就选择好 vue-router 这样项目创建时会送我们一个hello world的例子,我们可以先体验一下

6d068ca340cd232a53c8f41d7eea7831.png

c9dda600c544042d1d0ba21a832990bc.png

2.创建文件夹router,创建index.js

用来存放我们的路由配置

3.路由创建过程

首先,我们在index.js创建一个vuerouter并暴露

//1.导入VueRouter
import VueRouter from 'vue-router'
//2.导入Vue   (因为后面要用Vue.use())
import Vue from 'vue'//3.通过Vue.use安装一下插件
Vue.use(VueRouter)//4.创建路由对象
routes=[]const router = new VueRouter({routes
})//5.暴露路由对象
export default router

在main.js中,我们挂载这个vuerouter

import Vue from 'vue'
import App from './App.vue'
import router from './router'     //6.导入暴露的vuerouter (/index.js是默认,路径中省略了)Vue.config.productionTip = falsenew Vue({router,      //7. 将导入的router传给自己的router属性render: h => h(App),
}).$mount('#app')

4.配置映射关系

上面的模板中,routes=[], 我们没有配置映射关系, 现在我们来配置一下:

  • 第一步,导入页面组件
  • 第二步,创建映射关系
  • 第三步,在app.vue模板中(上级组件),添加router-link标签,这是一个触发url改变的入口
  • 第四步,在app.vue模板中(上级组件),添加router-view占位符标签,确定请求过来的内容的占位

在router/index.js中

import VueRouter from 'vue-router'
import Vue from 'vue'
import Home from '../components/Home'  //1. 导入第一个组件Home
import About from '../components/About' //1. 导入第二个组件AboutVue.use(VueRouter)
const routes = [{path: '/',       //2.添加映射关系component: Home},{path: '/about',  //2.添加映射关系component: About}
]const router = new VueRouter({routes
})export default router

在App.js中

<template><div id="app"><router-link to="/home">首页</router-link>   <!-- 3.使用路由 通过router-link标签,配置to属性提供链接目标,点击此标签会触发对应的url请求--><router-link to="/about">关于</router-link><!-- 3.使用路由 通过router-link标签,配置to属性提供链接目标,点击此标签会触发对应的url请求--><router-view></router-view><!-- 4.使用路由 通过router-view占位符标签,确定请求过来的内容的占位--></div>
</template><script>
export default {name: 'App',
}
</script><style scoped>
</style>

路由重定向:

const routes = [{path:'',redirect:'home'},
]

5.将默认的哈希方式改为history模式

vue默认是使用hash方式的,

e230520628e10b9bec9395adf9f29e02.png

我们可以给它改成history模式,

这需要,我们在router/index.js中创建VueRouter时传入另一个参数

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

7be7c9b0cd51179fe6960e15073f96c7.png

此外我们在cli初始化项目时,也可以默认history模式

cebb1cfb9eb799b19ec49010ac316ed3.png

6.router-link 属性

  • to属性 :指向的url地址
  • tag属性: 默认是a标签,如果tag='button',则渲染成标签.此外还可以是 <li>等
  • replace属性: 采用非压栈式跳转,不可返回

同时,我们注意到,当某个标签被点击时,他的class会自动添加两个类:router-link-exact-active和router-link-active

45b282e98d592c18077af16e67a4276b.png

有了这两个class,我们可以方便的写样式了

912507bb277abeb3f687d73c17392cfe.png

7. 不用router-link,通过代码修改路径 $router.push

上面的我们都是使用的 <router-link>来触发的url改变 有没有办法用普通的表单元素触发呢?

有的.比如一个button 我们绑定了他的单击事件 btnClick,则我们可以在方法里写:

每个组件都有一个全局对象叫$router,这个

btnClick(){this.$router.push('/home')
}

上面是压栈式,当然也有非压栈式

btnClick(){this.$router.replace('/home')
}

三. 动态路由 /:参数

很多时候我们的url可能是不固定的,访问的页面的具体信息也会随着url改变,这就称之为动态路由. 例如: 我们访问张三的资料 /user/zhangsan 李四的是 /user/lisi

注册动态路由的方法是 /:参数

我们注册映射关系时,这样注册

  {path:"/user/:userId",component:User}

我们触发url时这样触发

//在<router-link>上动态绑定
<router-link :to="'/user/'+userId">用户</router-link> //或者通过普通标签的事件:btnClick(){this.$router.push('/user/'+this.userId)}

那么url跳转后如何在先页面中拿到跳转的参数呢? 用$route

$route   :当前活跃路由 每个组件都有一个全局对象$route
一定要和$router区分开!!!!!

每个组件都有一个$route全局对象 (不是$router,少了一个r)

c457a11a10ae764585863600c11deb0f.png

我们看到这个 对象里有一个属性params ,里面有一个键值对 就是我们想要的,这时我们制作一个计算属性放在我们想显示的位置就好了

  computed: {userId(){return this.$route.params.userId }},

四. 路由的懒加载

当我们打包时,我们的bundle.js会变得特别大,太大的bundle会使得加载变慢,从而出现浏览器空白.但其实即使是单页程序,也无需浪费这段时间,同时给用户不好的体验.我们完全可以使用懒加载,将刚开始用不到的代代码先不加载,等用户触发了相关路由时再加载

懒加载说白了就是不同的路由打包到不同的js里去

9106e87893e00c72c394ed509b9c0041.png

懒加载如何实现??

我们不要在一开始就import 而是在用到的地方,用箭头函数直接匿名import

    path: '/about',  //2.添加映射关系component: ()=>import('../components/About')},

这样,我们可以让首页之外的路由选择懒加载,都懒加载也可以

五. 路由的嵌套

为什么要路由嵌套?看下图:

我们想在home页面请求路由,把路径改为/home/news, 但是页面还是在home页,只不过绿框里的内容改为了news组件的内容

023ec7390fea6cf6a3c9c7e250e4b625.png

如何实现路由嵌套?

5386ab34978de3a620301b9645fd01ce.png

1.映射路由

因为还是在home页面,所以不能直接写路由映射,而是将路由映射嵌套在home的映射中

具体做法是,将子映射写在父映射的children属性里

  {path: '/home',       //这是home的映射component: Home,children:[           //它里面可以定义一个children,里面放子映射{path: '',       //添加默认子映射redirect:'news'},{path: 'news',                   //添加子映射关系 路径只写名字 newscomponent: ()=>import('../components/HomeNews')},{path: 'msgs',                   //添加子映射关系component: ()=>import('../components/HomeMsg')},]},

接下来我们在home.vue中确定显示位置 路径照实写

<template><div><h2>我是首页</h2><p>我是首页内容</p><router-link to="/home/news">看看新闻</router-link><router-link to="/home/msgs">看看消息</router-link><router-view></router-view></div>
</template><script>
export default {name: "Home"
};
</script><style scoped>
</style>

六. 传递参数的路由

传递参数的两种方式

  • 配置动态路由 /router/:参数
  • query类型的传递 请求路径还是/router 但是同时会传一个query,如: /router?id=123

如果只需要传递一个符号,则选择第一种,如果信息较多,传递第二种

第一种我们之前已经接触了,现在看

1. 如何用query传递参数

只需要在<router-link> 的to属性里绑定一个对象,对象有如下属性:

<router-link :to="{path:'/profile',     <--path属性还是路由链接-->query:{              <--query属性里面传入一个对象,对象里都是键值对--> id:'lili',age:20,gender:'girl'}}">Profile</router-link>

新页面里如何取?还是用之前用过的$route对象

this.$route.query

2.不用<router-link>怎么传query??

$router.push和$router.replace传入上述对象即可

  methods: {btnClick(){this.$router.push({path:'/profile',query:{name:"lili",age:18,gender:'girl'}})}}

七. keep-alive

一个页面如果跳转到了另一个页面,那么这个页面会被销毁,此时如果用户又返回这个页面,又需要重新加载.

keep-alive主要解决离开页面又返回时,页面需要重构的问题,这种重构很多时候都是没必要的

1. 如何使用keep-alive?

  • <router-view>其实也是个组件,如果它直接被包在<keep-alive>里面,所有涉及到的视图组件都会被缓存
  • <keep-alive>是定义在Vue中的内置组件,目的是为了避免重新渲染

例:我们想让home的两个次级路由的组件来回切换时不重新构建,可以给控制他们显示的<router-view>用<keep-alive>包起来

<template><div><h2>我是首页</h2><p>我是首页内容</p><router-link to="/home/news">看看新闻</router-link><router-link to="/home/msgs">看看消息</router-link><keep-alive><router-view></router-view></keep-alive></div>
</template><script>
export default {name: "Home"
};
</script><style>
</style>

6a037859144092baba5e583105533d25.png

2. 因为被keep-alive,子组件多了两个属性

被keep-alive的组件都会多两个属性 activated 和 deactivated,里面可以传入方法,当活跃/不活跃时调用

举例:

<template><div><h1>您有4条短消息</h1><ul><li>短消息1</li><li>短消息2</li><li>短消息3</li><li>短消息4</li></ul></div>
</template><script>
export default {name:"HomeMsg",activated() {console.log("我真活跃");},deactivated() {console.log("我不活跃了");},
}
</script><style></style>

26bb342d6b9ec52a09a4a53d200150c8.png

3.<keep-alive> 的包含和例外

如果又4个标签,我们想其中3个keep-alive怎么办???

这时我们需要用keep-alive的属性

51477877b6ff179001d2dd5d0e2ac36e.png
    <keep-alive exclude="HomeMsg,User">    这会排除这两个组件的keep-alive<router-view></router-view></keep-alive>

八. 导航守卫

有时我们需要监听页面跳转

比如,我们要监听页面跳转,跳转时,将我们的网站的title该为对应页面的名称

1.前置守卫

前置守卫是跳转前的守卫

我们可以在index.js里,给我们的router调用一个前置守卫(钩子)函数:router.beforeEach()

router.beforeEach((to,from,next)=>{   //这就是页面跳转过程document.title= to.meta.matched[0].title  //将页面标题改为了to路由的meta信息里的标题next()  // 必须调用next(),以维护链式
})

前提是to路由里有meta,如: meta(描述信息)

  {path:"/profile",component:()=>import('../components/Profile'),meta:{title:'档案'},},

为什么有个 .matched[0], 因为有时我们进入嵌套路由,比如, home/news,

但此时我们还想显示home的meta, 就可以通过这种方法找到它的第一级路由的meta

2.后置守卫

其实还有后置守卫(钩子):

router.afterEach(to,from)

后置守卫没有next

3.next有大用

  • next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
  • next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
  • next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: truename: 'home' 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
  • next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。

4.路由独享守卫

你可以在路由配置上直接定义 beforeEnter 守卫:

const router = new VueRouter({routes: [{path: '/foo',component: Foo,beforeEnter: (to, from, next) => {// ...}}]
})

5.组件内守卫

你可以在路由组件内直接定义以下路由导航守卫:

const Foo = {template: `...`,beforeRouteEnter (to, from, next) {// 在渲染该组件的对应路由被 confirm 前调用// 不!能!获取组件实例 `this`// 因为当守卫执行前,组件实例还没被创建},beforeRouteUpdate (to, from, next) {// 在当前路由改变,但是该组件被复用时调用// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。// 可以访问组件实例 `this`},beforeRouteLeave (to, from, next) {// 导航离开该组件的对应路由时调用// 可以访问组件实例 `this`}
}
beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。不过,你可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。beforeRouteEnter (to, from, next) {next(vm => {// 通过 `vm` 访问组件实例})
}
注意 beforeRouteEnter 是支持给 next 传递回调的唯一守卫。对于 beforeRouteUpdate 和 beforeRouteLeave 来说,this 已经可用了,所以不支持传递回调,因为没有必要了。beforeRouteUpdate (to, from, next) {// just use `this`this.name = to.params.namenext()
}
这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消。beforeRouteLeave (to, from, next) {const answer = window.confirm('Do you really want to leave? you have unsaved changes!')if (answer) {next()} else {next(false)}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/542782.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

css div撑满窗口高度_如何使用CSS将div的高度设置为窗口的100%?

css div撑满窗口高度Introduction: 介绍&#xff1a; Hello there developers! Well, certainly if you are reading this article then that means that you have run into some trouble while creating your web page or website and if you are a beginner in this field, …

.net core image怎么保存_轻量级Vue图片上传插件——Vue-core-image-Upload

介绍vue-core-image-upload 是一款轻量级的 Vue.js 上传插件&#xff0c;它可以支持的图片的上传&#xff0c;裁剪&#xff0c;压缩。它同样也支持在移动端的图片处理&#xff0c;它定义了诸多上传周期&#xff0c;你可以自由的进行流程控制。Githubhttps://github.com/Vanthin…

mysql确认半同步命令_怎么判断mysql是否是半同步复制

AFTER_COMMIT(5.6默认值)master将每个事务写入binlog ,传递到slave 刷新到磁盘(relay log)&#xff0c;同时主库提交事务。master等待slave 反馈收到relay log&#xff0c;只有收到ACK后master才将commit OK结果反馈给客户端。AFTER_SYNC(5.7默认值&#xff0c;但5.6中无此模式…

《Linus Torvalds自传》摘录

转自&#xff1a;http://www.ruanyifeng.com/blog/2012/09/linus_torvalds.html作者&#xff1a; 阮一峰日期&#xff1a; 2012年9月 3日除了程序员&#xff0c;大概很少人知道Linux操作系统。它的发明者Linus Torvalds&#xff0c;知道的人就更少了。他本人也很低调&#xff0…

python绘制条形图例题_python matplotlib库绘制条形图练习题

练习一&#xff1a;假设你获取到了2017年内地电影票房前20的电影&#xff08;列表a&#xff09;和电影票房数据&#xff08;列表b&#xff09;&#xff0c;那么如何更加直观的展示该数据&#xff1f; a ["战狼2","速度与激情8","功夫瑜伽",&quo…

mac mysql 忘记密码 卸载_MySQL忘记密码后重置密码(Mac )

转&#xff1a;http://www.cnblogs.com/lihuanqing/p/5623872.html安装好MySQL以后&#xff0c;系统给了个默认的的密码&#xff0c;然后不小心关了&#xff0c;惨了密码没有了。1、关闭mysql服务器 sudo /usr/local/mysql/support-files/mysql.server stop 也可以在系统偏好里…

Nginx严格访问代理HTTP资源

为什么80%的码农都做不了架构师&#xff1f;>>> 1 严格访问 访问能基于客户端的IP地址允许或拒绝或使用基于HTTP验证。 为了允许或拒绝从某个地址及或所有地址的访问&#xff0c;使用allow和deny指令&#xff1a; location / { deny 192.168.1.2; allow 192.168…

csv 字符串_Python实现json转csv格式

利用Python实现json格式转换为csv文件格式前言本文是学校的课程设计&#xff0c;这里我没有用封装好的json库来实现&#xff0c;而是把读进来的文件当一个字符串来处理&#xff0c;核心函数其实是python的eval()类型转换函数。什么是 JSON?我们要考虑到json格式下key-value对的…

mysql 线性表_数据结构之线性表

概要参考《大话数据结构》&#xff0c;把常用的基本数据结构梳理一下。线性表定义线性表(List)&#xff1a;零个或多个数据元素的有限序列。若将线性表记为 \((a_1, \cdots, a_{i-1}, a_i, a_{i1}, \cdots, a_n)\)&#xff0c;则表中 \(a_{i-1}\) 领先于 \(a_i\)&#xff0c;\(…

sqldeveloper mysql迁移_通过SQL Developer工具将MySQL数据库内容迁移至Oracle的步骤

通过SQL Developer工具将MySQL数据库内容迁移至Oracle的步骤发布时间&#xff1a;2020-06-08 15:52:18来源&#xff1a;51CTO阅读&#xff1a;210作者&#xff1a;三月本篇文章给大家主要讲的是关于通过SQL Developer工具将MySQL数据库内容迁移至Oracle的步骤的内容&#xff0c…

未能成功加载扩展程序_【JAVA虚拟机(JVM)精髓】09-几种不同的类加载器

持续更新JVM相关知识&#xff0c;敬请关注&#xff1a;Java虚拟机精髓专栏​zhuanlan.zhihu.com上一节说了下类加载器和类加载过程。这一节我们看下几种不同的类加载器。JVM支持的类加载器有两类&#xff0c;分别是引导类加载器和自定义加载器。这里的自定义自定义加载器&#…

图片md5修改工具_如何修改视频和图片的MD5,用电脑自带的命令

首先说下&#xff0c;md5到底是啥&#xff0c;它是一段固定长度的数据。无论原始数据是多长或多短&#xff0c;其MD5值都是128bit。另外md5是确定性&#xff0c;一个原始数据的MD5值是唯一的&#xff0c;同一个原始数据不可能会计算出多个不同的MD5值&#xff1b;类似人类的身份…

c语言遍历文件内容_C语言学习第28篇---动态内存分配剖析

为什么C语言要动态分配内存的意义&#xff1f;1.C语言中的一切操作都是基于内存的2.变量和数组都是内存的别名---内存分配由编译器在编译期间决定的---定义数组的时候必须指定数组长度---数组长度是在编译期就必须确定的需求&#xff1a;程序运行的过程中&#xff0c;可能需要使…

重启mysql的命令 linux_linux重启mysql命令

如何启动/停止/重启MySQL一、 启动方式1、使用 service 启动&#xff1a;service mysqld start2、使用 mysqld 脚本启动&#xff1a;/etc/inint.d/mysqld start3、使用 safe_mysqld 启动&#xff1a;safe_mysqld&二、停止1、使用 service 启动&#xff1a;service mysqld s…

javascript原型_使用JavaScript的示例报告卡Web应用程序原型

javascript原型Hi! At times, beginners always find it hard getting the application of the theory they learn In programming or a particular language. 嗨&#xff01; 有时&#xff0c;初学者总是很​​难在编程或特定语言中应用他们学到的理论。 In this article, we…

vb.net cad 块表最后的实体_21个绘图命令+7个技巧,3分钟让你成为CAD高手

绘制图纸需要用到CAD&#xff0c;CAD制图在生活中也是广泛运用&#xff0c;那么学习CAD到底难不难呢&#xff1f;在这里要告诉CAD新手们&#xff0c;世上无难事&#xff0c;可以用3分钟让你成为CAD高手。21个绘图命令A&#xff1a;绘圆弧B&#xff1a;定义块C&#xff1a;画圆D…

本地tomcat启动war包_「shell脚本」懒人运维之自动升级tomcat应用(war包)

准备&#xff1a;提前修改war包里的相关配置&#xff0c;并上传到服务器&#xff1b;根据要自动升级的tomcat应用修改或添加脚本相关内容&#xff1b;tomcat启动脚本如是自己写的&#xff0c;要统一格式命名&#xff0c;如&#xff1a;xxx、xxxTomcat 等&#xff1b;拿到生产使…

python将txt转为字符串_python做第一只小爬虫

“受尽苦难而不厌&#xff0c;此乃修罗之路”本文技术含量过低&#xff0c;请谨慎观看之前用R语言的Rcurl包做过爬虫&#xff0c;给自己的第一感觉是比较费劲&#xff0c;看着看着发际线就愈加亮眼&#xff0c;最后果断丢之。不过好的是和python爬取原理基本一致&#xff0c;且…

python3 array为什么不能放不同类型的数据_小白入门Python数据科学全教程lt;一gt;...

前言本文讲解了从零开始学习Python数据科学的全过程&#xff0c;涵盖各种工具和方法你将会学习到如何使用python做基本的数据分析你还可以了解机器学习算法的原理和使用说明先说一段题外话。我是一名数据科学家&#xff0c;在用SAS做分析超过5年后&#xff0c;我决定走出舒适区…

c winform 上传文件到mysql_C# winform DevExpress上传图片到数据库【转】

实现功能如下图&#xff1a;注明&#xff1a;此文使用的是DevExpress控件&#xff0c;winform 原生控件也是一样使用方法。1.点击选择图片按钮&#xff0c;功能为通过对话框选择要上传的文件&#xff0c;并将该文件在下面的PictureEdit中显示出来。具体代码如下&#xff1a;pri…