这两个组件还是很简单的
按钮组件, 主要是靠的 css 来改变不同的大小, 颜色
计数组件, 它和确认框组件的逻辑如出一辙; 都是使用 v-model 去驱动
先来看看效果

先完成, 按钮组件
思路分析:
1. 基本布局就是一个 button 按钮, 和一个默认插槽
2. 通过父组件传入的 type 和 size 属性去动态的给 button 标签添加 class 类
3. 准备好所有情况的样式
- <template>
- <button class="xtx-button ellipsis" :class="[size,type]">
- <slot />
- button>
- template>
-
- <script>
- export default {
- name: 'XtxButton',
- props: {
- size: {
- type: String,
- default: 'middle'
- },
- type: {
- type: String,
- default: 'default'
- }
- }
- }
- script>
-
- <style scoped lang="less">
- .xtx-button {
- appearance: none;
- border: none;
- outline: none;
- background: #fff;
- text-align: center;
- border: 1px solid transparent;
- border-radius: 4px;
- cursor: pointer;
- margin-top: 20px;
- }
- .large {
- width: 240px;
- height: 50px;
- font-size: 16px;
- }
- .middle {
- width: 180px;
- height: 50px;
- font-size: 16px;
- }
- .small {
- width: 100px;
- height: 32px;
- font-size: 14px;
- }
- .mini {
- width: 60px;
- height: 32px;
- font-size: 14px;
- }
- .default {
- border-color: #e4e4e4;
- color: #666;
- }
- .primary {
- border-color: @xtxColor;
- background: @xtxColor;
- color: #fff;
- }
- .plain {
- border-color: @xtxColor;
- color: @xtxColor;
- background: lighten(@xtxColor,50%);
- }
- .gray {
- border-color: #ccc;
- background: #ccc;;
- color: #fff;
- }
- style>
计数组件
思路分析:
1. 父组件定义 v-model 所依赖的数据
2. 技术组件使用 props 接收 modelValue 数据
3. 使用 @vue/usecore 中的 useVmodel 方法去接收 modelValue 的数据
4. 用户点击计数时, 将修改的数据传给父组件
5. emit 一个 change 事件, 方便父组件可以拿到修改的值
- <template>
- <div class="xtx-numbox">
- <div class="label">{{ label }}div>
- <div class="numbox">
- <a href="javascript:;" @click="changeNumber(-1)">-a>
- <input type="text" readonly :value=" num">
- <a href="javascript:;" @click="changeNumber(1)">+a>
- div>
- div>
- template>
-
- <script>
- import { useVModel } from '@vueuse/core'
- export default {
- name: 'XtxNumbox',
- props: {
- modelValue: {
- type: Number,
- default: 1
- },
- label: {
- type: String,
- default: '数量'
- },
- max: {
- type: Number,
- default: 100
- },
- min: {
- type: Number,
- default: 1
- }
- },
- setup (props, { emit }) {
- const num = useVModel(props, 'modelValue', emit)
- const changeNumber = (step) => {
- const newNum = num.value + step
- if (newNum > props.max || newNum < props.min) return
- num.value = newNum
-
- emit('change', newNum)
- }
-
- return { changeNumber, num }
- }
- }
- script>
-
- <style scoped lang="less">
- .xtx-numbox {
- display: flex;
- align-items: center;
- .label {
- width: 60px;
- color: #999;
- padding-left: 10px;
- }
- .numbox {
- width: 120px;
- height: 30px;
- border: 1px solid #e4e4e4;
- display: flex;
- > a {
- width: 29px;
- line-height: 28px;
- text-align: center;
- background: #f8f8f8;
- font-size: 16px;
- color: #666;
- &:first-of-type {
- border-right:1px solid #e4e4e4;
- }
- &:last-of-type {
- border-left:1px solid #e4e4e4;
- }
- }
- > input {
- width: 60px;
- padding: 0 5px;
- text-align: center;
- color: #666;
- }
- }
- }
- style>