我是靠谱客的博主 务实哈密瓜,最近开发中收集的这篇文章主要介绍Vuex的todos案例,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

      • 项目创建
      • 初始渲染页面
      • 对文本框进行双向数据绑定。在index.js定义一个inputValue来存储文本框的值,映射到组件app
      • 接下来在文本框输入内容同步到state里面去
      • 接下来,我们要去实现点击添加事件的操作
      • 向文本框添加内容
      • 完成删除项
      • 复选框状态的绑定
      • 修改任务事项完成的状态
      • 剩余条数
      • 清除已经完成的任务
      • 动态切换按钮的高亮效果
      • 实现动态切换

项目创建

创建的时候记得勾上vuex

vue create vuex-todos 

配置App根组件

<template>
  <div id="app">
    <a-input placeholder="请输入任务" class="my_ipt" />
    <a-button type="primary">添加事项</a-button>

    <a-list bordered :dataSource="list" class="dt_list">
      <a-list-item slot="renderItem" slot-scope="item">
        <!-- 复选框 -->
        <a-checkbox>{{ item.info }}</a-checkbox>
        <!-- 删除链接 -->
        <a slot="actions">删除</a>
      </a-list-item>

      <!-- footer区域 -->
      <div slot="footer" class="footer">
        <!-- 未完成的任务个数 -->
        <span>0条剩余</span>
        <!-- 操作按钮 -->
        <a-button-group>
          <a-button type="primary">全部</a-button>
          <a-button>未完成</a-button>
          <a-button>已完成</a-button>
        </a-button-group>
        <!-- 把已经完成的任务清空 -->
        <a>清除已完成</a>
      </div>
    </a-list>
  </div>
</template>

<script>

export default {
  name: 'app',
  data () {
    return {
    }
  },
}
</script>

<style scoped>
#app {
  padding: 10px;
}

.my_ipt {
  width: 500px;
  margin-right: 10px;
}

.dt_list {
  width: 500px;
  margin-top: 10px;
}

.footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>

配置main.js

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

// 1. 导入 ant-design-vue 组件库
import Antd from 'ant-design-vue'
// 2. 导入组件库的样式表
import 'ant-design-vue/dist/antd.css'
import store from '@/store/index.js'

Vue.config.productionTip = false
// 3. 安装组件库
Vue.use(Antd)

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

配置store的index.js

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

import axios from 'axios'
Vue.use(Vuex)

export default new Vuex.Store({
  state: { },
  mutations: { },
  actions: { },
  modules: { },
})

在public下面新建一个list .json 渲染页面用的

[
    {
      "id": 0,
      "info": "Racing car sprays burning fuel into crowd.",
      "done": true
    },
    { "id": 1, "info": "Japanese princess to wed commoner.", "done": false },
    {
      "id": 2,
      "info": "Australian walks 100km after outback crash.",
      "done": true
    },
    { "id": 3, "info": "Man charged over missing wedding girl.", "done": false },
    { "id": 4, "info": "Los Angeles battles huge wildfires.", "done": false }
  ]

初始渲染页面

app根组件定义了一个created,只要页面加载就会执行created,就只直接通过dispatch调用这个异步函数getList

//去调用actions里面的getList方法,浏览器只要加载页面就会触发created
created () {
    this.$store.dispatch('getList')
  }

通过axios异步获取list.json的数据内容,然后用commit去访问mutations里面的initList方法,并且返回数据data给initList的第二个参数list,initList的第一个参数一定是state,mutations的list赋值给state.list,最后state得到了list的数据

//index.js
import Vue from 'vue'
import Vuex from 'vuex'

