概述
文章目录
- 项目创建
- 初始渲染页面
- 对文本框进行双向数据绑定。在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案例所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复