实验5:Vuex状态管理

Web前端开发技术课程实验报告

实验5Vuex状态管理

一、实验目的:

  1. 掌握Vuex的工作原理和5个核心概念。
  2. 掌握Vuex API接口的使用方法。

二、实验要求:

  1. 掌握mutations、actions、getters的定义和使用方法,完成以下实验内容。
  2. 上交实验报告电子文档。文档包含源程序,以班级、学号后两位、姓名依次出现组成的字符串如“计算机20-1班01张三实验5” 标识。各班学委收齐本班本次实验后进行打包(打包文件为.rar或.zip类型),使用名称如“1班Web前端开发技术实验5”提交。

三、实验内容:

    1. 模拟购物。如图所示,点击“加入购物车”可将相应物品放入购物车,并显示页面购物车中商品数量。

2. 模拟待办事项提醒。如图所示,在输入框中输入计划如“上午10点有课”,点击“+”可增加待计划;点击计划下方按钮,可显示当前计划和显示全部计划,点击“×”可删除全部计划。

四、实验过程中遇到的问题及解决手段:

1.报错如图1

                                                               图1

解决方法:数组是用push添加元素如图2,把put改成push即可

                                                               图2

五、实验结果和源码

1、实验1

1.1实验结果如图3、图4

                                                               图3

                                                   图4

1.2实验源码

Components的Count.vue

<template>

    <div>

        <h1>购物车商品数量:{{$store.state.cart.length}}</h1>

        <hr/>

        <div id="p1">

            <div v-for="s in shangpin">

            {{s}}<button @click="Addgoods(s)">加入购物车</button>

            </div>

        </div>

       

        <div id="p2">

            <div v-for="c in $store.state.cart ">

                {{c}}<br/>

            </div>

            <button>确定下单</button>

        </div>

    </div>

</template>

<script>

    export default {

        name:'Count',

        data() {

            return {

                shangpin:["华为Mate40 Pro","iphone 12 pro","小米11 Ultra","vivo S9"]

            }

        },

        methods: {

       

            Addgoods(s){

                this.$store.dispatch('jiaOdd',s)

            },

   

        },

        mounted() {

            console.log('Count',this)

        },

    }

</script>

<style lang="css">

    button{

        margin-left: 5px;

    }

    #p1{

        width:300px;

        height:auto;

        float:left;

        display:inline;

    }

    #p2{

        width:300px;

        height:auto;

        float:left;

        display:inline;

        border: 1px dashed black;

        background-color: rgb(211, 210, 210);

       

    }

</style>

Store/index.js

//该文件用于创建Vuex中最为核心的store

import Vue from 'vue'

//引入Vuex

import Vuex from 'vuex'

//应用Vuex插件

Vue.use(Vuex)

//准备actions——用于响应组件中的动作

const actions = {

   

    jiaOdd(context,value){

        console.log('actions中的jiaOdd被调用了')

            context.commit('JIA',value)

       

    },

}

//准备mutations——用于操作数据(state

const mutations = {

    JIA(state,value){

        console.log('mutations中的JIA被调用了');

        state.cart.push(value)

       

    },

   

}

//准备state——用于存储数据

const state = {

    cart:[] //当前的和

}

//创建并暴露store

export default new Vuex.Store({

    actions,

    mutations,

    state,

})

App.vue

<template>

    <div>

        <Count/>

    </div>

</template>

<script>

    import Count from './components/Count'

    export default {

        name:'App',

        components:{Count},

        mounted() {

            // console.log('App',this)

        },

    }

</script>

main.js

//引入Vue

import Vue from 'vue'

//引入App

import App from './App.vue'

//引入插件

import vueResource from 'vue-resource'

//引入store

import store from './store'

//关闭Vue的生产提示

Vue.config.productionTip = false

//使用插件

Vue.use(vueResource)

//创建vm

new Vue({

    el:'#app',

    render: h => h(App),

    store,

    beforeCreate() {

        Vue.prototype.$bus = this

    }

})

