路由与Vuex

一. VueRouter

Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。

1.1 安装

npm install vue-router --save

1.2 配置路由信息

新建一个文件夹叫做router,然后在里面定义一个index.js文件,在该文件中配置路由信息:

import Vue from 'vue'
import Router from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'


Vue.use(Router)   //使用插件

export default new Router({
    linkActiveClass: 'active',   //选中状态下默认添加的样式
    routes: [
        {
            path: '/home',
            component: Home
        },
        {
            path: '/about',
            component: About
        },
        {
            path: '/',
            redirect: '/about'   //根路径默认会重定向到/about路径
            
        }
    ]
})

1.3 main.js文件中的配置

import Vue from 'vue'
import App from './App.vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
import Base from './Base.vue'
import router from './router'

Vue.use(VueAxios, axios);  //顺序有关系
axios.defaults.baseURL = Base.BASE_URL

new Vue({
  render: h => h(App),
  router
}).$mount('#app')

1.4 访问与渲染

使用标签设置路径,to属性设置路由路径:

<router-link to="/home" class="list-group-item">Home</router-link>
<router-link to="/about" class="list-group-item">About</router-link>

使用标签,将对应的路由组件设置到这个标签当中:

<router-view></router-view>

1.5 子路由

在路由的配置中使用children来配置子路由。

children: [
	{
		path: '/home/game',
		component: Games
	}
]

1.6 参数的传递

在使用路由的过程中,经常会碰到路由参数的传递,那么传递方式大概有三种。

方式一:

路由配置:
{path:'/user/:id', component:userDetail, props:true}
路由请求:
<router-link :to="'/user/' + user.id">{{user.name}}</router-link>
取值:
在userDetail中使用 props: {id: String} 来接收数据

方式三:

路由配置:
{path:'/user', name:'userDetail', component:userDetail}
路由请求:
<router-link :to="{path:'/user', query:{id:user.id}}">{{user.name}}</router-link>
取值:
mounted() {
    this.id = this.$route.query.id;   //用户刷新的时候有用
},    
watch:{ //监听路由的变化
    $route: {
        handler(val) {
            this.id = val.query.id;
        }
     }
}

1.7 编程式路由

方式一:

实现跳转:
this.$router.push({
          path: '/user',
          query: {id:id}
       });
取值:
mounted() {
        this.id = this.$route.query.id;
    },
    
watch:{
    $route: {
    	handler(val) {
    		this.id = val.query.id;
    	}
    }
}

方式二:

实现跳转:
this.$router.push({
          path: '/user',
          query: {id:id}
       });
取值:
props: {
    id: String
}

1.8 路由守卫

1.8.1全局路由守卫

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

1.8.2 局部路由守卫

beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
},
beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
}

二. vuex

2.1 vuex是什么

vuex是对vue项目进行状态管理的js库,对于所有的组件来说,它是一个中央存储,这种模式就保证了只能按照特定的模式来更改状态。

2.2 vuex的五大核心

state

说的直白点就是存储数据的地方。

actions

通过异步的方式更改状态值,但是不能直接更改,需要借助于mutations来更改。

mutations

通过直接同步的方式更改状态。

getters

类似于计算属性,通常是需要通过state来间接计算得到的值。

modules

一个项目中因为模块的原因,存在着各种不同的状态,需要按照模块来划分。

2.3 安装vuex

npm install vuex --save

2.4 建立store

新建一个文件夹,名字叫store,在文件夹中新建一个文件,文件名叫index.js,文件内容如下:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex);

//state
const state = {
    todos:[{title:'工作一', complete:true}]
}
// actions
const actions = {
	// 第一个参数必须是context, 第二个参数是需要的业务数据
    addTodo(context, todo){
    	// 通过commit的方式提交个mutations, 真正实现对状态修改的其实是mutations
        context.commit('addTodo', todo)
    }
}
// getter,类似于计算属性,需要根据state来计算出其他想要的属性
const getters = {
    completedTodoNumber: state => {
        return state.todos.reduce((preTotal, current) => preTotal + (current.complete ? 1 : 0), 0)
    }
}
//操作
const mutations = {
    //添加待办事项,第一个参数必须是state, 第二个参数是传递过来的数据
    addTodo(state, todo) {
        state.todos.unshift(todo)
    }
}
// 对外暴露Vuex.Store的对象,在其他任何组件中都可以使用 $store来进行操作
export default new Vuex.Store({
    state,
    mutations,
    actions,
    getters
})

2.5 main.js配置

import Vue from 'vue'
import App from './App.vue'
import store from './store'

new Vue({
    store,   //引入store
    render: h => h(App)
}).$mount("#app");

2.6 组件中使用

this.$store.state.todos    //获取状态值
this.$store.commit('addTodo', todo);  //通过mutations中的方法更新状态
this.$store.dispatch('addTodo', todo); //通过actions中的方法异步更新状态
this.$store.getters.completedTodoNumber;  //获取getters中的属性

2.7 映射函数调用

import {mapState, mapActions, mapGetters, mapMutations} from 'vuex'

computed: {
    ...mapState(['todos']),  //扩展运算符, 在当前组件中直接使用this的方式调用
    ...mapGetters(['completedTodoNumber'])
},
methods: {
	//引号中的内容为actions中定义的方法名, 可以直接使用this.addTodo来调用。
    ...mapActions(['addTodo']),  
    ...mapMutations(['addTodo'])
}

2.8 Modules

A. 新建一个shopping目录,目录下新建index.js文件,文件内容如下:

const state = {
    todos:[{title:'工作一', complete:true}]
}

const actions = {
    addTodo(context, todo){
        context.commit('addTodo', todo)
    },
    delDone(context) {
        context.commit('delDone')
    },
    delByIndex(context, index) {
        context.commit('delByIndex', index);
    }
}
const getters = {
    completedTodoNumber: state => {
        return state.todos.reduce((preTotal, current) => preTotal + (current.complete ? 1 : 0), 0)
    }
}
//操作
const mutations = {
    //添加待办事项
    addTodo(state, todo) {
        state.todos.unshift(todo)
    },
    delDone(state) {
        state.todos = state.todos.filter(todo => !todo.complete)
    },
    delByIndex(state, index) {
        state.todos.splice(index, 1);
    }
}

export default {
    state,
    actions,
    getters,
    mutations
}

B. 在store下的index.js文件中写入如下内容:

import Vue from 'vue'
import Vuex from 'vuex'
import shopping from 'shopping'

Vue.use(Vuex);

export default new Vuex.Store({
    modules: {
        shopping
    }
})

C. 使用

获取对应模块的state值方式一:
...mapState({todos: state=>state.shopping.todos})
获取对应模块的state值方式二:
todos: function() {
      return this.$store.state.shopping.todos;
}


至于getters、actions、mutations都被注册到全局上,和之前的使用方式一样。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值