从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十三║Vue实战:Vuex 其实很简单

系列教程一目录:.netcore+vue 前后端分离

系列教程二目录:DDD领域驱动设计

系列教程三目录:Nuxt.js TiBug系统

系列教程四目录:VueAdmin 后台管理系统

系列教程五目录:IdentityServer4 授权服务器

本文梯子

正文

前言

哈喽大家周五好,马上又是一个周末了,下周就是中秋了,下下周就是国庆啦,这里先祝福大家一个比一个假日嗨皮啦~~转眼我们的专题已经写了第 23 篇了,好几次都坚持不下去想要中断,不过每当看到群里的交流,看到博客下边好多小伙伴提出问题,我又燃起了斗志,不过这两天感冒了,所以更新的比较晚,这里也提醒大家,节日要照顾好自己哟~~~,好多人说我写的上不了台面,哈哈这里表示赞同,本系列的宗旨就是,给大家一个学习的点,让大家去自学一个面,然后大家一起学,把面交流成一个立体,就达到一个体系了。好啦,言归正传(一直告诫自己,不能写心情贴,哈哈要写技术文章),昨天呢,不知道有几个小伙伴按照教程把自己的之前的 .net core api 教程里的项目给展示出来了呢,一定要自己动手试试哟,只要成功了,就是棒棒哒,今天咱们继续往下走,来说说一个一直让人头大的东西,就是表单以及 Vuex的使用,好啦,开始今天的讲解!

零、今天要完成实战1中的红色部分

一、常见的 Vue 表单提交是如何设计的?

说到了 Web开发,一定几乎所有人都能说到表单提交,这个是真的少不了,而且也让人写的头晕眼花,心身疲惫,自然在 Vue 开发中,也是少不了的一部分工作,常见的表单是什么样子的呢?

1、表单、按钮等在一个组件内

这个时候机智如你一定会说:这有什么难的是吧,Vue 提供了完美的 双向数据绑定,可以很好的实现数据的更新、获取和提交,嗯~没错,你说的很对,我们再也不用费心的操作 DOM 了,用户填好数据就可以直接 axios 到 后端api接口了,多好,当然,这也是一个处理方式。

这里的代码就不写了,很简单,把所有的写到一个页面内就行,大家可以自己试一试。

可是想一想,如果页面内有很多组件,有很多的表单,或者更直接点儿,想要表单单独是一个组件用作弹窗,你会怎么办呢~为什么呢?

2、按钮在父组件、表单在单独的子组件内

这种开发利于开发,易于维护,可是就是不适合数据传输,因为父子组件内的数据通讯是很麻烦的,虽然 Vue 支持双向数据绑定,但是父子通讯是:组件之间的数据只能是单项流通的,而且由父组件传递给子组件,如果你看过我之前写的文章,有关组件的《从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十║Vue基础终篇:组件详解+项目说明》,你应该知道,之所以这么麻烦 , 是因为父组件可以通过 props 给子组件传递参数 , 但子组件内却不能直接修改父组件传过来的参数。只能通过自定义方法,向上提交时数据,今天,咱们说下第二种方法,子组件可以使用 $emit 触发父组件的自定义事件。

二、通过 $emit 修改父组件数据

还个方法的本质的通过自定义事件的方式,把子组件的值,通过参数的形式广播到父组件去,然后父组件接收,我在之前的文章中有详细的讲解,请看《从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十║Vue基础终篇:组件详解+项目说明》章节——组件传值 子传父。

这里说说说说这两种方式

1、在原来代码里 About.vue 修改成 Form.vue

注意,如果你是使用 Webstorm 的话,重命名的时候,会自动的把当然文件的全部应用的地方都会修改(举栗子:router 中的名字),如果是手动修改的文件夹中的,请确保其他地方都被修改了。

在 Form.vue 组件内,添加以下代码

<!-- 父组件 Form.vue -->

