vuex-stepbystep 经典案例,详细注释一步到位

栏目: JavaScript · 发布时间: 7年前

Vuex

是什么(官网已经很完善了)

Vuex

为什么要使用 Vuex

Vuex

Vuex 的说明

  • Vuex 采用集中的方式统一管理了项目中所有需要共享的数据,只要组件之间相同共享数据就要通过 Vuex 才能实现
  • 可预测性
  • 可以简单理解为 Vuex 是一个增强版的 bus

状态管理

  • 前端最早的状态管理思想是由 React 的 Flux 提出来的
  • Flux 不仅提出了 前端状态管理的思想,也提供对应的实现
  • 其他状态管理库: Flux / Redux / Mobx / Vuex

actions 和 mutations 的区别

Vuex 中的核心概念

  • store

Vuex 的特点

  • Vuex 中的数据也是响应式的(双向绑定的)

案例搭建

  • 技术点
    • vuex
    • vue-cli 2.0
    • todos 模板
  • 项目目录
vuex-stepbystep 经典案例,详细注释一步到位
  • 然后我们开始搭建项目,使用vue-cli的步骤,就跳上过了,楼主在vue-admin教程中有详细步骤,现在我们在src目录下新建store文件夹,然后新建index.js文件,然后我们初始化store,代码如下
vuex-stepbystep 经典案例,详细注释一步到位
import Vue from 'vue'//引入vue
import Vuex from 'vuex'//引入vuex

// 安装
Vue.use(Vuex)

// 初始化state
const state = {}

// mutations
const mutations = {}

// 创建store把state和mutation 写入Vuex.store中
const store = new Vuex.Store({
  state,
  mutations
})

export default store //导出store
复制代码
  • 然后我们在main.js引入,挂载到vue的实例中
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'

// 导入样式
import '@/assets/index.css'

// 导入store
import store from './store'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  // 将 Vuex(store) 和 Vue实例关联到一起
  store,
  components: { App },
  template: '<App/>'
})

复制代码
  • 然后配置App.vue,把todos模板组件导入App.vue中,我们的store就配置好了
    vuex-stepbystep 经典案例,详细注释一步到位

功能完成

  • 效果图 (ps:经典到吐)
    vuex-stepbystep 经典案例,详细注释一步到位
  • 我们现在完善store,把数据填入,进行增删更新的一些状态的统一操作。
import Vue from 'vue'//引入vue
import Vuex from 'vuex'//引入vuex

// 安装
Vue.use(Vuex)

// 初始化state
const state = {
  todos: [
    { id: 1, name: '秃头', done: false },
    { id: 2, name: '女朋友跑了', done: false },
    { id: 3, name: '左手更加的有力', done: true }
  ]
}

// mutations配置
const mutations = {
  // 根据id修改完任务的成状态
  changeDone(state, payload) {
    // 1 根据id找到当前任务
    const curTodo = state.todos.find(item => item.id === payload.id) //箭头函数了解下
    // 2 状态直接取反即可
    curTodo.done = !curTodo.done
  },

  // 添加任务方法
  addTodo(state, payload) {
    const length = state.todos.length
    const id = length === 0 ? 1 : state.todos[length - 1].id + 1

    state.todos.push({
      id,
      name: payload.name,
      done: false
    })
  },

  // 删除任务方法
  delTodo(state, payload) {
    state.todos.splice(payload.index, 1)
  },

  // 更新任务方法
  updateTodo(state, payload) {
    // 查找到当前要更新的任务
    const curTodo = state.todos.find(item => item.id === payload.id)
    // 修改名称
    curTodo.name = payload.name
  },

  // 清除已完成任务
  clearAllDone(state) {
    state.todos = state.todos.filter(item => !item.done)
  }
}

// actions 异步操作(面试考察点)
// 内部还是提交的 mutations
const actions = {
  // 异步添加任务
  addTodoAsync(context, payload) {
    // setTimeout就是一个异步操作, 内部还是提交的 mutations
    setTimeout(() => {
      context.commit('addTodo', {
        name: payload.name
      })
    }, 2000)
  }
}

// getters
// 相当于Vue组件中的 计算属性 ,用法完全相同
// 当需要从现有的state中得到一些新的数据(比如:从 todos 集合中,得到未完成任务数量)
// 就要使用 getters ,也就是计算属性
const getters = {
  // 未完成任务数量
  unDoneCount(state) {
    return state.todos.filter(item => !item.done).length
  },

  // 控制清除已完成任务按钮的展示和隐藏
  showClearDone(state) {
    return state.todos.some(item => item.done)
  }
}

