Vue路由与状态管理

Vue路由与状态管理

1.路由vue-router

1.1 什么是vue-router

vue-router就是vue官方提供的一个路由框架。使用 Vue.js ,我们已经可以通过组合组件来组成应用程序,当你要把 vue-router 添加进来,我们需要做的是,将组件(components)映射到路由(routes),然后告诉 vue-router 在哪里渲染它们

1.2 快速入门

# 全局安装 vue-cli
$ npm install -g vue-cli
# 创建一个基于webpack模板的新项目
$ vue init webpack vue-router-demo
----------------------------------------------
? Project name vue-router-demo
? Project description 一个vue-roter的示例项目
? Author weibin <762142281@qq.com>
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? No
? Set up unit tests No
? Setup e2e tests with Nightwatch? No
? Should we run `npm install` for you after the project has been created? (recommended) npm
----------------------------------------------
$ cd vue-router-demo
$ npm run dev

1.2.2

src/App.vue使我们的主界面,其中<router-view/>标签用于显示各个组件视图内容,src/router/index.js是定义路由的脚本path是路径,name是名称,component是跳转的组件

export default new Router({
  routes: [
    {
      path: '/', // 请求的uri路径
      name: 'HelloWorld', // 显示的名称
      component: HelloWorld // 映射要跳转的组件
    }
  ]
})
1. 自定义两个组件

list.vue

<template>
    <div>
    这是一个列表
    </div>
</template>

about.vue

<template>
    <div>
    关于我们
    </div>
</template>
2. 修改src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import about from '@/components/about'
import list from '@/components/list'
Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    },
    {
      path: '/list',
      name: 'list',
      component: about
    },
    {
      path: '/about',
      name: 'about',
      component: list
    }
  ]
})

3. 放置跳转链接

修改src/app.vue ,添加链接

<router-link to='/'>首页</router-link>
<router-link to='/list'>列表</router-link>
<router-link to='/about'>关于我们</router-link>
属性 类型 含义
to string | Location 表示目标路由的链接。当被点击后,内部会立刻把 to 的值传到 router.push() ,所以这个值可以是一个字符串或者是描述目标位置的对象。
replace boolean 设置 replace 属性的话,当点击时,会调用 router.replace() 而不是 router.push() ,于是导航后不会留下 history 记录。
append boolean 设置 append 属性后,则在当前(相对)路径前添加基路径。例如,我们从 /a 导航到一个相对路径 b ,如果没有配置 append ,则路径为 /b ,如果配了,则为 /a/b

1.3 深入了解

1.3.1 动态路由

我们经常会遇到这样的需求,有一个新闻列表,点击某一条进入新闻详细页,我们通常是传递新闻的ID给详细页,详细页根据ID进行处理。这时我们就会用到动态路由一个『路径参数』使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到his.$route.params

在src/components下创建item.vue

<template>
    <div>
       详细页 {{ $route.params.id }}
    </div>
</template>

修改src/router/index.js,引入item组件

{
    path: '/item/:id',
    name: 'Item',
    component: item
}

修改list.vue

<template>
  <div>
    <router-link to="/item/1">新闻1</router-link>
    <router-link to="/item/2">新闻2</router-link>
    <router-link to="/item/3">新闻3</router-link>
  </div>
</template>

1.3.2 嵌套路由

实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路
径也按某种结构对应嵌套的各层组件,例如:

/about/address /about/linkman
+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+ 			   +‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
| About | 						 | About |
| +‐‐‐‐‐‐‐‐‐‐‐‐‐‐+ | 			   | +‐‐‐‐‐‐‐‐‐‐‐‐‐+ |
| | address 	| | +‐‐‐‐‐‐‐‐‐‐‐‐> | | linkman    | |
| | 			| |               | | 			 | |
| +‐‐‐‐‐‐‐‐‐‐‐‐‐‐+ | 				| +‐‐‐‐‐‐‐‐‐‐‐‐‐+ |
+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+ 				+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+
  1. 在src/components下创建address.vue

    <template>
        <div>
        	地址:北京市朝阳区
        </div>
    </template>
    
    创建linkman.vue
    
    <template>
        <div>
        	联系人:小二黑
        </div>
    </template>
    
  2. 修改src/router/index.js

    import linkman from '@/components/linkman'
    import address from '@/components/address'
    
    {
        path: '/about',
        name: 'About',
        component: about,
        children: [
            {path: 'linkman', component: linkman},
            {path: 'address', component: address}
        ]
    }
    
  3. 修改src/components/about.vue