<template>
    <div class="parent">
        <h3>问卷调查</h3>
       <!-- 注意这里,formData是自定义属性,用来向子组件传递数据,如果要想被子组件控制,必须加上 .sync-->
        <child :formData.sync="form"></child>
        <div class="">
            <p>姓名:{{form.name}}</p>
            <p>年龄:{{form.age}}</p>
            <p>地址:{{form.address}}</p>
        </div>
    </div>
</template>

<script>
import child from "../components/dialog.vue";//导入子组件

export default {
  components: {
    child
  },
  data: function() {//定义返回data
    return {
      form: {
        name: "",
        namePla: "姓名不能为空",
        address: "",
        age: ""
      }
    };
  }
};
</script>

2、在 components 文件夹内,添加窗口子组件 dialog.vue(之所以叫窗口,就是你可以把它设计成弹窗)

<!-- 子组件 dialog.vue -->

<template>
    <div class="child">
        <label>
            姓名:<input :placeholder="form.namePla" type="text" v-model="form.name">
        </label>
        <label>
            年龄:<input type="text" v-model="form.age">
        </label>
        <label>
            地址:<input type="text" v-model="form.address">
        </label>
    </div>
</template>

<script>
export default {
  data: function() {//子组件返回data
    return {
      form: {
        name: "",
        namePla: "",
        age: "",
        address: ""
      }
    };
  },
  props: {
    // 这个 prop 属性用来接收父组件传递进来的值
    formData: Object//对象的形式
  },
  watch: {
    // 因为不能直接修改 props 里的属性,所以不能直接把 formData 通过v-model进行双向绑定到 input 上
    // 在这里我们需要监听 formData,当它发生变化时,立即将值赋给 data 里的 form,因为 from 可以用来 绑定 input,就好像增加了一个跳板
    formData: {
      immediate: true,
      handler(val) {
        this.form = val;
      }
    }
  },

};
</script>

这里要说下 几个概念:
1、watch : 用来监听 父组件传递过来的值,当传递过来的时候,赋给 form,只有子组件的 from 才可以双向绑定 DOM

2、mounted : 挂载完成后执行,如果有不明白的小伙伴,可以看看我之前的有关生命周期的文章 —— 《从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十九║Vue基础: 样式动态绑定+生命周期》。

3、$emit : this.$emit("自定义事件名",要传送的数据),用来触发父组件的自定义事件,这里不是很明白没关系,因为它要配合 .sync 来使用。(注意:如果你在父组件里写了一个事件,这里就是那个事件的名字)

4、.sync : .sync 修饰符所提供的功能。当一个子组件改变了一个 prop 的值时,这个变化也会同步到父组件中所绑定,就是说我们可以直接在我们需要传的 prop 后面加上 .sync。也就是说我们在子组件内,用过 update:formData 来改变了父组件的 属性 prop 的值,通过 .sync 来同步到了父组件的 form 对象里。嗯~大概就是这个意思。官网 :地址

5、 update:my-prop-name 的模式触发事件。举个栗子,在一个包含 title prop 的假设的组件中,我们可以用以下方法表达对其赋新值:

this.$emit(‘update:formData‘, newData)

然后父组件可以监听那个事件并根据需要更新一个本地的数据属性。例如:

<text-document
  v-bind:formData="form"
  v-on:update:formData="form = $event"
></text-document>

为了方便起见,我们为这种模式提供一个缩写,即 .sync 修饰符:是不是和上边的是一样的

<text-document  v-bind:formData.sync="form"></text-document>

详细的过程:

3、这个时候,看我们的项目,结果就出来了

不仅可以把父组件的 ”姓名不能为空“传递到子组件,还可以,把子组件内的数据发送到父组件,是不是感觉很神奇?!而且也可以做成一个弹窗的,大家可以自己试试。

但是呢,这里是一个小 DEMO 还好,要是多的话,要设置总感觉不是很舒服,还需要 用到那么多的新的东西,欸!机智如你, Vuex 就这么登台了。

三、使用 Vuex 来实现父子通讯

