This is the fourth day of my participation in the August More text Challenge. For details, see:August is more challenging
Preface 👋
- The user is god, standing in god’s point of view is to stand in the user’s point of view to view components.
- Used a lot of good UI library, with the time of joy, it is their turn to build component library when often go to reference others source code.
- After reading the source code suddenly understand oh! Originally you can write like this, but the heart will inevitably have doubts how others come up with this solution? 🤳
- This series of articles is mainly for students who do not understand or have doubts, so the relatively basic, let us stand in the user’s point of view to think about the structure, see if there is a change in another way to write code?
About the Radio component 💿
Why do we use radio
As the user 👨💼
- When filling out forms, as users of the system, we are subconsciously used to selecting your answer with a simple mouse click or finger touch rather than typing on the keyboard.
- Why is that? For convenience, no one wants to spend ten minutes filling out a questionnaire full of input boxes, right? This is why almost all questionnaires are checkboxes and multiple checkboxes.
- To put it bluntly, it is portable and convenient.
As a component library consumer 👨💻
- What do we want to look like when we put the radio component of the component library on our page?
- No frills
- The basic selection requirements can be met
- Basic requirements can be customized to add functionality (e.g.
disable
The size of the
icon
)
- Basically, I can write as little code as possible to configure it.
Building components ⚒️
Next may use as little code as possible with element source code structure, with element Radio source food more delicious oh
Basic shelf 🔨
- If you want something nice
radio
Or customradio
Component that must not use nativeradio
Put it directly on the page, so you have to change the whole shelf. - A basic
radio
The shelf has two main points, one is nativeinput
The other is to create a circle and a text display for the user to see, which looks something like this.
<template>
<label class="zl-radio">
<span class="zl-radio__input">
<span class="zl-radio__inner"></span>
<input
ref="radio"
type="radio"
class="zl-radio__original"
>
</span>
<span>
<slot></slot>
</span>
</label>
</template>
Copy the code
- You can see it in the code above
label
Wrapping everything allows the user to select both the button and the text, whilelabel
Implicit associations are also cleverly used - The implicit way is to put the tag that you want to bind into
label
Inside,label
The element on the wrapper that needs to be bound is the equivalent of a clickradio
- The above that
span
Is for the previous circle style,inner
Class is the solid style in the middle,original
Class willinput
withopacity: 0;
Hidden processing - The following
span
You’re probably familiar with the idea of a slot to accept external text
Bidirectional binding 🧽
- For the component library consumer we want to pass in a
v-model
和label
To control the properties of our form
- In order to receive
label
The shelf is very simple. You just need to use itprops
Just to receive it. Sov-model
What about the values passed in? We all know thatv-model
This is also syntax sugar, and the above code is equivalent to
V-bind :value="radio" v-ON :input="radio=$event"></l-radio> <l-radio label=" second button" v-bind:value="radio" v-on:input="radio=$event"></l-radio>Copy the code
- So we need to be in a child component
props
Add avalue
To receive an incoming value that can be used in a child componentthis.$emit('input', val)
Trigger on the parentinput
Event to change the selection
<script> export default { props: { value: {}, label:{}, }, computed:{ model: { get() { return this.value; }, set(val) { this.$emit('input', val); }}}}; </script>Copy the code
- in
props
Receive incomingv-model
The numerical andlabel
Because we need to call the parent’s in the child componentinput
Event, so we can write a calculated property to use separatelyget
Receives from the parent component via bidirectional bindingvalue
Through theset
Set the new value, corresponding totemplate
The following
<template> <label class="zl-radio"> <span class="zl-radio__input" :class="{ 'is-checked': model === label }" > <span class="zl-radio__inner"></span> <input ref="radio" v-model="model" :value="label" type="radio" class="zl-radio__original" > </span> <span> <slot></slot> <template v-if="! $slots.default">{{ label }}</template> </span> </label> </template>Copy the code
- You can see the first one
span
Use dynamics in stylesclass
If the user has setlabel
With the incomingvalue
If it is the same (that is, selected), there will beis-checked
Selected style for - in
input
It’s also used in tagsv-model
Compute attributes for the abovemodel
To make a bidirectional binding so that our child component’sinput
The value of “is linked to the external form properties and bidirectional binding between parent and child components - Because sometimes the value of the radio button is the value of the text so I put one under the slot
template
It is used to determine whether there is text in the slotlabel
The show
Since this is just the analysis of the structure, you can check out the portal here for style related information
More attribute requirements 🏁
- So far this is the simplest one
Radio
The component is done, implementing bidirectional binding - But we often need some customization such as the implementation of the disable button, which we want to do by adding properties to the component
- The same is true for the child component
props
Receive the parameter and then iftrue
What to do iffalse
What should we do
. <span class="zl-radio__input" :class="{ 'is-checked': model === label, 'is-disabled': disabled }" > <span class="zl-radio__inner"></span> <input ref="radio" v-model="model" :value="label" type="radio" class="zl-radio__original" :disabled="disabled" > </span> ...Copy the code
- Let’s say we disable it and we get the property and we follow it
is-checked
Do the same with dynamic style binding to disable the style and then let the child componentinput
thedisabled
Synchronous processing - It’s true for one property and it’s true for the other property just like
Element
There are also many dynamic classes defined to do matching includingA border
,size
, etc.
Put it at the end 👋
- As for the building of the component library, I am also slowly exploring. What I talk about is all my own sharing, so it may be relatively basic for the big guy, but I believe that my continuous output can help some students who have doubts.
- If you think this article is helpful to your words might as well 🍉 attention + thumbs up + favorites + comments + forwarding 🍉 support yo ~~😛
Past highlights 🌅
How to write an elegant component example using Vuepress (above) 👈
How to write an elegant component example using Vuepress (2) 👈
How hard is style naming? Brief introduction to BEM naming specification ⚡
For convenience, I changed someone else’s wheel 😅