import axios from 'axios'
Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    list: []
  },
  mutations: {
    initList (state, list) {
      state.list = list
    }
  },
  actions: {
    // app根组件定义了一个created,只要页面加载就会执行created,就只直接通过dispatch调用这个异步函数getList
    // 通过axios异步获取list.json的数据内容,然后用commit去访问mutations里面的initList方法,并且返回数据data给initList的第二个参数list,initList的第一个参数一定是state,mutations的list赋值给state.list,最后state得到了list的数据
    // 通过mapState把state的list映射到app根组件(先要导入mapState)

    getList (context) {
      axios.get('/list.json').then(({ data }) => {
        console.log(data)
        context.commit('initList', data)
      })
    }
  },
  modules: {
  }
})

通过mapState把state的list映射到app根组件(先要导入mapState),App根组件得到了list,可以渲染页面

<script>
import { mapState } from 'vuex'
export default {
  name: 'app',
  data () {
    return {
    }
  },
  created () {
    this.$store.dispatch('getList')
  },
  computed: {
    ...mapState(['list'])
  }
}
</script>

在这里插入图片描述

在这里插入图片描述

对文本框进行双向数据绑定。在index.js定义一个inputValue来存储文本框的值,映射到组件app

  state: {
    list: [],
    inputValue: 'aaaa'
  }
<script>
import { mapState } from 'vuex'
export default {
  name: 'app',
  data () {
    return {
    }
  },
  //页面加载访问created,调用acyions异步函数
  created () {
    this.$store.dispatch('getList')
  },
  computed: {
    ...mapState(['list', 'inputValue'])
  }
}
</script>

找到文本框,进行绑定 :value="inputValue"

<a-input placeholder="请输入任务" class="my_ipt" :value="inputValue"/>

在这里插入图片描述

接下来在文本框输入内容同步到state里面去

在文本框设置一个监听事件,只要文本框内容发生变化就会监听到打印一下监听内容
定义一个文本框监听事件

   <a-input placeholder="请输入任务" class="my_ipt" :value="inputValue" @change="handelInputChange"/>

文本框监听事件的方法,打印一下e,和文本框变化的内容

//app.vue
 methods: {
    //文本框监听事件的方法,打印一下e,和文本框变化的内容
    handelInputChange (e) {
      console.log('eeeeee', e)
      console.log(e.target.value)
    }
  }

在这里插入图片描述
得到了这个文本框变化的值,我们需要把这个值同步的和state里面的值一起变化

app组件的监听文本框变化用commit来触发mutations参数一是mutations里面定义的方法,参数二是需要给val传过来的值,val得到的值再传给state里面的inputValue

//app.vue
methods: {
    // 文本框监听事件的方法,打印一下e,和文本框变化的内容
    handelInputChange (e) {
      console.log('eeeeee', e)
      console.log(e.target.value)
      //app组件的监听文本框变化用commit来触发mutations,参数一是mutations里面定义的方法,参数二是需要给val传过来的值
      //这个方法可以调用mutations,还可以传递参数
      this.$store.commit('setInputValue', e.target.value)
    }
//index.js
//app组件的监听文本框变化用commit来触发mutations,参数一是mutations里面定义的方法,参数二是需要给val传过来的值,val得到的值再传给state里面的inputValue
//setInputValue里面的参数2把值传给state里面的inputValue
    setInputValue (state, val) {
      state.inputValue = val
    }
  }

在这里插入图片描述

接下来,我们要去实现点击添加事件的操作

添加添加事项点击事件,在methods里面定义方法触发

    <a-button type="primary" @click="addText" >添加事项</a-button>

判断文本框内容是否为空,为空返回提示信息
inputValue是文本框的内容,已经从state映射到computed
trim去除两端空格
$message.warning可以返回为空的打印信息 主要是导入了这个css组件库import 'ant-design-vue/dist/antd.css'

methods: {
    // 文本框监听事件的方法,打印一下e,和文本框变化的内容
    handelInputChange (e) {
      console.log('eeeeee', e)
      console.log(e.target.value)
      // app组件的监听文本框变化用commit来触发mutations,参数一是mutations里面定义的方法,参数二是需要给val传过来的值
      this.$store.commit('setInputValue', e.target.value)
    },
    // 向列表中新增内容
    addText () {
      // 判断文本框内容是否为空,为空返回提示信息
      // inputValue是文本框的内容,已经从state映射到computed
      // trim去除两端空格
      if (this.inputValue.trim().length <= 0) {
        return this.$message.warning('文本框内容不能为空')
      }
    }
  }