2.实验2

2.2实验结果如图5、图6、图7

图5

图6

2

图7

2.2实验源码

MyFooter.vue

<template>

    <div class="todo-footer" v-show="total">

        <label>

            <!-- <input type="checkbox" :checked="isAll" @change="checkAll"/> -->

            <input type="checkbox" v-model="isAll"/>

        </label>

        <span>

            <span>已完成{{doneTotal}}</span> / 全部{{total}}

        </span>

        <button class="btn btn-danger" @click="clearAll">清除已完成任务</button>

    </div>

</template>

<script>

    export default {

        name:'MyFooter',

        props:['todos'],

        computed: {

            //总数

            total(){

                return this.todos.length

            },

            //已完成数

            doneTotal(){

                //此处使用reduce方法做条件统计

                /* const x = this.todos.reduce((pre,current)=>{

                    console.log('@',pre,current)

                    return pre + (current.done ? 1 : 0)

                },0) */

                //简写

                return this.todos.reduce((pre,todo)=> pre + (todo.done ? 1 : 0) ,0)

            },

            //控制全选框

            isAll:{

                //全选框是否勾选

                get(){

                    return this.doneTotal === this.total && this.total > 0

                },

                //isAll被修改时set被调用

                set(value){

                    // this.checkAllTodo(value)

                    this.$emit('checkAllTodo',value)

                }

            }

        },

        methods: {

            /* checkAll(e){

                this.checkAllTodo(e.target.checked)

            } */

            //清空所有已完成

            clearAll(){

                // this.clearAllTodo()

                this.$emit('clearAllTodo')

            }

        },

    }

</script>

<style scoped>

    /*footer*/

    .todo-footer {

        height: 40px;

        line-height: 40px;

        padding-left: 6px;

        margin-top: 5px;

    }

    .todo-footer label {

        display: inline-block;

        margin-right: 20px;

        cursor: pointer;

    }

    .todo-footer label input {

        position: relative;

        top: -1px;

        vertical-align: middle;

        margin-right: 5px;

    }

    .todo-footer button {

        float: right;

        margin-top: 5px;

    }

</style>

Myheader.vue

<template>

    <div class="todo-header">

        <input type="text" placeholder="请输入你的计划内容" v-model="title" @keyup.enter="add"/>

    </div>

</template>

<script>

    import {nanoid} from 'nanoid'

    export default {

        name:'MyHeader',

        data() {

            return {

                //收集用户输入的title

                title:''

            }

        },

        methods: {

            add(){

                //校验数据

                if(!this.title.trim()) return alert('输入不能为空')

                //将用户的输入包装成一个todo对象

                const todoObj = {id:nanoid(),title:this.title,done:false}

                //通知App组件去添加一个todo对象

                this.$emit('addTodo',todoObj,1,2,3)

                //清空输入

                this.title = ''

            }

        },

    }

</script>

<style scoped>

    /*header*/

    .todo-header input {

        width: 560px;

        height: 28px;

        font-size: 14px;

        border: 1px solid #ccc;

        border-radius: 4px;

        padding: 4px 7px;

    }

    .todo-header input:focus {

        outline: none;

        border-color: rgba(82, 168, 236, 0.8);

        box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);

    }

</style>

Myitem.vue

<template>

    <li>

        <label>

            <input type="checkbox" :checked="todo.done" @change="handleCheck(todo.id)"/>

            <!-- 如下代码也能实现功能,但是不太推荐,因为有点违反原则,因为修改了props -->

            <!-- <input type="checkbox" v-model="todo.done"/> -->

            <span v-show="!todo.isEdit">{{todo.title}}</span>

            <input

                type="text"

                v-show="todo.isEdit"

                :value="todo.title"

                @blur="handleBlur(todo,$event)"

                ref="inputTitle"

            >

        </label>

        <button class="btn btn-danger" @click="handleDelete(todo.id)">删除</button>

        <button v-show="!todo.isEdit" class="btn btn-edit" @click="handleEdit(todo)">编辑</button>

    </li>

