vue之路由(跳转、多级路由、守卫)、localStorage

一、vue-router使用

1、vue-router的使用

创建项目时候已经安装路由

不需要: npm install vue-router --save

//引入VueRouter
   import VueRouter from 'vue-router'
   //引入Luyou 组件
   import About from '../components/About'
   import Home from '../components/Home'
   
   //创建router实例对象,去管理一组一组的路由规则
   const router = new VueRouter({
   	routes:[
   		{
   			path:'/about',
   			component:About
   		},
   		{
   			path:'/home',
   			component:Home
   		}
   	]
   })
   
   //暴露router
   export default router

2、路由跳转

标签跳转:<router-link,

控制页面跳转:$router.push

# 1 html 中通过标签跳转
    <router-link :to="about_url">
      <button>点我调到about-->标签的跳转</button>
    </router-link>
    
     <router-link to="/about">
          <button>点我调到about-->标签的跳转</button>
      </router-link>

# 2 js 控制页面跳转
	  // 方式一:直接放地址形式
      // this.$router.push('/about')
      // 方式二:对象形式
      // this.$router.push({name: 'about'})
      // this.$router.push({path: '/about'})

3、相关api

this.$router.push(path): 相当于点击路由链接(可以返回到当前路由界面)

this.$router.replace(path): 用新路由替换当前路由(不可以返回到当前路由界面)

this.$router.back(): 请求(返回)上一个记录路由

this.$router.go(-1): 请求(返回)上一个记录路由

this.$router.go(1): 请求下一个记录路由 

4、页面跳转,携带数据

注意:

以 login?user_id=9&age=18携带参数,需要从 $route.query 中取

以/xx/:id/:name 携带参数,需要从 $route.params中取

方式一:url地址中携带 ? 

http://localhost:8081/login?user_id=9&age=18

跳转的时候: 
    	-标签跳转: 
            <router-link to="/userinfo?user_id=9">
            <router-link :to="{name:userinfo,query:{user_id:88}}">
        
        -js跳转
            this.$router.push("/userinfo?user_id=9")
            this.$router.push({name:'userinfo',query:{user_id:88}})
            
取值的时候:
	  this.$route.query.user_id                    

方式二:/xx/:id/:name

配置路由:
        {
        path: '/userinfo/:id/:name',
        name: 'userinfo',
        component: UserDetail
   	 },

跳转的时候: 
    	-标签跳转: 
            <router-link to="/userinfo/88/lqz">
            <router-link :to="{name:'userinfo',params:{id:88,name:lqz}}">
        -js跳转
	    this.$router.push("/userinfo/88/lqz")
            this.$router.push({name:userinfo,params:{id:88,name:lqz}})
            
取值的时候:
		this.$route.params.id 

代码:

<template>
  <div class="home">

    <h1>首页</h1>
    <button @click="handleClick">点我调到about</button>
    <br>
    <!--        <router-link to="/about">-->
    <!--          <button>点我调到about–>标签的跳转</button>-->
    <!--        </router-link>-->

    <router-link :to="about_url">
      <button>点我调到about-->标签的跳转</button>
    </router-link>

    <hr>
    <router-link to="/userinfo?user_id=9">
      <button>点我跳转到userinfo,携带用户id</button>
    </router-link>
    <br>

    <button @click="handleClick2()">js跳转点我跳转到userinfo,?携带用户id</button>

    <br>
    <router-link to="/userinfo/88/lqz">
      <button>点我跳转到userinfo,携带用户id</button>
    </router-link>

    <hr>

    <div>
      <div class="head"> 头部标题</div>

      <div class="main">

        <el-row :gutter="20">
          <el-col :span="4">
            <el-menu
                default-active="2"
                class="el-menu-vertical-demo"
                @open="handleOpen"
                @close="handleClose"
                background-color="#545c64"
                text-color="#fff"
                active-text-color="#ffd04b">
              <router-link to="/index">
                <el-menu-item index="1">
                  <i class="el-icon-menu"></i>

                  <span slot="title">首页</span>

                </el-menu-item>
              </router-link>
              <router-link to="/order">
                <el-menu-item index="2">
                  <i class="el-icon-menu"></i>

                  <span slot="title">订单</span>

                </el-menu-item>
              </router-link>

            </el-menu>
          </el-col>
          <el-col :span="20">
            <div class="right">
              <router-view/>
            </div>
          </el-col>
        </el-row>

      </div>

    </div>

  </div>
</template>

<script>


export default {
  name: 'HomeView',
  data() {
    return {
      // about_url: '/about',
      // about_url: {'name': 'about'},
      about_url: {'path': '/about'},
    }
  },
  methods: {
    handleClick() {
      // 方式一:直接放地址形式
      // this.$router.push('/about')
      // 方式二:对象形式
      // this.$router.push({name: 'about'})
      // this.$router.push({path: '/about'})


      // replace的使用
      this.$router.replace({name: 'about'})

    },
    handleClick2() {
      // this.$router.push('/userinfo/77/aaa')
      this.$router.push({
        name: 'userinfo',
        params: {id: 77, name: 'aaa'},
        query: {aa: 'aaa'}
      })
    }
  }
}
</script>
<style>