请添加图片描述

向文本框添加内容

只要用户点击了添加按钮就会通过$store.commit触发mutations里面的addItem方法

 addText () {
      // 判断文本框内容是否为空,为空返回提示信息
      // inputValue是文本框的内容,已经从state映射到computed
      // trim去除两端空格
      if (this.inputValue.trim().length <= 0) {
        return this.$message.warning('文本框内容不能为空')
      }

      //只要用户点击了添加按钮就会通过$store.commit触发mutations里面的addItem方法
      this.$store.commit('addItem')
    }

addText触发了mutations的addItem,每点击一次就会向list添加一个新对象

 mutations: {
    initList (state, list) {
      state.list = list
    },

    // app组件的监听文本框变化用commit来触发mutations,参数一是mutations里面定义的方法,参数二是需要给val传过来的值,val得到的值再传给state里面的inputValue
    // setInputValue里面的参数2把值传给state里面的inputValue
    setInputValue (state, val) {
      state.inputValue = val
    },

    addItem (state) {
      //定义一个对象,最后添加到列表,里面要有id,info(文本框内容inputValue),done(在这里默认是fales)
      const listObj = {
        id: state.next_id,
        info: state.inputValue.trim(),
        done: false
      }
      //添加到list里面去
      state.list.push(listObj)
      //每添加一个对象到list id++
      state.next_id++
      //每添加一个对象到list 文本框内容置为空
      state.inputValue = ''
    }
  }

请添加图片描述

完成删除项

我们通过item传过来的id来指定删除那一项,在删除定义一个点击事件

 <a slot="actions" @click="removeItemId(item.id)">删除</a>

在methods定义方法,打印点击后那一项的id

methods: {
    //通过item传过来的id来指定删除那一项
    removeItemId (id) {
      console.log(id)
    }
  }

请添加图片描述
用这个方法去触发mutations里面的删除方法,并且传过去要删除项的id进行对比是否雨state里面的id相对应,如果相同就赋值给一个变量,我把它称为变量id,接着判断是否存在这个变量id,如果存在,删除当前变量id项

  methods: {
    // 文本框监听事件的方法,打印一下e,和文本框变化的内容
    handelInputChange (e) {
      console.log('eeeeee', e)
      console.log(e.target.value)
      // app组件的监听文本框变化用commit来触发mutations,参数一是mutations里面定义的方法,参数二是需要给val传过来的值
      this.$store.commit('setInputValue', e.target.value)
    },
    // 向列表中新增内容
    addText () {
      // 判断文本框内容是否为空,为空返回提示信息
      // inputValue是文本框的内容,已经从state映射到computed
      // trim去除两端空格
      if (this.inputValue.trim().length <= 0) {
        return this.$message.warning('文本框内容不能为空')
      }

      // 只要用户点击了添加按钮就会通过$store.commit触发mutations里面的addItem方法
      this.$store.commit('addItem')
    },
    // 通过item传过来的id来指定删除那一项
    removeItemId (id) {
      this.$store.commit('removeItem', id)
      console.log(id)
    }
  }
 mutations: {
    initList (state, list) {
      state.list = list
    },

    // app组件的监听文本框变化用commit来触发mutations,参数一是mutations里面定义的方法,参数二是需要给val传过来的值,val得到的值再传给state里面的inputValue
    // setInputValue里面的参数2把值传给state里面的inputValue
    setInputValue (state, val) {
      state.inputValue = val
    },

    addItem (state) {
      // 定义一个对象,最后添加到列表,里面要有id,info(文本框内容inputValue),done(在这里默认是fales)
      const listObj = {
        id: state.next_id,
        info: state.inputValue.trim(),
        done: false
      }
      // 添加到list里面去
      state.list.push(listObj)
      // 每添加一个对象到list id++
      state.next_id++
      // 每添加一个对象到list 文本框内容置为空
      state.inputValue = ''
    },
    // 根据id删除对应的任务事项
    removeItem (state, id) {
      // findIndex去查询list里面的每一个id,如果会等于传过来的id那就通过变量接收
      const idIndex = state.list.findIndex(x => x.id === id)
      // 如果存在idIndex的话,那就执行删除项,删除该id的删除项
      if (idIndex !== -1) {
        state.list.splice(idIndex, 1)
      }
    }
  }

