Skip to content

Commit

Permalink
Merge pull request #115 from Tencent/feat/slider
Browse files Browse the repository at this point in the history
Refactor: 重构 Slider 组件
  • Loading branch information
LeeJim authored May 26, 2022
2 parents b6d4384 + e42fd35 commit af205a8
Show file tree
Hide file tree
Showing 18 changed files with 536 additions and 545 deletions.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"url": "/tdesign-mobile-vue.git"
},
"scripts": {
"start": "npm run dev",
"prepare": "husky install .husky",
"dev": "cd site && cross-env NODE_ENV=development vite",
"dev:debug": "cd site && cross-env NODE_ENV=development vite --debug",
Expand Down Expand Up @@ -167,10 +168,10 @@
"typescript": "^4.5.2",
"vite": "^2.7.2",
"vite-plugin-tdoc": "^2.0.1",
"vue": "^3.2.4",
"vue": "^3.2.33",
"vue-eslint-parser": "^8.0.1",
"vue-router": "4.0.11",
"vue-tsc": "^0.29.8",
"vue-tsc": "^0.34.16",
"vue3-jest": "^27.0.0-alpha.2"
},
"config": {
Expand Down
4 changes: 2 additions & 2 deletions scripts/test/jest.base.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ module.exports = {
modulePathIgnorePatterns: ['<rootDir>/test/unit/coverage/'],
transform: {
'.*\\.(vue)$': 'vue3-jest',
'^.+\\.(ts|tsx)?$': 'ts-jest',
"^.+\\.(js|jsx)$": "babel-jest",
'^.+\\.tsx?$': 'ts-jest',
"^.+\\.jsx?$": "babel-jest",
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
},
testRegex: '.*\\.test\\.js$',
Expand Down
6 changes: 6 additions & 0 deletions site/docs.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,12 @@ export default {
path: '/mobile-vue/components/search',
component: () => import('@/search/search.md'),
},
{
title: 'Slider 滑动选择器',
name: 'slider',
path: '/mobile-vue/components/slider',
component: () => import('@/slider/slider.md'),
},
{
title: 'Fab 悬浮按钮',
name: 'fab',
Expand Down
1 change: 0 additions & 1 deletion site/styles/mobile/components.less
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@
.slider-demo {
background-color: #fff;
padding: 12px 16px;
max-height: 69px;
}

.stepper-demo {
Expand Down
2 changes: 1 addition & 1 deletion src/shared/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default withInstall;

export function extendAPI<T = Record<string, any>>(apis: T) {
const instance = getCurrentInstance();
if (instance) {
if (instance && instance.proxy) {
Object.assign(instance.proxy, apis);
}
}
32 changes: 21 additions & 11 deletions src/shared/useVModel/index.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
import { ref, Ref, getCurrentInstance, ComponentInternalInstance } from 'vue';

export type ChangeHandler<T, P extends any[]> = (value: T, ...args: P) => void;
export type ChangeHandler<T> = (value: T, ...args: any[]) => void;

// 用于实现 v-model
export function useVModel<T, P extends any[]>(
export function useVModel<T>(
value: Ref<T>,
modelValue: Ref<T>,
defaultValue: T,
onChange: ChangeHandler<T, P>,
// emit 和 eventName 用于支持 v-model
): [Ref<T>, ChangeHandler<T, P>] {
onChange?: (...args: any) => any,
propName = 'value',
// emit 和 eventName 用于支持 v-model 和 xxx.sync 语法糖
): [Ref<T>, ChangeHandler<T>] {
const { emit } = getCurrentInstance() as ComponentInternalInstance;
const internalValue = ref();
const internalValue = ref<T>() as Ref<T>;
internalValue.value = defaultValue;

// 受控模式
// 受控模式 v-model:propName
if (typeof value.value !== 'undefined') {
return [value, onChange || (() => {})];
return [
value,
(newValue, ...args) => {
emit?.(`update:${propName}`, newValue, ...args);
onChange?.(newValue, ...args);
},
];
}

// 受控模式:modelValue
// 受控模式:modelValue v-model
if (typeof modelValue.value !== 'undefined') {
return [
modelValue,
Expand All @@ -32,10 +38,14 @@ export function useVModel<T, P extends any[]>(

// 非受控模式
return [
internalValue as Ref<T>,
internalValue,
(newValue, ...args) => {
internalValue.value = newValue;
onChange?.(newValue, ...args);
},
];
}

// emits name
export const UPDATE_MODEL = 'update:modelValue';
export const UPDATE_VALUE = 'update:value';
28 changes: 4 additions & 24 deletions src/slider/demos/base.vue
Original file line number Diff line number Diff line change
@@ -1,29 +1,9 @@
<template>
<div class="cell-base">
<t-cell-group title="基础滑动选择器">
<t-cell label="选择器标题">
<t-slider v-model="value" @change="onChange"> </t-slider>
</t-cell>
<t-cell label="禁用选择器">
<t-slider v-model="value" disabled> </t-slider>
</t-cell>
</t-cell-group>
</div>
<t-slider v-model="value" />
</template>

<script lang="ts">
import { ref, defineComponent } from 'vue';
<script lang="ts" setup>
import { ref } from 'vue';
export default defineComponent({
setup() {
const value = ref(60);
function onChange($event: number | number[]) {
console.log(`change to ${$event}`);
}
return {
value,
onChange,
};
},
});
const value = ref(60);
</script>
33 changes: 33 additions & 0 deletions src/slider/demos/disable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<template>
<div class="section">
<t-slider :default-value="60" disabled />
</div>
<div class="section">
<t-slider :default-value="30" show-extreme-value :min="30" disabled />
</div>
<div class="section">
<t-slider :default-value="50" :marks="marks" disabled />
</div>
<div class="section">
<t-slider :default-value="[30, 80]" range disabled />
</div>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
const marks = ref({ 0: '', 50: '', 100: '' });
</script>

<style lang="less" scoped>
.section {
// display: flex;
align-items: center;
padding-top: 16px;
padding-bottom: 16px;
& + .section {
margin-top: 16px;
}
}
</style>
33 changes: 11 additions & 22 deletions src/slider/demos/mark.vue
Original file line number Diff line number Diff line change
@@ -1,27 +1,16 @@
<template>
<div class="cell-base">
<t-cell-group title="带刻度滑动选择器">
<t-cell label="选择器标题">
<t-slider v-model="value" :marks="marks"> </t-slider>
</t-cell>
<t-cell label="禁用选择器">
<t-slider v-model="value" disabled :marks="marks"> </t-slider>
</t-cell>
</t-cell-group>
</div>
<t-slider v-model="value" :marks="marks" />
</template>

<script lang="ts">
import { ref, defineComponent } from 'vue';
<script lang="ts" setup>
import { ref } from 'vue';
export default defineComponent({
setup() {
const value = ref(50);
const marks = ref({ 0: '', 50: '', 100: '' });
return {
value,
marks,
};
},
});
const value = ref(50);
const marks = ref({ 0: '', 50: '', 100: '' });
// const marks = ref([0, 50, 100]);
// const marks = ref({
// 0: (val: number) => `${val}%`,
// 50: (val: number) => `${val}%`,
// 100: (val: number) => `${val}%`,
// });
</script>
62 changes: 36 additions & 26 deletions src/slider/demos/mobile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,58 @@
<p class="summary">滑动滑块来选择一个数值,在具体场景中也可以增加来刻度和展示数值来方便用户使用</p>
<tdesign-demo-block title="01 类型" summary="基础滑动选择器">
<div class="slider-demo">
<t-slider v-model="value" @change="onChange"> </t-slider>
<BaseDemo />
</div>
</tdesign-demo-block>
<tdesign-demo-block summary="带数值滑动选择器">
<div class="slider-demo">
<t-slider v-model="value1" show-value> </t-slider>
<ValueDemo />
</div>
</tdesign-demo-block>
<tdesign-demo-block summary="起始非零滑动选择器">
<div class="slider-demo">
<t-slider :default-value="30" :min="30" show-extreme-value> </t-slider>
</div>
</tdesign-demo-block>
<tdesign-demo-block summary="带刻度滑动选择器">
<div class="slider-demo">
<t-slider v-model="value2" :marks="marks"> </t-slider>
<MarkDemo />
</div>
</tdesign-demo-block>
<tdesign-demo-block summary="区间滑动选择器">
<div class="slider-demo">
<t-slider v-model="rangeValue" show-value range @change="onChange"> </t-slider>
<RangeDemo />
</div>
</tdesign-demo-block>
<tdesign-demo-block title="02 状态" summary="滑动选择器禁用状态">
<div class="slider-demo">
<DisableDemo />
</div>
</tdesign-demo-block>
</div>
</template>

<script lang="ts">
import { ref, defineComponent } from 'vue';
<script lang="ts" setup>
import { ref } from 'vue';
import BaseDemo from './base.vue';
import MarkDemo from './mark.vue';
import ValueDemo from './value.vue';
import RangeDemo from './range.vue';
import DisableDemo from './disable.vue';
export default defineComponent({
setup() {
const value = ref(60);
const value1 = ref(60);
const value2 = ref(50);
const marks = ref({ 0: '', 50: '', 100: '' });
const rangeValue = ref([30, 70]);
function onChange($event: number | number[]) {
console.log(`change to ${$event}`);
}
return {
value,
value1,
value2,
rangeValue,
marks,
onChange,
};
},
});
const value = ref(60);
const value1 = ref(60);
const value2 = ref(50);
const marks = ref({ 0: '', 50: '', 100: '' });
const rangeValue = ref([30, 70]);
function onChange($event: number | number[]) {
console.log(`change to ${$event}`);
}
</script>

<style scoped>
.tdesign-mobile-demo {
background: #fff;
}
</style>
32 changes: 8 additions & 24 deletions src/slider/demos/range.vue
Original file line number Diff line number Diff line change
@@ -1,29 +1,13 @@
<template>
<div class="cell-base">
<t-cell-group title="区间滑动选择器">
<t-cell label="选择器标题">
<t-slider v-model="rangeValue" show-value range @change="onChange"> </t-slider>
</t-cell>
<t-cell label="禁用选择器">
<t-slider v-model="rangeValue" range disabled> </t-slider>
</t-cell>
</t-cell-group>
</div>
<t-slider v-model="rangeValue" show-value range @change="onChange" />
</template>

<script lang="ts">
import { ref, defineComponent } from 'vue';
<script lang="ts" setup>
import { ref } from 'vue';
export default defineComponent({
setup() {
const rangeValue = ref([30, 80]);
function onChange($event: number | number[]) {
console.log(`change to ${$event}`);
}
return {
rangeValue,
onChange,
};
},
});
const rangeValue = ref([30, 80]);
function onChange($event: number | number[]) {
console.log(`change to ${$event}`);
}
</script>
24 changes: 4 additions & 20 deletions src/slider/demos/value.vue
Original file line number Diff line number Diff line change
@@ -1,25 +1,9 @@
<template>
<div class="cell-base">
<t-cell-group title="带数字滑动选择器">
<t-cell label="选择器标题">
<t-slider v-model="value" show-value> </t-slider>
</t-cell>
<t-cell label="禁用选择器">
<t-slider v-model="value" disabled show-value> </t-slider>
</t-cell>
</t-cell-group>
</div>
<t-slider v-model="value" show-value />
</template>

<script lang="ts">
import { ref, defineComponent } from 'vue';
<script lang="ts" setup>
import { ref } from 'vue';
export default defineComponent({
setup() {
const value = ref(60);
return {
value,
};
},
});
const value = ref(60);
</script>
Loading

0 comments on commit af205a8

Please sign in to comment.