1、老规矩,什么是 Vuex?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。说人话就是,它就像是一个容器,一个第三方,我们可以把内容存进去,然后在别的任何地方去取出来,这个是不是正好就是我们的父子组件通讯?!大家再看看上面,父子组件之间的通信是不是比较麻烦,改变数据还要用$emit。如果有一个地方跟仓库一样就存放着form的值,谁要用谁去请求form的值,谁想改就改该多好是吧,vuex就是一个管理仓库,有点全局变量的意思。任何组件需要拿,改东西,都可以找他。

2、首先我们需要安装 Vuex

利用npm下载vuex包,在命令行工具中输入以下命令,cd到你的项目目录

npm install vuex --save

3、还记得那个 store.js 么,终于用到了,修改内容

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

const store = new Vuex.Store({
  // 初始化的数据
  state: {
    formDatas: null//定义一个变量 formDatas
  },
  // 改变state里面的值得方法
  mutations: {
    getFormData(state, data) {
      state.formDatas = data;
    }
  }
});
// 输出模块
export default store;

4、在 views 文件夹下,新建 FormVuex.vue 页面

内容和 Form.vue 主要内容差不多

<!-- 父组件 parent.vue -->

<template>
    <div class="parent">
        <h3>问卷调查</h3>
        <child ></child><!-- 注意: 这里已经没有 .sync 了 -->
        <div class="">
            <br>
            <br>
            <p>数据:{{_fatherData}}</p>//感谢网友 @Mr.TangHao 的纠错
        </div>
    </div>
</template>

<script>
import child from "../components/dialogVuex.vue";

export default {
  components: {
    child
  },
  data: function() {
    return {
      form: {
        name: "",
        namePla: "姓名不能为空",
        address: "",
        age: ""
      }
    };
  },
  computed: {//挂载完成后
    _fatherData() {//获取全局 store 仓库中的 formDatas 值
      // 读取store里面的值,这里是重点
      return this.$store.state.formDatas;
    }
  }
};
</script>

5、在 components 文件夹下,新增 dialogVuex.vue 页面

<!-- 子组件 child.vue -->

<template>
    <div class="child">
        <label>
            姓名:<input  type="text" v-model="form.name">
        </label>
        <label>
            年龄:<input type="text" v-model="form.age">
        </label>
        <label>
            地址:<input type="text" v-model="form.address">
        </label>
    </div>
</template>

<script>
export default {
  data: function() {
    return {
      form: {
        name: "",
        namePla: "",
        age: "",
        address: ""
      }
    };
  },
  mounted() {
    // 将数据提交到 store
    this.$store.commit(‘getFormData‘, this.form)//感谢网友 @Mr.TangHao 的纠错
  }
};
</script>

6、修改 App.vue 和 路由 router.js,提供 Vuex 页面入口

import Vue from "vue";
import Router from "vue-router";
import Home from "./views/Home.vue";
import FormVuex from "./views/FormVuex.vue";

Vue.use(Router);

export default new Router({
  mode: "history",
  base: process.env.BASE_URL,
  routes: [
    {
      path: "/",
      name: "home",
      component: Home
    },
    {
      path: "/Vuex",
      name: "Vuex",
      component: FormVuex
    },
    {
      path: "/about",
      name: "about",
      // route level code-splitting
      // this generates a separate chunk (about.[hash].js) for this route
      // which is lazy-loaded when the route is visited.
      component: () =>
        import(/* webpackChunkName: "about" */ "./views/Form.vue")
    }
  ]
});

7、浏览页面,搞定!

就这样就完成啦!是不是很简单,原理就是:在子组件内,把双向数据绑定的数据,提交到 store 里,然后再在父组件里获取,剩下的大家可以在处理

四、其他扩展

1、store.js 各部分单独管理

从上边可以看出,虽然我们的 store 单独在一个文件里,那组件多了之后 , 状态也多了 , 这么多状态都堆在 store.js 不好维护怎么办 ?

我们可以使用 vuex 的 modules , 把   store.js 改成 :(感谢群小伙伴@宝 的纠错)