// 创建store
const store = new Vuex.Store({
  // 开启严格模式
  // 开发期间 NODE_ENV 的值为: 'development'
  // 生成环境中 NODE_ENV 的值为: 'production'
  strict: process.env.NODE_ENV !== 'production',
  state,
  mutations,
  actions,
  getters
})

export default store

复制代码
  • 然后我们进行TodoHeader的添加操作
    vuex-stepbystep 经典案例,详细注释一步到位
<template>
  <header class="header">
    <h1>todos</h1>
    <input 
      <!--数据绑定,对应data中的数据-->
		v-model="todoName" 
		<!--enter修饰符,绑定时间-->
		@keyup.enter="addTodo"
		 class="new-todo" 
		 placeholder="What needs to be done?"
		 <!--自动聚焦-->
		 autofocus>
  </header>
</template>

<script>
export default {
  data() {
    return {
      // 因为这个数据只会在当前组件中使用
      // 因此,就不需要放到 Vuex 中
      todoName: ''
    }
  },

  methods: {
    // 添加任务
    addTodo() {
    //input输入框通常我们会trim一下,把空格干掉
      if (this.todoName.trim() === '') {
        return
      }

      // 调用 Vuex 中提供的 mutations 即可(在组件中,通过$store.commit方法来执行mutation)
      // this.$store.commit('addTodo', {
      //   name: this.todoName
      // })

      // 调用 actions 来完成,异步添加(action在组件内通过$store.dispatch触发)
      this.$store.dispatch('addTodoAsync', {
        name: this.todoName
      })

      this.todoName = ''//完成之后,清空input框的内容
    }
  }
}
</script>
复制代码
  • 然后我们操作列表组件TodoList
vuex-stepbystep 经典案例,详细注释一步到位
<template>
  <section class="main">
    <input id="toggle-all" class="toggle-all" type="checkbox">
    <label for="toggle-all">Mark all as complete</label>
    <ul class="todo-list">
      <!--
        完成状态: completed
        编辑状态: editing
       -->
      <li 
			:class="{ completed: todo.done, editing: todo.id === editId }"
			 v-for="(todo, index) in $store.state.todos" 
			 :key="todo.id">
        <div class="view">
          <!--
            前提:因为我们知道 Vuex 中的数据,只能通过 mutations 中提供的方法来修改
            因为在 checkbox 中使用了 v-model,v-model是双向绑定的,当点击 复选框 的时候,会将其对应的数据修改,
            这样就违背了 Vuex 中数据只能由 mutations 修改这个原则了!!!

            数据 -> 视图: :checked="todo.done" (单向)
            视图 -> 数据: 先绑定一个事件,在事件中调用 mutations 来完成数据修改
           -->
          <input 
					class="toggle"
					 type="checkbox"
					 :checked="todo.done"
					 @change="changeDone(todo.id)">
          <!-- <input class="toggle" type="checkbox" v-model="todo.done"> -->
          <label @dblclick="showEditStatus(todo.id)">{{ todo.name }}</label>
          <button class="destroy" @click="delTodo(index)"></button>
        </div>
        <input class="edit" :value="todo.name" @keyup.enter="updateTodo(todo.id, index)" ref="todoUpdate">
      </li>
    </ul>
  </section>
</template>

<script>
export default {
  data() {
    return {
      // 临时变量,用来处理编辑状态
      editId: -1
    }
  },
  methods: {
    // 出现编辑状态
    showEditStatus(id) {
      this.editId = id
    },

    // 更新任务名称
    updateTodo(id, index) {
      // 根据索引号找到对应的文本框
      const name = this.$refs.todoUpdate[index].value

      this.$store.commit('updateTodo', {
        id,
        name
      })

      // 去掉编辑状态
      this.editId = -1
    },

    // 切换完成状态
    changeDone(id) {
      // 调用 mutations 中提供的方法,来修改state中的数据
      this.$store.commit('changeDone', {
        id
      })
    },

    // 删除任务
    delTodo(index) {
      this.$store.commit('delTodo', {
        index
      })
    }
  }
}
</script
<style>
</style>

复制代码
  • 底部就一个清除,直接贴代码了
export default {
  methods: {
    // 清除所有已完成任务
    clearAllDone() {
      this.$store.commit('clearAllDone')
    }
  }
}
复制代码

结语

  • 我看了有些,博文,感觉把vueX都神话了,各位小伙伴把我这篇教程看完,其实就这些东西。
  • 大项目确实很方便,具体使用:按需使用。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Cyberwar

Cyberwar

Kathleen Hall Jamieson / Oxford University Press / 2018-10-3 / USD 16.96

The question of how Donald Trump won the 2016 election looms over his presidency. In particular, were the 78,000 voters who gave him an Electoral College victory affected by the Russian trolls and hac......一起来看看 《Cyberwar》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具