vue中使用vuex和router

6 篇文章 0 订阅
5 篇文章 0 订阅

vuex

Vuex 是一个专为 Vue应用程序开发的状态管理模式 ,它用来储存管理所有组件状态。

这个状态自管理应用包含以下几个部分:
  1. state,驱动应用的数据源;
  2. view,以声明方式将 state 映射到视图;
  3. actions,响应在 view 上的用户输入导致的状态变化。

定义好state(组件间的状态),view视图渲染这些数据,actions去请求数据,得到后在给state。 以下是一个表示“单向数据流”理念的简单示意:

在这里插入图片描述

核心概念

state:单一的自身状态,比如在一个页面中(由很多个组件组合而成),那么就可以为这个页面单独建立一个store,让这个页面的所有组件都共享这个状态。

state:{
	count:0,
	arr:[1, 2]
}

mutations:更改vuex的state只能通过mutations的方法去修改。回调函数接受第一个参数为state,也就是自身的状态。当更改简单类型的数据直接赋值就可以了,注意:更改复杂数据类型的时候就需要每次赋予一个新的地址。视图才会得到刷新。

mutations:{
	increment(state){
		state.count++
	},
	updateArr(state){
		//这里通过Object.assign方法合并,也可以用其它方法
        const arr = [3, 4];
        Object.assign(state,{ arr });
        //扩展数组
        state.arr = [...arr];
	}
}

getters:有时候会从state中衍生出来一些属性(可以认为是store的计算属性),就像计算属性一样,getter的返回值会更据它的依赖进行缓存,只有当它 的依赖值发生变化才会被重新计算。回调函数也接受state为第一个参数例如数组的长度。

getters:{
	arrLen:state => {
		return state.arr.length;
	},
	existence:state => index => {
		return state.arr.indexOf(index)===-1?false:true;
	}
}

actions:在actions中提交 mutation ,去改变状态,用来处理异步和事务性操作。回调函数接受一个参数context,通过context可以访问state、getters、commit 、dispatch(用来触发其它actions函数)。在接收到的时候可以直接结构.

actions:{
	async getData({state, getters, commit ,dispatch}){
        //组装好数据
		let obj = { count:state.count, arrLen:getters.arrLen };
        //异步请求数据
		const { data } = await ajax(obj);
        //成功过后在去触发
        commit("increment");
        //也可以在触发一个其它actions函数
        dispatch("getStu");
	},
    async getStu(){
        //...
    }
}

modules:当你的应用变得相当复杂时,store就会变得十分臃肿,就会把一个个的store分离开,在通过modules组合在一起。namespaced命名空间的开启会让每个store独立的调用。

const moduleA = {
  namespaced: true,//命名空间
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  namespaced: true,//命名空间
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

辅助函数

当一个组件需要获取多个状态或方法的时候,如果都声明出来会显得沉重多余,一般来说,使用辅助函数只声明需要的属性。

createNamespacedHelpers:创建基于某个命名空间辅助函数。它返回一个对象,对象里有新的绑定在给定命名空间值上的组件绑定辅助函数。通过解构的方式在组件的vue实例里声明出来。

mapState、mapGetters、mapMutations、mapActions分别对应的就是state、getters的状态,mutations、actions方法。直接this调用就好了。

const {
 mapState,
 mapGetters, 
 mapMutations,
 mapActions } = createNamespacedHelpers("count");//count为module里的命名,需要开启命名空间

export default {
  computed: {
    // 在 `module==>count` 中查找
    ...mapState(["a","b"]),
    ...mapGetters(["arrLen","existence"]),
  },
  methods: {
    // 在 `module==>count` 中查找
    ...mapActions([ 'getStu','getData']),
    ...mapMutations([ 'updateArr','increment']),
  }
}

router

配置基本路由

配置一个基本路由path就是路径也就是地址栏上的,component表示组件当页面足够多,组件足够复杂时可以采用懒加载的方式,这样就能加高效了。name非必填项这里可以取一个组件名字,meta代表页面的teitle的配置。每一个路径就对应映射一个组件。

import Count from "./components/count.vue"
// 懒加载的方式
// const Count = () => import('./components/count.vue')
const routes =new VueRouter({
    routers:[
  			{ path: '/count', component: Count, name:'count',  meta: {title: '总数' } 
		]
  }) 

一般来说使用vue做单页应用时在App.vue里使用router提供的组件,每当路径发生变化时,就能去渲染不同的页面,也就是说替换整个body。

<template>
 	<div id="app">
      <router-view />
	</div>
</template>
路由的嵌套
const routes =new VueRouter({
    routers:[ { path: '/count', 
    component: () => import('./components/count.vue'),
    children:[{
   		 path: 'countList',
         component: () => import('./components/countList.vue').
         children:...//嵌套
  	}]
  ]
 }) 

页面复杂一些的时候会有一级菜单,二级菜单,那么对应的会有一级路由二级路由,一级一级往下。此时使用嵌套的路由就能解决了。

动态路由跳转

路由配置好了,就能使用了。从一个页面跳转到另一个页面。

// 声明式
<router-link :to="/count"> </router-link>
// 点击这个组件时就能直接跳转更a标签一样的效果

// 编程式
this.$router.push('/count')
// 效果都一样

// 需要传递参数时
<router-link :to="{ name: '/count', params: { id: 123 }}" > </router-link>
//或者
this.$router.push({ name: '/count', params: { id: 123 }})

routes.js配置则需要配置一下接收的名称。

const routes =new VueRouter({
     routers:[{ path: '/count/:id', component: () => import('./components/count.vue') 
          }]
  }) 
//获取通过 id = this.$route.params
// 更加快捷的方式,跳转
this.$router.push('/count?id=123')
// 获取参数
this.$route.query.count
重定向和别名

重定向也是通过routers来完成的,下面这个例子就是从/a 重定向到 /b,当地址栏输入/a是也会跳转到/b

//
const router = new VueRouter({
  routes: [
    { path: '/a', redirect: '/b' }
  ]
})
// 动态返回重定向
const router = new VueRouter({
  routes: [
    { path: '/a', redirect:to=>{
        // 方法接收 目标路由 作为参数
      // return 重定向的 字符串路径/路径对象
        return '/b'
    } }
  ]
})

别名,与重定向类似,当访问/a,时URL会保持/a,当访问/b,时URL也会保持/b,访问这两个路径都是一样的,只是url不会变,重定向就会变。

const router = new VueRouter({
  routes: [
    { path: '/a', component: A, alias: '/b' }
  ]
})
导航守卫

每一个守卫方法接收三个参数

  1. to: route:即将要进入的目标路由对象
  2. from:route:当前导航正要离开的路由
  3. next:function:一定要调用此方法来resolve这个钩子,next( true )或next( )直接进入下一个路由next( false)直接中断,路由不会该表。

全局前置守卫:当一个到导航触发时,会调用这个方法。

const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
  // ...
})

全局后置守卫:路由完成之后会调用这个钩子,不会接收next函数作为参数。

router.afterEach((to, from) => {
  // ...
})

路由独享的守卫:进入该路由前会调用,***next()***调用路由才会该表。

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

组件内的守卫:当在组件内才会调用这些钩子。

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值