import Vue from ‘vue‘
import vuex from ‘vuex‘
Vue.use(vuex);

import dialog_store from ‘./components/dialog_store.js‘;//引入某个store对象

export default new Vuex.Store({
    modules: {
        dialog: dialog_store
    }
})

这里我们引用了一个 dialog_store.js , 在这个 js 文件里我们就可以单独写 dialog 组件的状态了 :

export default {
   state: {
    formDatas: null
  },
  // 改变state里面的值得方法
  mutations: {
    getFormData(state, data) {
      state.formDatas = data;
    }
  }
}

做出这样的修改之后 , 我们将之前我们使用的 $store.state.formDatas 统统改为 $store.state.dialog.formDatas 即可。这个大家可以自由的尝试,这里就不一一说明了。

2、什么情况下我应该使用 Vuex?

虽然 Vuex 可以帮助我们管理共享状态,但也附带了更多的概念和框架。这需要对短期和长期效益进行权衡。

如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

3、其他扩展问题补充中

五、结语

今天因为时间的问题,就暂时说到了这里,是不是感觉很简单,这个就是 vuex 的使用,当然,还有其他的一些扩展使用,我还没有来得及准备,明天就是周末了,我再整理后,再修改下吧,如果你以上的都看懂了,那父子组件通讯,各种表单提交,你已经没有问题啦~好啦下次再见咯。

六、CODE

https://github.com/anjoy8/Blog.Vue

意:如果下载好了,首先需要 执行 npm install 安装依赖

请确保已经把 webpack 和 vue-cli 都安装了。

原文地址:https://www.cnblogs.com/Alex80/p/10545045.html

时间: 2024-12-14 09:25:22

从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十三║Vue实战:Vuex 其实很简单的相关文章

从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十一║Vue实战:开发环境搭建【详细版】

系列教程一目录:.netcore+vue 前后端分离 系列教程二目录:DDD领域驱动设计 系列教程三目录:Nuxt.js TiBug系统 系列教程四目录:VueAdmin 后台管理系统 系列教程五目录:IdentityServer4 授权服务器 本文梯子 缘起 零.今天要完成左下角红色的部分 A.Vue 常见的IDE —— 我是开发工具,干活的都是我 1.VsCode 2.Webstorm 3.Atom B.安装Nodejs环境 —— 我是运行环境,没我不行 C.安装 npm / cnpm ——

从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十五║实战二:初探SSR服务端渲染(个人博客二)

缘起 时间真快,现在已经是这个系列教程的下半部 Vue 第 12 篇了,昨天我也简单思考了下,可能明天再来一篇,Vue 就基本告一段落了,因为什么呢,这里给大家说个题外话,当时写博文的时候,只是想给大家增加点儿学习的动力,每天提醒下,完全没有提纲或者安排说明什么的,就是按照我自己学的方向走,正好发现了一个规律就是:每一个系列正好是 1 个引子 + 12 篇正文,不知道大家对这个有没有感觉,大家可能看到我的头像就知道了,哈哈,其实我是一个红迷,正好这里机缘巧合,两个系列都形成了这样的,我自私的给自

从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十六 ║ Vue前篇:ES6初体验 &amp; 模块化

缘起 昨天说到了<从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十五 ║ Vue前篇:JS对象&字面量&this>,通过总体来看,好像大家对这一块不是很感兴趣,嗯~~这一块确实挺枯燥的,不能直接拿来代码跑一下那种,不过还是得说下去,继续加油吧!如果大家对昨天的小demo练习的话,相信现在已经对JS的面向对象写法很熟悉了,如果嵌套字面量定义函数,如何使用this关键字指向.今天呢,主要说一下ES6中的一些特性技巧,然后简单说一下模块化的问题,好啦,开始今天的讲

从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十七 ║Vue基础:给博客首页加花样(二)