<template>
    <div>
        关于我们
        <router-link to="/about/address" >地址</router-link>
        <router-link to="/about/linkman" >联系人</router-link>
        <router‐view/>
    </div>
</template>

2.Vuex简介

官方的解释: Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

快速理解:每个组件都有它自己数据属性,封装在data()中,每个组件之间data是完全隔离的,是私有的。如果我们需要各个组件都能访问到数据数据,或是需要各个组件之间能互相交换数据,这就需要一个单独存储的区域存放公共属性。这就是状态管理所要解决的问题。

2.1 快速入门

2.1.1 工程搭建

# 创建一个基于 webpack 模板的新项目
vue init webpack vuexdemo
# 安装依赖,走你
cd vuexdemo
cnpm install --save vuex
npm run dev

2.1.2 读取状态值

每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你
的应用中大部分的状态 (state)。

  1. 在src下创建store文件夹,store下创建index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    // 使用vuex
    Vue.use(Vuex)
    
    const store = new Vuex.Store({
        state: {
            count: 0
        }
    })
    
    export default store
    
  2. 修改main.js,引入和装载store

    import Vue from 'vue'
    import App from './App'
    import store from './store/index'
    
    Vue.config.productionTip = false
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      components: { App },
      template: '<App/>',
      store
    })
    
  3. 修改components\HelloWorld.vue

<template>
  <div class="hello">
    {{$store.state.count}}
  </div>
</template>

2.1.3 改变状态值

你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交(commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

  1. 修改store/index.js ,增加mutation定义

    const store = new Vuex.Store({
        state: {
            count: 0
        },
        mutations: {
            increment(state) {
                state.count ++
            }
        }
    })
    
  2. 修改components\HelloWorld.vue ,调用mutation

    <template>
      <div class="hello">
        {{$store.state.count}}
        <button @click='handleStore'>测试</button>
      </div>
    </template>
    
    export default {
      name: 'HelloWorld',
      data () {
        return {
          msg: 'Welcome to Your Vue.js App'
        }
      },
      methods: {
        handleStore() {
          this.$store.commit('increment')
        }
      }
    }
    

    2.1.4 提交载荷

    所谓载荷(payload)就是 向 store.commit 传入额外的参数。

    1.修改store下的index.js

    ......
    mutations: {
        increment (state,x) {
        	state.count += x
        }
    }
    .....
    
    1. 修改HelloWorld.vue

      ......
      addCount(){
          this.$store.commit('increment',10)
          console.log(this.$store.state.count)
      }
      ......
      

    2.1.5 Action

    Action 类似于 mutation,不同在于:

    • Action 提交的是 mutation,而不是直接变更状态。
    • Action 可以包含任意异步操作。

    1.修改store/index.js

    const store = new Vuex.Store({
        .....
        actions: {
            increment (context){
                context.commit('increment',10)
            }
        }
    })
    

    2.修改show.vue

    <template>
        <div>
            show: {{$store.state.count}}
            <button @click="addCount">测试</button>
        </div>
    </template>
    <script>
    export default {
        methods:{
            addCount(){
                this.$store.dispatch('increment')
                console.log(this.$store.state.count)
            }
            
        }
    }
    </script>
    

    2.1.6 Getter

    1. 修改HelloWorld.vue

      remark: {{$store.getters.remark}}
      
    2. 修改store/index.js

      getters: {
          remark(state) {
              if (state.count < 50) {
                  return "加油"
              } else if( state.count < 100 ) {
                  return "你真棒"
              } else {
                  return "你是大神"
              }
          }
      }
      

2.2 模块化

posted @ 2020-05-25 23:07  松间明月447  阅读(418)  评论(0编辑  收藏  举报