.head {
  height: 50px;
  background-color: aqua;
}

.left {
  background-color: blanchedalmond;
  height: 300px;
}

.right {
  background-color: chartreuse;
  height: 300px;
}
</style>

### 接收
<template>
  <div class="home">

    <h1>用户详情</h1>
    {{ user_id }}

  </div>
</template>

<script>

export default {
  name: 'UserDetail',
  data() {
    return {
      // user_id: this.$route.query.user_id
      user_id: ''
    }
  },
  created() {
    // this.$route代指当前路由对象
    console.log(this.$route)
    // this.$route.query 代指当前路由对象传递的参数  ? 后的
    // this.user_id = this.$route.query.user_id
    this.user_id = this.$route.params.id
  }
}
</script>

5、多级路由(子路由)

children: []

# 1 新建一个首页HomeView,一个IndexView和OrderView
	-构建出骨架,以后想点击只有这个位置变,就放一个 <router-view/>
    
   	-IndexView和OrderView正常写
    
# 2 定义多级路由
	 {
        path: '/',
        name: 'home',
        component: HomeView,
        children: [ //通过children配置子级路由
            {
                path: 'index', //此处一定不要写:/news
                component: IndexView
            },
            {
                path: 'order',//此处一定不要写:/message
                component: OrderView
            }
        ]
    },
    
# 3 路由跳转:js,html  

跳转:

<router-link to="/order">
                <el-menu-item index="2">
                  <i class="el-icon-menu"></i>
                  <span slot="title">订单</span>
                </el-menu-item>
</router-link>

需动态改变的地方:

 <el-col :span="20">
            <div class="right">
              <router-view/>
            </div>
          </el-col> 

vue代码:

<template>
  <div class="home">
    <h1>首页</h1>
    <div>
      <div class="head"> 头部标题</div>
      <div class="main">
        <el-row :gutter="20">
          <el-col :span="4">
            <el-menu
                default-active="2"
                class="el-menu-vertical-demo"
                @open="handleOpen"
                @close="handleClose"
                background-color="#545c64"
                text-color="#fff"
                active-text-color="#ffd04b">
              <router-link to="/index">
                <el-menu-item index="1">
                  <i class="el-icon-menu"></i>
                  <span slot="title">顾客</span>
                </el-menu-item>
              </router-link>
              <router-link to="/order">
                <el-menu-item index="2">
                  <i class="el-icon-menu"></i>
                  <span slot="title">订单</span>
                </el-menu-item>
              </router-link>
            </el-menu>
          </el-col>
          <el-col :span="20">
            <div class="right">
              <router-view/>
            </div>
          </el-col>
        </el-row>
      </div>

    </div>

  </div>
</template>

<script>


export default {
  name: 'HomeView',
  data() {
    return {
      // about_url: '/about',
      // about_url: {'name': 'about'},
      about_url: {'path': '/about'},
    }
  },
  methods: {
    handleClick() {
      // 方式一:直接放地址形式
      // this.$router.push('/about')
      // 方式二:对象形式
      // this.$router.push({name: 'about'})
      // this.$router.push({path: '/about'})


      // replace的使用
      this.$router.replace({name: 'about'})

    },
    handleClick2() {
      // this.$router.push('/userinfo/77/aaa')
      this.$router.push({
        name: 'userinfo',
        params: {id: 77, name: 'aaa'},
        query: {aa: 'aaa'}
      })
    }
  }
}
</script>


<style>
.head {
  height: 50px;
  background-color: aqua;
}

.left {
  background-color: blanchedalmond;
  height: 300px;
}

.right {
  background-color: chartreuse;
  height: 300px;
}
</style>

6、路由守卫 

作用:对路由进行权限控制

全局守卫(全局路由文件)

//全局前置路由守卫————初始化的时候被调用、每次路由切换之前被调用
router.beforeEach((to,from,next)=>{
	console.log('前置路由守卫',to,from)
	if(to.meta.isAuth){ //判断是否需要鉴权
		if(localStorage.getItem('name')==='lqz'){
			next()
		}else{
			alert('名不对,无权限查看!')
		}
	}else{
		next()
	}
})

//全局后置路由守卫————初始化的时候被调用、每次路由切换之后被调用
router.afterEach((to,from)=>{
	console.log('后置路由守卫',to,from)
	document.title = to.meta.title || 'lqz系统'
})

export default router

独享守卫(某个页面的路由)

// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import About from '../pages/About'
import Home from '../pages/Home'
import News from '../pages/News'
import Message from '../pages/Message'
import Detail from '../pages/Detail'