</template>

<script>

    import pubsub from 'pubsub-js'

    export default {

        name:'MyItem',

        //声明接收todo

        props:['todo'],

        methods: {

            //勾选or取消勾选

            handleCheck(id){

                //通知App组件将对应的todo对象的done值取反

                // this.checkTodo(id)

                this.$bus.$emit('checkTodo',id)

            },

            //删除

            handleDelete(id){

                if(confirm('确定删除吗?')){

                    //通知App组件将对应的todo对象删除

                    // this.deleteTodo(id)

                    // this.$bus.$emit('deleteTodo',id)

                    pubsub.publish('deleteTodo',id)

                }

            },

            //编辑

            handleEdit(todo){

                if(todo.hasOwnProperty('isEdit')){

                    todo.isEdit = true

                }else{

                    // console.log('@')

                    this.$set(todo,'isEdit',true)

                }

                this.$nextTick(function(){

                    this.$refs.inputTitle.focus()

                })

            },

            //失去焦点回调(真正执行修改逻辑)

            handleBlur(todo,e){

                todo.isEdit = false

                if(!e.target.value.trim()) return alert('输入不能为空!')

                this.$bus.$emit('updateTodo',todo.id,e.target.value)

            }

        },

    }

</script>

<style scoped>

    /*item*/

    li {

        list-style: none;

        height: 36px;

        line-height: 36px;

        padding: 0 5px;

        border-bottom: 1px solid #ddd;

    }

    li label {

        float: left;

        cursor: pointer;

    }

    li label li input {

        vertical-align: middle;

        margin-right: 6px;

        position: relative;

        top: -1px;

    }

    li button {

        float: right;

        display: none;

        margin-top: 3px;

    }

    li:before {

        content: initial;

    }

    li:last-child {

        border-bottom: none;

    }

    li:hover{

        background-color: #ddd;

    }

   

    li:hover button{

        display: block;

    }

</style>

Mylist.vue

<template>

    <ul class="todo-main">

        <transition-group name="todo" appear>

            <MyItem

                v-for="todoObj in todos"

                :key="todoObj.id"

                :todo="todoObj"

            />

        </transition-group>

    </ul>

</template>

<script>

    import MyItem from './MyItem'

    export default {

        name:'MyList',

        components:{MyItem},

        //声明接收App传递过来的数据

        props:['todos']

    }

</script>

<style scoped>

    /*main*/

    .todo-main {

        margin-left: 0px;

        border: 1px solid #ddd;

        border-radius: 2px;

        padding: 0px;

    }

    .todo-empty {

        height: 40px;

        line-height: 40px;

        border: 1px solid #ddd;

        border-radius: 2px;

        padding-left: 5px;

        margin-top: 10px;

    }

    .todo-enter-active{

        animation: atguigu 0.5s linear;

    }

    .todo-leave-active{

        animation: atguigu 0.5s linear reverse;

    }

    @keyframes atguigu {

        from{

            transform: translateX(100%);

        }

        to{

            transform: translateX(0px);

        }

    }

</style>

App.vue

<template>

    <div id="root">

        <div class="todo-container">

            <div class="todo-wrap">

                <MyHeader @addTodo="addTodo"/>

                <MyList :todos="todos"/>

                <MyFooter :todos="todos" @checkAllTodo="checkAllTodo" @clearAllTodo="clearAllTodo"/>

            </div>

        </div>

    </div>

</template>