请添加图片描述

复选框状态的绑定

 <a-checkbox :checked="item.done">{{ item.info }}</a-checkbox>

在这里插入图片描述

修改任务事项完成的状态

监听复选框选中状态,只要点击了复选框按钮,就会触发cbStatusChanged方法,这个方法可以监听复选框状态发生的最新变化,把change接收到的事件对象e 传给cbStatusChanged

  <a-checkbox :checked="item.done" @change="(e)=>{cbStatusChanged(e)}">{{ item.info }}</a-checkbox>

在methods定义这个方法去监听复选框最新状态,这里我们打印出来是true还是false

//通过e.target.checked可以接收到最新的选中状态
    cbStatusChanged (e) {
      console.log(e.target.checked)
    }

接下里,我们需要知道我们点击复选框的id是哪一项,所以不仅仅要传事件对象e,还要传id

<a-checkbox :checked="item.done" @change="(e)=>{cbStatusChanged(e,item.id)}">{{ item.info }}</a-checkbox>

打印出被改变选中id和被选中的状态

// 通过e.target.checked可以接收到最新的选中状态
    cbStatusChanged (e, id) {
      console.log(e.target.checked, id)
    }

通过这个方法可以cbStatusChanged触发commit触发mutations里面的changeStatus,定义一个对象,传给changeStatus的params,参数1是id,参数2是选中状态

 cbStatusChanged (e, id) {
      console.log(e.target.checked, id)
      //定义一个对象,传给changeStatus的params,参数1是id,参数2是选中状态
      const param = {
        id: id,
        status: e.target.checked
      }
      this.$store.commit('changeStatus', param)
    }
  }
  methods: {
    // 文本框监听事件的方法,打印一下e,和文本框变化的内容
    handelInputChange (e) {
      console.log('eeeeee', e)
      console.log(e.target.value)
      // app组件的监听文本框变化用commit来触发mutations,参数一是mutations里面定义的方法,参数二是需要给val传过来的值
      this.$store.commit('setInputValue', e.target.value)
    },
    // 向列表中新增内容
    addText () {
      // 判断文本框内容是否为空,为空返回提示信息
      // inputValue是文本框的内容,已经从state映射到computed
      // trim去除两端空格
      if (this.inputValue.trim().length <= 0) {
        return this.$message.warning('文本框内容不能为空')
      }

      // 只要用户点击了添加按钮就会通过$store.commit触发mutations里面的addItem方法
      this.$store.commit('addItem')
    },
    // 通过item传过来的id来指定删除那一项
    removeItemId (id) {
      this.$store.commit('removeItem', id)
      console.log(id)
    },
    // 通过e.target.checked可以接收到最新的选中状态
    cbStatusChanged (e, id) {
      console.log(e.target.checked, id)
      // 定义一个对象,传给changeStatus的params,参数1是id,参数2是选中状态
      const param = {
        id: id,
        status: e.target.checked
      }
      this.$store.commit('changeStatus', param)
    }
  }