//创建并暴露一个路由器
const router =  new VueRouter({
	routes:[
		{
			name:'guanyu',
			path:'/about',
			component:About,
			meta:{title:'关于'}
		},
		{
			name:'zhuye',
			path:'/home',
			component:Home,
			meta:{title:'主页'},
			children:[
				{
					name:'xinwen',
					path:'news',
					component:News,
					meta:{isAuth:true,title:'新闻'},
					beforeEnter: (to, from, next) => {
						console.log('独享路由守卫',to,from)
						if(to.meta.isAuth){ //判断是否需要鉴权
							if(localStorage.getItem('name')==='lqz'){
								next()
							}else{
								alert('名不对,无权限查看!')
							}
						}else{
							next()
						}
					}
				},
				{
					name:'xiaoxi',
					path:'message',
					component:Message,
					meta:{isAuth:true,title:'消息'},
					children:[
						{
							name:'xiangqing',
							path:'detail',
							component:Detail,
							meta:{isAuth:true,title:'详情'},

						}
					]
				}
			]
		}
	]
})

export default router  

注意:meta: { isAuth: false } 是在路由里面定义好的

组件内守卫(组件内)

  //进入守卫:通过路由规则,进入该组件时被调用
   beforeRouteEnter (to, from, next) {
   },
   //离开守卫:通过路由规则,离开该组件时被调用
   beforeRouteLeave (to, from, next) {
   }


	//通过路由规则,进入该组件时被调用
		beforeRouteEnter (to, from, next) {
			console.log('About--beforeRouteEnter',to,from)
			if(to.meta.isAuth){ //判断是否需要鉴权
				if(localStorage.getItem('school')==='atguigu'){
					next()
				}else{
					alert('学校名不对,无权限查看!')
				}
			}else{
				next()
			}
		},

		//通过路由规则,离开该组件时被调用
		beforeRouteLeave (to, from, next) {
			console.log('About--beforeRouteLeave',to,from)
			next()
		} 

7、路由器的两种工作模式

1 对于一个url来说,什么是hash值?—— #及其后面的内容就是hash值。

2 hash值不会包含在 HTTP 请求中,即:hash值不会带给服务器。

3 hash模式:
地址中永远带着#号,不美观 。
若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。
兼容性较好。

4 history模式:
地址干净,美观 。
兼容性和hash模式相比略差。
应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题

二、localStorage系列

1、前端存储数据,可以存在哪?

# localStorage
# sessionStorage
# cookie

- 可以放到cookie中,cookie有过期时间,一旦过期就清理了

- 可以当到localStorage,永久存储,除非使用代码删除,清理浏览器
 
- 可以存到sessionStorage,关闭浏览器就没了
    
# 用户登录状态----》token串--->cookie中

2、LocalStorage的存、读、删

一下都是定义点击事件来模拟

     saveLocalStorage() {
      // 保存对象呢?
      var userinfo = {'name': 'lqz', 'age': 19}
      localStorage.setItem('userinfo', JSON.stringify(userinfo))
    },

    getLocalStorage() {
      var res = JSON.parse(localStorage.getItem('userinfo'))
      console.log(res)
    },

    deleteLocalStorage() {
      localStorage.clear()
      localStorage.removeItem('username')
    }

3、session的存、读、删

    savesessionStorage() {
      // 保存对象呢?
      var userinfo = {'name': 'lqz', 'age': 19}
      sessionStorage.setItem('userinfo', JSON.stringify(userinfo))
    },
    getsessionStorage() {
      var res = JSON.parse(sessionStorage.getItem('userinfo'))
      console.log(res)
    },
    deletesessionStorage() {
      sessionStorage.clear()
      sessionStorage.removeItem('username')
    },

4、cookie --->js操作---》借助于第三方操作cookie

安装vue-cookies

npm install vue-cookies -S

在main.js引入

import VueCookies from "vue-cookies";

Vue.use(VueCookies);

cookie的存、读、删

    savecookie() {
      // 保存对象呢?
      this.$cookies.set('name', 'lqz')
    },
    getcookie() {
      console.log(this.$cookies.get('name'))
    },
    deletecookie() {
      this.$cookies.remove('name')
    },

三、vue3介绍

1、tree-shaking、typeScript 

# tree-shaking是一种消除死代码的性能优化理论
# TypeScript 
	-javascript:坑---》填坑---》弱类型
    -typeScript:强类型语言

2、组合式api和配置项api

配置项 Options API(vue2)

比较分散

<template>
  <div>
    <button @click="increment">{{ count }}</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0
    };
  },
  methods: {
    increment() {
      this.count++;
    }
  }
};
</script>

组合式Composition API(vue3)

集中在setup中

<template>
  <div>
    <button @click="increment">{{ count }}</button>
  </div>
</template>

<script>
import { ref } from 'vue';

export default {
  setup() {
    const count = ref(0);

    function increment() {
      count.value++;
    }

    return {
      count,
      increment
    };
  }
};
</script>

  

 

posted @ 2023-09-27 16:04  凡人半睁眼  阅读(33)  评论(0编辑  收藏  举报