<script>

    import pubsub from 'pubsub-js'

    import MyHeader from './components/MyHeader'

    import MyList from './components/MyList'

    import MyFooter from './components/MyFooter'

    export default {

        name:'App',

        components:{MyHeader,MyList,MyFooter},

        data() {

            return {

                //由于todosMyHeader组件和MyFooter组件都在使用,所以放在App中(状态提升)

                todos:JSON.parse(localStorage.getItem('todos')) || []

            }

        },

        methods: {

            //添加一个todo

            addTodo(todoObj){

                this.todos.unshift(todoObj)

            },

            //勾选or取消勾选一个todo

            checkTodo(id){

                this.todos.forEach((todo)=>{

                    if(todo.id === id) todo.done = !todo.done

                })

            },

            //更新一个todo

            updateTodo(id,title){

                this.todos.forEach((todo)=>{

                    if(todo.id === id) todo.title = title

                })

            },

            //删除一个todo

            deleteTodo(_,id){

                this.todos = this.todos.filter( todo => todo.id !== id )

            },

            //全选or取消全选

            checkAllTodo(done){

                this.todos.forEach((todo)=>{

                    todo.done = done

                })

            },

            //清除所有已经完成的todo

            clearAllTodo(){

                this.todos = this.todos.filter((todo)=>{

                    return !todo.done

                })

            }

        },

        watch: {

            todos:{

                deep:true,

                handler(value){

                    localStorage.setItem('todos',JSON.stringify(value))

                }

            }

        },

        mounted() {

            this.$bus.$on('checkTodo',this.checkTodo)

            this.$bus.$on('updateTodo',this.updateTodo)

            this.pubId = pubsub.subscribe('deleteTodo',this.deleteTodo)

        },

        beforeDestroy() {

            this.$bus.$off('checkTodo')

            this.$bus.$off('updateTodo')

            pubsub.unsubscribe(this.pubId)

        },

    }

</script>

<style>

    /*base*/

    body {

        background: #fff;

    }

    .btn {

        display: inline-block;

        padding: 4px 12px;

        margin-bottom: 0;

        font-size: 14px;

        line-height: 20px;

        text-align: center;

        vertical-align: middle;

        cursor: pointer;

        box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);

        border-radius: 4px;

    }

    .btn-danger {

        color: #fff;

        background-color: #da4f49;

        border: 1px solid #bd362f;

    }

    .btn-edit {

        color: #fff;

        background-color: skyblue;

        border: 1px solid rgb(103, 159, 180);

        margin-right: 5px;

    }

    .btn-danger:hover {

        color: #fff;

        background-color: #bd362f;

    }

    .btn:focus {

        outline: none;

    }

    .todo-container {

        width: 600px;

        margin: 0 auto;

    }

    .todo-container .todo-wrap {

        padding: 10px;

        border: 1px solid #ddd;

        border-radius: 5px;

    }

</style>

Main.js

//引入Vue

import Vue from 'vue'

//引入App

import App from './App.vue'

//关闭Vue的生产提示

Vue.config.productionTip = false

//创建vm

new Vue({

    el:'#app',

    render: h => h(App),

    beforeCreate() {

        Vue.prototype.$bus = this

    },

})

五、本次实验的体会(结论):

通过这次实验我掌握了Vuex的工作原理和5个核心概念,掌握了Vuex API接口的使用方法。同时明白了只有自己亲自动手去编写程序才能把书本的内容与实际结合起来,才能更容易的把知识牢记于心。在动手真正的去编程往往会发生各种各样的问题,如果不去实践就会永远堆积问题,停滞不前,就会落后。编程需要沉淀,不能急功近利,欲速则不达,花时间打好基础,基础不牢地动山摇。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/36692.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入解析 Linux 声卡驱动:从架构到实战

在嵌入式 Linux 设备中&#xff0c;音频功能的实现离不开 Linux 声卡驱动。而 ALSA (Advanced Linux Sound Architecture) 作为 Linux 内核的音频框架&#xff0c;提供了一整套 API 和驱动模型&#xff0c;帮助开发者快速集成音频功能。本篇文章以 WM8960 音频编解码器&#xf…

windows+ragflow+deepseek实战之一excel表查询