修改列表的选中状态

  mutations: {
    initList (state, list) {
      state.list = list
    },

    // app组件的监听文本框变化用commit来触发mutations,参数一是mutations里面定义的方法,参数二是需要给val传过来的值,val得到的值再传给state里面的inputValue
    // setInputValue里面的参数2把值传给state里面的inputValue
    setInputValue (state, val) {
      state.inputValue = val
    },

    addItem (state) {
      // 定义一个对象,最后添加到列表,里面要有id,info(文本框内容inputValue),done(在这里默认是fales)
      const listObj = {
        id: state.next_id,
        info: state.inputValue.trim(),
        done: false
      }
      // 添加到list里面去
      state.list.push(listObj)
      // 每添加一个对象到list id++
      state.next_id++
      // 每添加一个对象到list 文本框内容置为空
      state.inputValue = ''
    },
    // 根据id删除对应的任务事项
    removeItem (state, id) {
      // findIndex去查询list里面的每一个id,如果会等于传过来的id那就通过变量接收
      const idIndex = state.list.findIndex(x => x.id === id)
      // 如果存在idIndex的话,那就执行删除项,删除该id的删除项
      if (idIndex !== -1) {
        state.list.splice(idIndex, 1)
      }
    },
    // 修改列表的选中状态
    changeStatus (state, param) {
      const idIndex = state.list.findIndex(x => x.id === param.id)
      state.list[idIndex].done = param.status
    }
  }

请添加图片描述

剩余条数

猪index.js定义一个getters,对每一项done进行过滤

getters: {
    // 统计没有完成的任务的条数
    unDoneLength (state) {
      return state.list.filter(x => x.done === false).length
    }
  }

把过滤的内容映射到app里

import { mapState, mapGetters } from 'vuex'
 computed: {
 //列表内容和文本框内容的映射
    ...mapState(['list', 'inputValue']),
    //剩余条数的映射
    ...mapGetters(['unDoneLength'])
  
  <span>{{unDoneLength}}条剩余</span>

请添加图片描述

清除已经完成的任务

先要在清除已完成的a标签设置点击事件,定义方法clearFinshItem,commit触发mutations里面的方法clearFinshItemDone

clearFinshItem () {
      this.$store.commit('clearFinshItemDone')
    }

通过过滤,把没有选中为false的过滤出来,重新赋值给state.list

 // 清除已经完成的任务
    clearFinshItemDone (state) {
      state.list = state.list.filter(x => x.done === false)
    }

请添加图片描述

动态切换按钮的高亮效果

showItemList (key) {
      console.log(key)
      this.$store.commit('showList', key)
    }
 // 修改试图关键字,参数2:外界传进来的key
    showList (state, key) {
      state.viewKey = key
    }
state: {
    // 渲染列表
    list: [],
    // 文本框的内容
    inputValue: 'qxtzmr',
    // id 在下面每添加一项自增1
    next_id: 5,
    viewKey: 'all'
  }
 computed: {
    ...mapState(['list', 'inputValue', 'viewKey']),
    ...mapGetters(['unDoneLength'])
  }
<a-button-group>
          <a-button :type="viewKey==='all'? 'primary' :'default' " @click="showItemList('all')">全部</a-button>
          <a-button :type="viewKey==='unfinsh'?'primary':'default'"  @click="showItemList('unfinsh')">未完成</a-button>
          <a-button :type="viewKey==='finsh'?'primary':'default'"  @click="showItemList('finsh')">已完成</a-button>
 </a-button-group>

请添加图片描述

实现动态切换

getters: {
    // 统计没有完成的任务的条数
    unDoneLength (state) {
      return state.list.filter(x => x.done === false).length
    },
    infoList (state) {
      if (state.viewKey === 'all') {
        return state.list
      }
      //! x.done 就是 false
      if (state.viewKey === 'unfinsh') {
        return state.list.filter(x => !x.done)
      }
      if (state.viewKey === 'finsh') {
        return state.list.filter(x => x.done)
      }

      // 如果三者都不是 直接返回全部
      return state.list
    }
  }
computed: {
    ...mapState(['inputValue', 'viewKey']),
    ...mapGetters(['unDoneLength', 'infoList'])
  }
    <a-list bordered :dataSource="infoList" class="dt_list">

请添加图片描述

最后

以上就是务实哈密瓜为你收集整理的Vuex的todos案例的全部内容,希望文章能够帮你解决Vuex的todos案例所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部