学习Vue.js的过程是一个有趣且富有挑战性的体验。以下是我学习Vue.js的一-些心得:
1.理解响应式原理: Vue.js的核心是响应式系统,这意味着当数据发生变化时,视图会自动更新。理解这个原理是掌握Vue.js的关键。
2.组件化开发: Vue.js鼓 励使用组件化的方式进行开发。组件化开发可以提高代码的可重用性和可维护性。
3.指令和混入:Vue.js提供了丰富的指令和混入功能,这些功能可以帮助我们更方便地操作DOM和处理逻辑。
4.路由和状态管理:对于单页应用来说,路由和状态管理是非常重要的。Vue.js的路由库Vue Router和状态管理库Vuex可以帮助我们更好地管理应用的状态和路由。
5.异步加载和代码分割:为了提高应用的性能,我们可以使用异步加载和代码分割技术。这些技术可以帮助我们按需加载代码,减少首屏加载时间。
6.使用构建工具:使用构建工具如Webpack或Vite可以帮助我们更好地管理项目,提高开发效率。
7.实践出真知:最好的学习方式还是实践。通过不断地编写代码、调试代码,我们可以更好地掌握Vue.js。
下面,是我在课堂跟老师学习以及自己完成的一些代码练习:
1.表格的简单实现以及隐私号码实现:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<table border="1">
<thead>
<th>商品名称</th>
<th>商品价格</th>
<th>状态</th>
</thead>
<tbody>
<tr v-for="(item,index) in list" :key="index">
<td>{{item.name}}</td>
<td>{{item.price}}</td>
<td>{{item.status|statusFormat}}</td>
</tr>
</tbody>
</table>
<h1>{{tel|telFormat}}</h1>
</div>
<script>
var vm=new Vue({
el:"#app",
data(){
return{
tel:"13324558785",
list: [
{
name: "衣服",
price:'100',
status: 1,
},
{
name: "帽子",
price:'50',
status: 0,
},
{
name: "鞋子",
price:'50',
status: 2,
}
]
}
},
methods:{
},
filters:{
statusFormat(val){
if(val==0){
return "待支付"
}else if(val==1){
return "待发货"
}else{
return "已完成"
}
},
telFormat(val){
return val.substr(0,3)+"****"+val.substr(7)
}
}
})
</script>
</body>
</html>
代码实现效果图:
2.过滤器:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
{{money|addIcon}}
{{money2|addIcon}}
</div>
<script>
var vm=new Vue({
el:"#app",
data(){
return{
money:500,
money2:1000
}
},
methods:{
},
filters:{
//定义一个给金额添加符号的过滤器 return computed
//在过滤器里面,不能通过this拿到data里面的变量
addIcon(val){
return "¥"+val
}
}
})
</script>
</body>
</html>
3.监听属性:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../js/vue.js"></script>
</head>
<style>
.tip{
color: red;
font-size: 14px;
}
</style>
<body>
<div id="app">
<input type="text" placeholder="请输入借款金额" v-model.number="money">
<p class="tip">{{tip}}</p>
</div>
<script src="../js/vue.js"></script>
<script type="text/javascript">
new Vue({
el:"#app",
data:{
money:"",
tip:""
},
computed:{},
watch:{
money(newVal,oldVal){
console.log(newVal)
console.log(oldVal)
if(newVal>1000){
this.tip="最大借款金额不能超过1000"
alert("你的借款额度超出范围了")
}else{
this.tip=""
}
}
}
})
</script>
</body>
</html>
代码实现效果图:
4.事件修饰符:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="app">
<input type="text" @keydown.enter="onEnter">
<a href="http://www.baidu.com" @click.prevent="toBaidu">百度</a>
</div>
<script>
var vm=new Vue({
el:"#app",
data(){
return{
}
},
methods:{
toBaidu(){
alert("跳转到百度")
},
onEnter(){
alert("回车键被按下了")
}
}
})
</script>
</body>
</html>
代码实现效果图:
5.点击切换图片:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../js/vue.js"> </script>
<style>
#imgmax{
width: 250px;
height: 250px;
}
#imgmin{
width: 50px;
height: 50px;
}
.border{
border: 5px solid rgb(255, 187, 0);
}
</style>
</head>
<body>
<!-- html -->
<div id="app">
<img v-bind:src="big" alt="" id="imgmax">
<div>
<img v-for="(tiem,index) in imgs" :src="imgs[index]" alt="" id="imgmin" @click="BG" :class="[show==index?'border':'']">
</div>
</div>
<!-- js -->
<script>
var app = new Vue({
el:"#app",
data(){
return{
show:0,
big:"../images/good4.jpg",
imgs:[
"../images/good4.jpg",
"../images/good5.jpeg",
"../images/mobile1.jpg",
"../images/mobile2.png",
],
}
},
methods:{
BG(){
img = event.target
imgs = img.parentNode.childNodes
for(var i = 0;i < imgs.length;i = i + 1){
if (imgs[i] == img) {
this.show = i
this.big = this.imgs[i]
}
}
console.log(imgs);
}
}
})
</script>
</body>
</html>
代码效果实现图:
点击切换图片我写的比较简单 。
下面是最近跟老师学习在vue脚手架下创建项目:
1.主代码:
<template>
<div id="app">
<!-- 左 -->
<div class="left" v-if="$route.meta.isShow">
<ul>
<!-- 实现菜单的页面跳转 -->
<router-link to="/">
<li><img src="./assets/logo.png" alt="">首页</li>
</router-link>
<router-link to="/cart">
<li><img src="./assets/logo.png" alt="">购物车</li>
</router-link>
<router-link to="/order">
<li><img src="./assets/logo.png" alt="">订单</li>
</router-link>
<router-link to="user">
<li><img src="./assets/logo.png" alt="">用户列表</li>
</router-link>
</ul>
</div>
<div class="right">
<!-- 右边 -->
<!-- 这个标签不要删 -->
<!-- 路由path对应的页面的占位符 -->
<div class="header" v-if="$route.meta.isShow">
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/'}">首页</el-breadcrumb-item>
<el-breadcrumb-item v-if="$route.meta.title!=='首页'"><a href="/">{{ $route.meta.title }}</a></el-breadcrumb-item>
</el-breadcrumb>
<el-dropdown @command="handleCommand">
<span class="el-dropdoen-link">
{{userinfo.username}}<img :src="userinfo.avator" alt="" />
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="退出">退出</el-dropdown-item>
<el-dropdown-item command="个人资料">个人资料</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<router-view />
</div>
</div>
</template>
<script>
export default {
name:"App",
data(){
return {
userinfo: {},
};
},
created() {
this.userinfo = JSON.parse(localStorage.getItem("userinfo"));
},
methods: {
ToAbout() {
this.$router.push("/about");
},
handleCommand(command) {
//跳转到登录页面
if (command=="退出") {
this.$router.push("/login");
}
}
},
};
</script>
<style lang="scss">
*{
margin: 0;
padding: 0;
}
#app{
display: flex;
}
.left{
background: rgb(128, 125, 125);
color: white;
width: 200px;
// vh 可视高度
height: 100vh;
box-sizing: border-box;
}
.left ul{
list-style: none;
}
.left ul li{
// margin-top:20px;
display: flex;
padding-left: 25px;
align-items: center;
padding: 15px 0 15px 15px;
}
.left ul li:hover{
background: red;
}
.left ul li img{
margin-right: 5px;
}
.left img{
width: 30px;
}
.right{
flex: 1;
}
.right .header img{
width: 30px;
vertical-align: middle;
}
.right .header{
padding: 25px 0;
margin: 0 25px;
border-bottom: 1px solid rgb(172, 170, 170);
display: flex;
justify-content: space-between;
}
</style>
2.登陆页面设计:
<template>
<div class="login">
<div class="box">
<h1>mall-admin</h1>
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
class="demo-ruleForm"
>
<el-form-item prop="name">
<el-input
prefix-icon="el-icon-user-solid"
v-model="ruleForm.name"
></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
prefix-icon="el-icon-lock"
v-model="ruleForm.password"
></el-input>
</el-form-item>
<el-form-item>
<el-button class="login-btn" type="primary" @click="submitForm('ruleForm')"
>登录</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
// @ is an alias to/src
import axios from 'axios'
export default {
name:"LoginView",
data() {
return {
ruleForm: {
name:"",
region:"",
},
rules: {
name: [
{ required: true, message: "请输入用户名", trigger: "blur"},
],
password: [
{ required: true, message: "请输入密码", trigger: "blur"},
],
},
};
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) =>{
if(valid) {
// 调用登陆的接口,实现登录功能
// 判断一下:成功,弹出来 登陆成功 并且跳转到首页
// 失败,失败的错误信息 以弹框的形式弹出来
axios
.post("http://106.52.94.26:3001/user/login",{
username: this.ruleForm.name,
password: this.ruleForm.password,
})
.then((res) =>{
console.log(res);
localStorage.setItem("userinfor",JSON.stringify(res.data.user))
if (res.data.code == 200) {
this.$message({
message:"登陆成功",
type:"success",
});
this.$router.push("/home")
}
})
.catch((err) =>{
console.log(err);
this.$message.error(err.response.data.msg);
});
}else {
console.log("error submit!!");
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
},
},
};
</script>
<style scoped lang="scss">
.login {
color: red;
display: flex;
justify-content: center;
.box {
width: 350px;
box-shadow: #ccc 0px 0px 8px;
padding: 50px;
margin-top: 150px;
h1{
text-align: center;
}
.login-btn{
width: 350px;
}
}
}
</style>
效果图:
3.路由:
import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
// name: 'home',
// component: HomeView ,
//路由重定向
redirect:"/login",
// meta:{
// //页面的标题
// title:"首页管理",
// // 布尔值 判断是否显示左侧菜单
// isShow:true
// }
},
{
path: '/home',
name: 'home',
component: HomeView ,
meta:{
//页面的标题
title:"首页管理",
// 布尔值 判断是否显示左侧菜单
isShow:true
}
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue'),
meta:{
//页面的标题
title:"详情管理",
// 布尔值 判断是否显示左侧菜单
isShow:true
}
},
{
path: '/cart',
name: 'cart',
component: () => import('../views/CartView.vue'),
meta:{
//页面的标题
title:"购物车管理",
// 布尔值 判断是否显示左侧菜单
isShow:true
}
},
{
path: '/login',
name: 'login',
component: () => import('../views/LoginView.vue'),
meta:{
//页面的标题
title:"登录管理",
// 布尔值 判断是否显示左侧菜单
isShow:false
}
},
{
path: '/order',
name: 'order',
component: () => import('../views/OrderView.vue'),
meta:{
//页面的标题
title:"订单管理",
// 布尔值 判断是否显示左侧菜单
isShow:true
}
},
{
path: '/user',
name: 'user',
component: () => import('../views/UserView.vue'),
meta:{
//页面的标题
title:"用户管理",
// 布尔值 判断是否显示左侧菜单
isShow:true
}
}
]
const router = new VueRouter({
routes
})
export default router
上面用到了axios,下面说一下怎么调用接口:
1.安装axios,npm install --save axios
2.在main.js中引入
import axios from ‘.axios’
Vue.prototype. a x i o s = a x i o s / / 如 果 V u e . p r o t o t y p e . axios=axios //如果Vue.prototype. axios=axios//如果Vue.prototype.ajax=axios ,调用时写法如下②
在想要调用接口数据的页面中,get后面的地址是你的接口地址
methods:{
getData:function(){
this.$axios.get("https://api.apiopen.top/getSingleJoke?sid=28654780").then(res=>{
alert(res.data.result.text);
this.data=res.data.result.text;
console.log(res.data)
})
}
}
mounted(){
this.$ajax({
method:'get',
url:'https://api.apiopen.top/getSingleJoke?sid=28654780'
}).then(response=>{
alert(response.data.result.text)
}).catch(function(err){
console.log(err)
})
},
post请求:
var qs=require('qs')
var url="https://www.apiopen.top/weatherApi";
this.$axios.post(url,qs.stringify({
city:'青岛'
})).then(res=>{
alert(res.data.data.city)
console.log(res.data)
})
分享一下路由方面的内容:
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:
1.嵌套的路由/视图表
2.模块化的、基于组件的路由配置
3.路由参数、查询、通配符
4.基于 Vue.js 过渡系统的视图过渡效果
5.细粒度的导航控制
6.带有自动激活的 CSS class 的链接
7.HTML5 历史模式或 hash 模式,在 IE9 中自动降级
8.自定义的滚动条行为
1.安装
NPM
npm install vue-router –save
如果在一个模块化工程中使用它,必须要通过 Vue.use() 明确地安装路由功能:
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
2.基础
起步
HTML指定路由显示位置
App.vue:<router-view></router-view>
JavaScript配置路由
1. 定义 (路由) 组件
创建了两个组件:Home.vue和About.vue
2. 定义路由
const routes = [
{
path:"/",
component:Home
},
{
path:"/about",
component:About
}
]
3. 创建 router 实例,然后传 `routes` 配置
const router = new VueRouter({
routes
})
4. 创建和挂载根实例
new Vue({
render: h => h(App),
router
}).$mount('#app')
5.增加跳转规则
<li><router-link to="/">首页</router-link></li>
<li><router-link to="/about">关于</router-link></li>
动态路由匹配(路由传递参数)
我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果:
- 定义传递参数的key
{
path: "/user/:username",
component: User
}
- 传递参数值
<li><router-link :to="'/user/'+username">用户</router-link></li>
- 读取参数
{{ this.$route.params.username }}
捕获所有路由或 404 Not found 路由
{
// 会匹配所有路径
path: '*'
}
{
// 会匹配以 `/user-` 开头的任意路径
path: '/user-*'
}
嵌套路由
实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件
借助 vue-router,使用嵌套路由配置,就可以很简单地表达这种关系。
{
path:"/news",
component:News,
children:[
{
// 不需要表现为路径,他会自动补全
path:"sports",
component:Sports
},
{
path:"yule",
component:Yule
}
]
}
对应的子路由需要显示的位置:news ->
<router-view></router-view>
注意事项:
- 要注意,以 / 开头的嵌套路径会被当作根路径。 这让你充分的使用嵌套组件而无须设置嵌套的路径。
- 跳转的连接要写全路径<li><router-link to="/news/yule">娱乐</router-link></li>
编程式的导航
除了使用 <router-link> 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。
关于<router-link>解释
<router-link> 组件支持用户在具有路由功能的应用中 (点击) 导航。 通过 to 属性指定目标地址,默认渲染成带有正确链接的 <a> 标签,可以通过配置 tag 属性生成别的标签.。另外,当目标路由成功激活时,链接元素自动设置一个表示激活的 CSS 类名。
<router-link> 比起写死的 <a href="..."> 会好一些,理由如下:
1.无论是 HTML5 history 模式还是 hash 模式,它的表现行为一致,所以,当你要切换路由模式,或者在 IE9 降级使用 hash 模式,无须作任何变动。
2.在 HTML5 history 模式下,router-link 会守卫点击事件,让浏览器不再重新加载页面。
3.当你在 HTML5 history 模式下使用 base 选项之后,所有的 to 属性都不需要写 (基路径) 了。
router.push(location, onComplete?, onAbort?)
// 字符串
router.push('home')
// 对象
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
router.replace(location, onComplete?, onAbort?)
跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录
router.go(n)
这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)。
命名路由
有时候,通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由,或者是执行一些跳转的时候。你可以在创建 Router 实例的时候,在 routes 配置中给某个路由设置名称。
const router = new VueRouter({
routes: [
{
path: '/user/:userId',
name: 'user',
component: User
}
]
})
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
router.push({ name: 'user', params: { userId: 123 }})
命名视图
有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar (侧导航) 和 main (主内容) 两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 router-view 没有设置名字,那么默认为 default。
<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>
一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components 配置 (带上 s):
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: Foo,
a: Bar,
b: Baz
}
}
]
})
重定向和别名
重定向也是通过 routes 配置来完成,下面例子是从 /a 重定向到 /b
const router = new VueRouter({
routes: [
{ path: '/a', redirect: '/b' }
]
})
别名,/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。
const router = new VueRouter({
routes: [
{ path: '/a', component: A, alias: '/b' }
]
})
路由组件传参
在组件中使用 $route 会使之与其对应路由形成高度耦合,从而使组件只能在某些特定的 URL 上使用,限制了其灵活性。
使用 props 将组件和路由解耦:
取代与 $route 的耦合
const User = {
props: ['id'],
template: '<div>User {{ id }}</div>'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User, props: true },
// 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项:
{
path: '/user/:id',
components: { default: User, sidebar: Sidebar },
props: { default: true, sidebar: false }
}
]
})
HTML5 History 模式
vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。
如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。
const router = new VueRouter({
mode: 'history',
routes: [...]
})
当你使用 history 模式时,URL 就像正常的 url,例如 http://yoursite.com/user/id,也好看!
不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 http://oursite.com/user/id 就会返回 404,这就不好看了。
导航高亮效果
Router-link默认携带class:router-link-active和router-link-exact-active,可以用来设置样式
当然class过长可以通过全局配置来修改:linkActiveClass和linkExactActiveClass
Exact:精准匹配,主要解决根目录的匹配规则
进阶
导航守卫
正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。
记住参数或查询的改变并不会触发进入/离开的导航守卫。你可以通过观察 $route 对象来应对这些变化,或使用 beforeRouteUpdate 的组件内守卫。
全局前置守卫
你可以使用 router.beforeEach 注册一个全局前置守卫:
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中。
每个守卫方法接收三个参数:
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: 'home' 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
确保要调用 next 方法,否则钩子就不会被 resolved。
全局解析守卫
在 2.5.0+ 你可以用 router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用
全局后置钩子
你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:
router.afterEach((to, from) => {
// ...
})
路由独享的守卫
你可以在路由配置上直接定义 beforeEnter 守卫:
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
这些守卫与全局前置守卫的方法参数是一样的。
组件内的守卫
最后,你可以在路由组件内直接定义以下路由导航守卫:
beforeRouteEnter
beforeRouteUpdate (2.2 新增)
beforeRouteLeave
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`
}
}
完整的导航解析流程
1.导航被触发。
2.在失活的组件里调用离开守卫。
3.调用全局的 beforeEach 守卫。
4.在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
5.在路由配置里调用 beforeEnter。
6.解析异步路由组件。
7.在被激活的组件里调用 beforeRouteEnter。
8.调用全局的 beforeResolve 守卫 (2.5+)。
9.导航被确认。
10.调用全局的 afterEach 钩子。
11.触发 DOM 更新。
12.用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。
这是目前所学的全部内容,给我带来了很大的帮助,虽然难免有代码报错烦躁的时候,但每次写出正确的代码的时候总是很开心。
总之,学习Vue.js需要耐心和实践。通过不断地学习和实践,我们可以掌握Vue.js,并使用它来构建高效、可维护的前端应用。