IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 【Vue3.0实战逐步深入系列】vue3.0获取问卷调查结果并输出到控制台 -> 正文阅读

[JavaScript知识库]【Vue3.0实战逐步深入系列】vue3.0获取问卷调查结果并输出到控制台

【千字长文,熬夜更新,原创不易,多多支持,感谢大家】

前言

hello,小伙伴们大家好。昨天我们对最初的投票功能做了一个简单的扩展:实现了一个简单的问卷调查功能。在实现该问卷功能时,我们分别封装了几个不同类型的组件:投票组件,单选组件,多选组件,输入组件和评分组件。不知有没有小伙伴发现,虽然问卷的大部分功能都实现了,问卷主题可自由配置,用户也可以进行点选输入填写问卷,但最后问卷填写完成后发现点击提交按钮并没有反应,那岂不是白操作了一顿?没错该问卷还少了个提交功能,接下来我们就把问卷的提交功能补齐,同时对App.vue组件进行一个简单的优化。

给自定义问卷组件添加change事件

在我们封装的问卷组件中不管是投票组件,多选组件,单选组件还是输入组件,最终选择的结果都是保存在一个响应式属性selectValue上,这个属性只能在组件内部使用,外部是无法访问到的,而我们的问卷最终是在父组件中通过提交按钮来提交问卷结果的,也就是说我们需要在父组件中来获取各个子组件已选择的结果,那么就需要用到子组件向父组件传值了,在本次分享中我们选择通过自定义事件的形式向父组件传值。除了投票组件,其它几个组件的代码基本上都是一样的,所以就在这里进行统一说明了,具体实现步骤如下:

  • 在setup函数的第二个参数context中解构出emit方法
  • 定义一个方法valChange,接收一个参数val,并在这个方法中调用emit方法,同时传递两个参数:【自定义事件“select”】和【已选结果值“val”】。注意这里我们给所有的自定义组件(包括投票组件)统一指定自定义事件select
  • 通过return暴露valChange方法给模板
  • 最后修改模板给组件添加change事件

下面以单选组件myradio为例,展示一下修改后的代码,其它几个组件(投票组件除外)与之相同,不再赘述

<!--...适用于myradio.vue, mycheck.vue, myinput.vue, mystar.vue-->
<template>
<!--...省略-->
	<el-radio-group v-model="selectedValue" @change="valChange">
	<!--...省略-->		
	</el-radio-group>
<!--...省略-->
</template>
//适用于myradio.vue, mycheck.vue, myinput.vue, mystar.vue
//...省略
setup(props, context){
	//...省略
	const {emit} = context;
	const valChange = () => {
		emit('select', val);//通过emit方法自定义select事件并将选择结果传递给父组件
	}
}
//...省略

投票组件vote.vue改造

之所以把投票组件单独改造是因为在投票组件相对来说有点复杂,并且投票组件中的的元素除了按钮el-button和卡片el-card都是原生的html元素,这些元素都没有change事件,所以我们应该在按钮的点击事件中调用emit来自定义事件select,同时将投票结果(支持人数,反对人数和支持率)返回给主问卷页面

  • 在setup方法的第二个参数context中解构出emit方法
  • 定义一个result变量用于接收投票结果
  • 定义一个方法calcResult,在该方法中以固定字符串模板将支持人数,反对人数和支持率拼接成字符串并赋值给变量result
  • 在calcResult 中调用emit方法并传递“select”和result作为参数
  • 最后在原有的support和oppose中调用calcResult方法
//...省略
setup(props, context){
	//...省略
	const { emit } = context;
	let result = "";
	const calcResult = () => {
		result = `支持人数:${supCount.value}/${supCount.value+oppCount.value};反对人数:${oppCount.value}/${supCount.value + oppCount.value};支持率:${supRate.value}%`
		emit('select', result);
	}
	// 支持方法
    const support = () => {
      supCount.value++; 
      calcResult();
    };
    //反对方法
    const oppose = () => {
      oppCount.value++; 
      calcResult();
    };
}

封装Home组件

在前面的案例中,我们把所有的业务逻辑都写在了App.vue里,但是作为入口组件我们应该尽可能少的把业务逻辑都写在App.vue中,因此从这次的分享开始,我们就把业务逻辑相关的代码从App.vue中提取出来单独放在Home.vue的组件中。同时由于这个组件中的响应式变量越来越多,因此我们也把ref换成reactive进行响应式变量的定义。

  • 新增一个Home.vue的组件
  • 将原来App.vue中的代码剪切到Home.vue中(注意代码切换后,导入自定义组件路径的变化)
  • 将原来用ref声明的响应式变量统一改成用reactive来声明(注意在return的时候需要先调用toRefs方法然后再进行结构,以免破坏响应式)
  • 声明一个普通变量result默认值为空对象,用于保存已选中的问卷结果
  • 定义一个submit方法,用于点击提交按钮时调用,在该方法中遍历result对象循环输出问卷主题及结果
  • 定义一个getValue方法,接收3个参数,并将问卷主题和结果以字符串的形式添加到对象result中,3个参数:
    • val:已选结果,用于接收子组件传回来的已选结果值
    • title:问卷主题,用于展示当前所选结果是属于哪个问卷主题的
    • flag:问卷标识,由于每类问卷主题的个数都是不固定的,我们自定义的组件又都是通过v-for指令循环生成的,并且每个组件都会调用该方法,因此我们需要方法被调用时对每个问卷主题做一个唯一标识便于区分
  • 将上面的响应式变量及两个方法通过return暴露出去
  • 最后在为模板中的每个自定义组件添加一个select事件(注:该事件由子组件定义返回),在该事件中调用上面的getValue方法并传递3个实参

改造后的代码如下:

<template>
	<div class="main">
		<!--$event为子组件传回来的已选择的结果,item.title为问卷主题,vote${item.id}则为字符串vote加问卷主题id拼接成的唯一标识-->
		<!--这里只展示了新增代码部分,原有代码省略-->
		<vote  @select="getValue($event, item.title, `vote${item.id}`)"></vote>
		<myradio @select="getValue($event, radio.title, `radio${radio.id}`)"></myradio >
		<mycheck @select="getValue($event, check.title, `check${check.id}`)"></mycheck>
		<myinput  @select="getValue($event, inp.title, `input${inp.id}`)"></myinput>
		<mystar @select="getValue($event, star.title, `star${star.id}`)"></mystar>
	</div>
</template>
// ... 省略
import { reactive, toRefs } from 'vue'

export default {
	//...省略
	setup(){
		const state = reactive({
			data:[],
			radios:[],
			checks:[],
			inputs:[],
			stars:[]
		})
		
		http.get('/data.json').then(res=>{
			state.data = res.data;
			state.radios = res.radios;
			state.checks = res.checks;
			state.inputs = res.inputs;
			state.stars = res.stars;
		});
		
		const result = {}
		const submit = () => {
			for(const key in result){
				console.log(result[key])
			}
		}
		const getValue = (val, title, flag) => {
			result[flag] = `${title} >>> ${val}`
		}
	
		return {	
			...toRefs(state),
			submit,
			getValue
		}
	}
}

效果展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

本次分享我们基于前面的案例继续扩展,实现了问卷的提交功能,其中涉及到了子组件向父组件传值,子组件中自定义事件以及基于reactive去定义响应式属性等,最终实现点击提交按钮后将问卷结果输出到控制台中。
本次分享就到这里了,喜欢的小伙伴欢迎点赞评论加关注哦!

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-27 09:48:55  更:2021-11-27 09:49:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:04:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码