回顾 今天来晚辣,给公司做了一个小项目,一个瀑布流+动态视频控制的DEMO,有需要的可以联系我,公司的项目就不对外展示了(一个后端程序员真的要干前端了哈哈哈). 书接上文,昨天正式的开始了Vue的代码的学习,简单的通过一些假的数据来展示了下个人博客的首页列表,不知道大家是否还记得昨天讲的什么,如果不太清楚呢,可以再回顾下<从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十七 ║Vue基础:使用Vue.js 来画博客首页(一)>,我们主要说到了,Vue的核心语法是什么,MVVM

从壹开始前后端分离【 .NET Core2.0 Api + Vue 2.0 + AOP + 分布式】框架之七 || API项目整体搭建 6.2 轻量级ORM

代码已上传Github,文末有地址 书接上文:<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之六 || API项目整体搭建 6.1 仓储>,我们简单的对整体项目进行搭建,用到了项目中常见的仓储模式+面向接口编程,核心的一共是六层,当然你也可以根据自己的需求进行扩展,比如我在其他的项目中会用到Common层,当然我们这个项目接下来也会有,或者我还会添加Task层,主要是作为定时项目使用,我之前用的是Task Schedule,基本能满足

从壹开始前后端分离【 .NET Core2.0 Api + Vue 3.0 + AOP + 分布式】框架之九 || 依赖注入IoC学习 + AOP界面编程初探

代码已上传Github,文末有地址 说接上文,上回说到了<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之八 || API项目整体搭建 6.3 异步泛型+依赖注入初探>,后来的标题中,我把仓储两个字给去掉了,因为好像大家对这个模式很有不同的看法,嗯~可能还是我学艺不精,没有说到其中的好处,现在在学DDD领域驱动设计相关资料,有了好的灵感再给大家分享吧. 到目前为止我们的项目已经有了基本的雏形,后端其实已经可以搭建自己的接口列表了,框架已

从壹开始前后端分离【 .NET Core2.0 Api + Vue 2.0 + AOP + 分布式】框架之六 || API项目整体搭建 6.1

书接上文:前几回文章中,我们花了三天的时间简单了解了下接口文档Swagger框架,已经完全解放了我们的以前的Word说明文档,并且可以在线进行调试,而且当项目开始之中,我们可以定义一些空的接口,或者可以返回假数据,这样真正达到了前后端不等待的缺陷,还是很不错的,当然,这离我说的前后端分离还是相差甚远,今天呢,我们就简单搭建下我们的项目架构. 本项目是我自己的一个真实项目,数据都是真实的,之前搭建过一个MVC + EF Code First的项目,本项目就是基于这个了,前一段时间我已经搭建起来了,

从壹开始前后端分离[.netCore 不定期 ] 36 ║解决JWT权限验证过期问题

缘起 哈喽,老张的不定期更新的日常又开始了,在咱们的前后端分离的.net core 框架中,虽然已经实现了权限验证<框架之五 || Swagger的使用 3.3 JWT权限验证[修改]>,只不过还是有一些遗留问题,最近有不少的小伙伴发现了这样的一些问题,本来想着直接就在原文修改,但是发现可能怕有的小伙伴看不到,就单发一条推送吧,所以我还是单写出一篇文章来说明解决这些问题,希望对无论是正在开发权限管理系统,还是平时需要数据库动态绑定权限分配的你有一些启发和思考.今天咱们注意解决这三个问题: 1.

从壹开始前后端分离 40 || 完美基于AOP的接口性能分析

旁白音:本文是不定时更新的.net core,当前主线任务的Nuxt+VueAdmin教程的 nuxt.js 之 tibug项目已上线,大家可以玩一玩:http://123.206.33.109:7090,具体的部署教程会在下周发表. 缘起 哈喽大家周五好呀,今天是一个不定时更新的文章,是很简单的一篇文章,大家应该都能看懂,主要包含了两个内容,一个是对AOP编程的进一步的理解(其中还有和过滤器比较),第二个就是一个简单的小插件——记录接口的调用时间调用情况,也就是很简单的性能记录,这个时候你肯定