ragflows平台部署参考文章 Win10系统Docker+DeepSeek+ragflow搭建本地知识库 ragflow通过python实现参考这篇文章 ragflow通过python实现 文章目录 背景效果1、准备数据2、创建知识库3、上传数据并解析4、新建聊天助理5、测试会话背景 前面已经基于Win10系统Docker+DeepSeek+…

【VUE】ant design vue实现表格table上下拖拽排序

适合版本&#xff1a;ant design vue 1.7.8 实现效果&#xff1a; 代码&#xff1a; <template><div class"table-container"><a-table:columns"columns":dataSource"tableData":rowKey"record > record.id":row…

vue3+Ts+elementPlus二次封装Table分页表格,表格内展示图片、switch开关、支持

目录 一.项目文件结构 二.实现代码 1.子组件&#xff08;表格组件&#xff09; 2.父组件&#xff08;使用表格&#xff09; 一.项目文件结构 1.表格组件&#xff08;子组件&#xff09;位置 2.使用表格组件的页面文件&#xff08;父组件&#xff09;位置 3.演示图片位置 ele…

ModBus TCP/RTU互转(主)(从)|| Modbus主动轮询下发的工业应用 || 基于智能网关的串口服务器进行Modbus数据收发的工业应用

目录 前言 一、ModBus TCP/RTU互转&#xff08;从&#xff09;及应用|| 1.1 举栗子 二、ModBus TCP/RTU互转&#xff08;主&#xff09; 2.1 举栗子 三、ModBus 主动轮询 3.1 Modbus主动轮询原理 3.2 Modbus格式上传与下发 3.2.1.设置Modbus主动轮询指令 3.2.2 设…

Elasticsearch 在航空行业:数据管理的游戏规则改变者

作者&#xff1a;来自 Elastic Adam La Roche 数字化客户体验不再是奢侈品&#xff0c;而是欧洲航空公司必不可少的需求。它推动了客户满意度&#xff0c;提升了运营效率&#xff0c;并创造了可持续的竞争优势。随着行业的不断发展&#xff0c;优先投资前沿数字技术和平台的航空…

CXL协议之FM(Fabric Management)解释

CXL协议中的FM功能详解 1. FM的核心作用 FM是CXL&#xff08;Compute Express Link&#xff09;架构中的核心管理实体&#xff0c;负责协调和管理CXL设备之间的通信、资源分配及拓扑结构。其核心功能包括&#xff1a; 设备发现与枚举&#xff1a;识别CXL拓扑中的设备&#x…

html5基于Canvas的经典打砖块游戏开发实践

基于Canvas的经典打砖块游戏开发实践 这里写目录标题 基于Canvas的经典打砖块游戏开发实践项目介绍技术栈核心功能实现1. 游戏初始化2. 游戏对象设计3. 碰撞检测系统4. 动画系统5. 用户界面设计 性能优化1. 渲染优化2. 内存管理 项目亮点技术难点突破项目总结 项目介绍 在这个…

IDEA的常用设置与工具集成

简介 IDEA是捷克JetBrains公司推出的一款Java集成开发环境&#xff0c;在业内被公认为最好的Java开发工具之一&#xff0c;尤其在智能代码助手、代码自动提示、重构、J2EE支持、Ant、Junit、CVS整合、代码审查、创新的GUI设计等方面的功能可以说是超强的。 官网&#xff1a;ht…

Golang | 每日一练 (6)

&#x1f4a2;欢迎来到张胤尘的技术站 &#x1f4a5;技术如江河&#xff0c;汇聚众志成。代码似星辰&#xff0c;照亮行征程。开源精神长&#xff0c;传承永不忘。携手共前行&#xff0c;未来更辉煌&#x1f4a5; 文章目录 Golang | 每日一练 (6)题目参考答案什么是内存逃逸&am…

Qt窗口控件之颜色对话框QColorDialog

