Vue实现自定义多选与单选的答题功能(2)
接,上文……
本篇改用v-model
的方式来实现自定义样式の多选与单选。
这两天在玩mpvue
,但是下午如果对着文档大眼瞪小眼的话,肯定会睡着的。
想起昨晚的flag,我就想直接用demo上手吧,一举两得。
谁想到我好不容易快做完了,v-model
在小程序中不起作用!
来不及研究为什么,我先直接在原来项目上赶紧建了一个test页面,先赶紧实现我的这种设想:
使用v-model和原生表单也可以实现这么好看且达到需求的效果。
重要的是不用自己跟在用户屁股后面屁颠屁颠的监听人家到底何时用了点击事件,又把点击事件用在何处了!效果图如下,和之前的没什么两样呢!
关于具体实现上
我想,vue官网有关于表单输入绑定的讲解和demo,事实上,我只要做到利用他的demo把我的数据和样式调整一下就万事大吉了!
没有什么比简单解决一个功能更让人开心的了!
说干就干,我直接在原来项目代码的基础上动手:
之前的选项处理就一个li孤军奋战,数据渲染、样式切换、包括点击事件都绑定在上边
ul.qus-list
li(v-for="(item,index) in state.ExamInfo.QuestionAnswerCode" :key="item.Code + index" @click="choosed(index)" :class="{'li-focus' : chooseNum==index}" ref="liId") {{item.Code}}、{{item.Description}}
简直忙到没朋友啊有没有!光他和ul的长度差距就说明了一切!
现在我们把他要做的事分解一下:
现在他只负责v-for循环数据渲染
ul.qus-list
li(v-for="(item,index) in state.ExamInfo.QuestionAnswerCode" :key="item.Code + index" :class="{'li-focus' : chooseNum==index}")
内部分配给他两个小弟:input:radio/checkbox
和label
,这俩人一个负责点击后与数据的绑定,一个负责样式。
这么一说大神就明了了,好你可以走了,把沙发腾出来。
“圆规正转“。
这俩人中,Input
负责数据绑定,其实也就是利用v-model
。具体原理直接看https://cn.vuejs.org/v2/guide/forms.html
input(type="radio" :value="item.Code" :id="'choice1'+index" v-model="picked")
然后是label负责样式。样式也包括用户看到的选项文本的展示:
label(:for="'choice1'+index" class="choice-item") {{item.Code}}、{{item.Description}}
至于他具体怎么负责样式?这个也利用了css的选择器::checked
选择器和+相邻兄弟选择器
/*普通样式*/
.choice-item{
display: block;
margin: .2rem auto 0;
padding: .3rem .3rem .34rem;
color: $qusTxt;
font-size: .34rem;
text-align: center;
@include boxStyle(1rem,.12rem,rgba(49,32,114,0.16));
}
/*input被选中时,label的样式*/
input:checked + .choice-item{
background: $purpleClr;
color: #FFF;
}
于是就有了这样的样式:这里可以看出,二者是相互成就的关系:
首先通过html那里,label的for
属性和input的id
属性关联,使得点击label的时候,input也就被选择上了。
然后是css样式这里,label除了自己正常的样式,还受input被选中状态的影响:当input被选中后(input:checked),作为input在li爸爸内部的唯一兄弟元素(+选择符),label的样式就被重新更新了选中态。
因为选中展示的效果被label做了,那么input也就可以“归隐山林”、悠享田园生活了。
所以直接设置样式不可见即可。
好了
完事儿了……
事实证明很简单的事儿,让我给搞复杂额。也就是我上一篇说的,不会巧妙的利用每一个代码的特性。
这一篇的实现方式正是还算巧妙的利用了该利用的知识点。
也就不再需要li身上绑定的哪个choose事件来监听用户点击了,vue自己给我们做了!
甚至最后连用户选了什么都不用管,直接将v-model绑定的变量传给后端即可。
好用的v-model
!强大的v-model
!
最后因为本需求有多选和单选,作为单页应用,又因不需要渲染很多道题目,每次只渲染一道。
所以我们可以最后根据选项判断是需要多选还是单选,动态的切换这两套就行了。
这么一看是不是特别简单明了!却被我之前实现的那么麻烦。。。。。我也是佩服自己光脚登山的傻劲。
本篇是早期接触vue后,第一个答题项目。
代码稍显稚嫩,但是思考问题的角度和思路值得纪念。
尤其当初自己善于总结、喜欢前端的精神,还是值得现在的自己去学习的。
来让我们一起携手同走前端路! 关注公众号回复【加群】