颜色对话框QColorDialog QColorDialog 是 Qt 内置的颜色对话框&#xff0c;它允许用户选择一个颜色&#xff0c;并通过接口获取颜色的值&#xff0c;进行进一步设置。 获取QColorDialog颜色 QColorDialog 可以使用堆创建&#xff0c;挂载对象树的方式。但它更适合使用它的静…

Windows Docker 报错: has no HTTPS proxy,换源

pull python 3.7报错&#xff1a; 尝试拉取Docker 测试库hello world也失败 尝试使用临时镜像源&#xff0c;可以成功拉取&#xff1a; sudo docker pull docker.m.daocloud.io/hello-world说明确实是网络问题&#xff0c;需要配置镜像源&#xff0c;为了方便&#xff0c;在d…

Unity Shader 学习16:全局光照 概念理解

- 全局光照 直接光 间接光&#xff0c;在没有开启GI的情况下是不计算间接光的&#xff08;如果放了光照探针 倒是可以模拟间接光 <光照探针只影响动态物体>&#xff09;&#xff1b; - 处理对象&#xff1a;静态物体(static) 、 非静态(动态)物体&#xff1b; - 计算方…

【蓝桥杯python研究生组备赛】005 数学与简单DP

题目1 01背包 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi&#xff0c;价值是 wi。 求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;且总价值最大。 输出最大价值。 输入格式 第一行两个整数&a…

吴恩达机器学习笔记复盘(六)梯度下降算法

简介 梯度下降&#xff08;Gradient Descent&#xff09;是一种常用的优化算法&#xff0c;广泛应用于机器学习、深度学习等领域&#xff0c;在这里是用于求J&#xff08;w,b&#xff09;局部最小值。 我自己觉得这样说有点过于抽象。换个直观点的说法就是&#xff0c;一个人…

【Golang那些事】go1.22和1.23 更新重点及测评

好久没有写文章了&#xff0c;攒了一年的Golang版本特性的技术点以及踩过的坑&#xff0c;那就在新年第一篇的文章中做一个总结吧&#xff1a; 一、关于迭代器 (一)迭代器去掉了共享共享内存 一个经典的面试题 说到Golang经典的面试题&#xff0c;大家可能都刷到过很多&…

【css酷炫效果】纯CSS实现照片堆叠效果

【css酷炫效果】纯CSS实现照片堆叠效果 缘创作背景html结构css样式完整代码基础版进阶版(增加鼠标悬停查看) 效果图 想直接拿走的老板&#xff0c;链接放在这里&#xff1a;https://download.csdn.net/download/u011561335/90492022 缘 创作随缘&#xff0c;不定时更新。 创…

labview与西门子1500plc进行S7通讯(仿真效果)

环境&#xff1a; 1.博图V16 2.S7-PLCSIM Advanced V3.0 3.labview2020 4.HslCommunication的dll文件 运行效果图 通过使用HslCommunication的库文件来对西门子plc进行通讯 labview代码 代码打包 通过网盘分享的文件&#xff1a;labview进行s7通讯测试.rar 链接: https:/…

[蓝桥杯 2023 省 B] 飞机降落(不会dfs的看过来)

[蓝桥杯 2023 省 B] 飞机降落 题目描述 N N N 架飞机准备降落到某个只有一条跑道的机场。其中第 i i i 架飞机在 T i T_{i} Ti​ 时刻到达机场上空&#xff0c;到达时它的剩余油料还可以继续盘旋 D i D_{i} Di​ 个单位时间&#xff0c;即它最早可以于 T i T_{i} Ti​ 时刻…

实验1:Vue基础实验

Web前端开发技术实验报告 实验1&#xff1a;Vue基础实验 一、实验目的&#xff1a; 掌握Vue实例的创建方法理解并初步掌握Vue实例的生命周期及钩子函数的使用掌握计算属性与侦听器使用方法 二、实验要求&#xff1a; 掌握Vue的基本语法及使用。编写程序并调试&#xff0c;完…