Skip to content

Commit ca4a280

Browse files
kagolgitee-org
authored andcommitted
!265 textarea组件
Merge pull request !265 from Afterain/dev
2 parents 65cbca2 + 50cc098 commit ca4a280

File tree

6 files changed

+334
-0
lines changed

6 files changed

+334
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { mount } from '@vue/test-utils';
2+
import { Textarea } from '../index';
3+
4+
describe('textarea test', () => {
5+
it('textarea init render', async () => {
6+
// todo
7+
})
8+
})
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import type { App } from 'vue'
2+
import Textarea from './src/textarea'
3+
4+
Textarea.install = function(app: App): void {
5+
app.component(Textarea.name, Textarea)
6+
}
7+
8+
export { Textarea }
9+
10+
export default {
11+
title: 'Textarea 多行文本框',
12+
category: '数据录入',
13+
status: '已完成', // TODO: 组件若开发完成则填入"已完成",并删除该注释
14+
install(app: App): void {
15+
app.use(Textarea as any)
16+
}
17+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import type { PropType, ExtractPropTypes } from 'vue';
2+
3+
export const textareaProps = {
4+
id: {
5+
type: String,
6+
default: undefined,
7+
},
8+
autofocus: {
9+
type: Boolean,
10+
default: false,
11+
},
12+
showCount: {
13+
type: Boolean,
14+
default: false,
15+
},
16+
placeholder: {
17+
type: String,
18+
default: undefined,
19+
},
20+
value: {
21+
type: String,
22+
default: '',
23+
},
24+
maxLength: {
25+
type: [String, Number] as PropType<number | string>,
26+
default: undefined,
27+
},
28+
disabled: {
29+
type: Boolean,
30+
default: false,
31+
},
32+
error: {
33+
type: Boolean,
34+
default: false,
35+
},
36+
cssClass: {
37+
type: String,
38+
default: '',
39+
},
40+
resize: {
41+
type: String as PropType<
42+
'none' | 'vertical' | 'horizontal' | 'both' | 'inherit'
43+
>,
44+
default: 'none',
45+
},
46+
} as const;
47+
48+
export type TextareaProps = ExtractPropTypes<typeof textareaProps>;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@import '../../style/core/form';
2+
3+
.devui-textarea-wrap {
4+
.devui-textarea-show-count {
5+
text-align: right;
6+
color: inherit;
7+
white-space: nowrap;
8+
pointer-events: none;
9+
font-size: $devui-font-size;
10+
}
11+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { defineComponent, ref } from "vue";
2+
import { textareaProps, TextareaProps } from "./textarea-types";
3+
import "./textarea.scss";
4+
5+
export default defineComponent({
6+
name: "DTextarea",
7+
props: textareaProps,
8+
emits: ["update:value", "focus", "blur", "change", "keydown"],
9+
setup(props: TextareaProps, ctx) {
10+
const textareaCls = {
11+
error: props.error,
12+
[props.cssClass]: true,
13+
};
14+
15+
const curValueRef = ref<string>(props.value);
16+
const onInput = ($event: Event) => {
17+
const inputValue = ($event.target as HTMLInputElement).value;
18+
curValueRef.value = inputValue;
19+
ctx.emit("update:value", inputValue);
20+
},
21+
onFocus = ($event: Event) => {
22+
ctx.emit("focus", $event);
23+
},
24+
onBlur = ($event: Event) => {
25+
ctx.emit("blur", $event);
26+
},
27+
onChange = ($event: Event) => {
28+
ctx.emit("change", ($event.target as HTMLInputElement).value);
29+
},
30+
onKeydown = ($event: KeyboardEvent) => {
31+
ctx.emit("keydown", $event);
32+
};
33+
34+
return {
35+
textareaCls,
36+
onInput,
37+
onFocus,
38+
onBlur,
39+
onChange,
40+
onKeydown,
41+
curValueRef,
42+
autofocus: props.autofocus,
43+
};
44+
},
45+
render() {
46+
const {
47+
id,
48+
placeholder,
49+
disabled,
50+
maxLength,
51+
resize,
52+
textareaCls,
53+
onInput,
54+
onFocus,
55+
onBlur,
56+
onChange,
57+
onKeydown,
58+
showCount,
59+
autofocus,
60+
curValueRef,
61+
} = this;
62+
return (
63+
<div class="devui-textarea-wrap">
64+
<textarea
65+
{...{ DTextarea: true }}
66+
id={id}
67+
value={curValueRef}
68+
autofocus={autofocus}
69+
placeholder={placeholder}
70+
disabled={disabled}
71+
maxlength={maxLength}
72+
style={{ resize: resize }}
73+
class={textareaCls}
74+
onInput={onInput}
75+
onFocus={onFocus}
76+
onBlur={onBlur}
77+
onChange={onChange}
78+
onKeydown={onKeydown}
79+
></textarea>
80+
{showCount && (
81+
<div class="devui-textarea-show-count">
82+
{curValueRef.length}
83+
{!(maxLength ?? false) ? "" : " / " + maxLength}
84+
</div>
85+
)}
86+
</div>
87+
);
88+
},
89+
});
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
# Textarea 多行文本框
2+
3+
文本输入区域。
4+
5+
### 何时使用
6+
7+
需要手动输入文字,并且文字内容较多时使用。
8+
9+
### 基本用法
10+
11+
:::demo
12+
13+
```vue
14+
<template>
15+
<h4 style="margin: 10px 0">Default</h4>
16+
17+
<d-textarea
18+
value="我是默认值"
19+
:autofocus="true"
20+
id="textArea"
21+
cssClass="my-text-area"
22+
></d-textarea>
23+
24+
<h4 style="margin: 10px 0">Disabled</h4>
25+
26+
<d-textarea placeholder="我是被禁用状态" :disabled="true"></d-textarea>
27+
28+
<h4 style="margin: 10px 0">Error</h4>
29+
30+
<d-textarea placeholder="我是出错状态" :error="true"></d-textarea>
31+
</template>
32+
<style>
33+
.dinput {
34+
width: 200px;
35+
}
36+
</style>
37+
```
38+
39+
:::
40+
41+
### 调整大小
42+
43+
:::demo
44+
45+
```vue
46+
<template>
47+
<h4 style="margin: 10px 0">vertical</h4>
48+
<d-textarea placeholder="我可以缩放" resize="vertical"></d-textarea>
49+
50+
<h4 style="margin: 10px 0">horizontal</h4>
51+
52+
<d-textarea resize="horizontal" placeholder="请输入"></d-textarea>
53+
54+
<h4 style="margin: 10px 0">both</h4>
55+
56+
<d-textarea resize="both" placeholder="请输入"></d-textarea>
57+
58+
<h4 style="margin: 10px 0">none</h4>
59+
60+
<d-textarea resize="none" placeholder="请输入"></d-textarea>
61+
62+
<h4 style="margin: 10px 0">inherit</h4>
63+
64+
<d-textarea resize="inherit" placeholder="请输入"></d-textarea>
65+
</template>
66+
```
67+
68+
:::
69+
70+
### 显示字数
71+
72+
:::demo
73+
74+
```vue
75+
<template>
76+
<h4 style="margin: 10px 0">默认</h4>
77+
<d-textarea :showCount="true" placeholder="请输入"></d-textarea>
78+
<h4 style="margin: 10px 0">显示最大字数</h4>
79+
<d-textarea
80+
:showCount="true"
81+
:maxLength="20"
82+
placeholder="请输入"
83+
></d-textarea>
84+
</template>
85+
<style>
86+
.dinput {
87+
width: 200px;
88+
}
89+
</style>
90+
```
91+
92+
:::
93+
94+
### 事件响应
95+
96+
:::demo
97+
98+
```vue
99+
<template>
100+
<d-textarea
101+
:showCount="true"
102+
:maxLength="20"
103+
placeholder="打开控制台输入文字看看"
104+
@update:value="onUpdate"
105+
@change="onChange"
106+
@focus="onFocus"
107+
@keydown="onKeydown"
108+
></d-textarea>
109+
</template>
110+
<script>
111+
export default {
112+
setup() {
113+
const onUpdate = (value) => {
114+
console.log("【d-textarea update value】: ", value);
115+
};
116+
const onChange = (value) => {
117+
console.log("【d-textarea change value】:", value);
118+
};
119+
const onFocus = (e) => {
120+
console.log("【d-textarea onFocus】:", e);
121+
};
122+
const onKeydown = (e) => {
123+
console.log("【d-textarea onKeydown:", e);
124+
};
125+
return {
126+
onUpdate,
127+
onChange,
128+
onFocus,
129+
onKeydown,
130+
};
131+
},
132+
};
133+
</script>
134+
```
135+
136+
:::
137+
138+
### d-textarea API
139+
140+
d-textarea 参数
141+
142+
| 参数 | 类型 | 默认 | 说明 | 跳转 Demo | 全局配置项 |
143+
| ----------- | --------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------ | --------------------- | ---------- |
144+
| id | string | `-` | 可选,文本框 id | [基本用法](#基本用法) | |
145+
| placeholder | string | `-` | 可选,文本框 placeholder | [基本用法](#基本用法) | |
146+
| value | string | `-` | 可选,文本框默认值 | [基本用法](#基本用法) | |
147+
| disabled | boolean | `false` | 可选,文本框是否被禁用 | [基本用法](#基本用法) | |
148+
| autoFocus | boolean | `false` | 可选,文本框是否自动获得焦点 | [基本用法](#基本用法) | |
149+
| error | boolean | `false` | 可选,文本框是否出现输入错误 | [基本用法](#基本用法) | |
150+
| resize | `'none' \|'vertical' \|'horizontal' \|'both' \|'inherit'` | `'none'` | 可选,文本框是否可调整大小,可选项:不可调整,水平调整,垂直调整,自由调整,默认继承 | [调整大小](#调整大小) | |
151+
| showCount | boolean | `false` | 可选,文本框是否是否展示字数 | [显示字数](#显示字数) | |
152+
153+
d-textarea 事件
154+
155+
| 事件 | 类型 | 说明 | 跳转 Demo |
156+
| ------- | ---------------------- | ------------------------------ | --------------------- |
157+
| update | `EventEmitter<string>` | 文本框内容变化(实时触发) | [事件响应](#事件响应) |
158+
| focus | `EventEmitter<Event>` | 文本框获得焦点 | [事件响应](#事件响应) |
159+
| blur | `EventEmitter<Event>` | 文本框失去焦点 | [事件响应](#事件响应) |
160+
| change | `EventEmitter<string>` | 文本框内容变化(失去焦点触发) | [事件响应](#事件响应) |
161+
| keydown | `EventEmitter<Event>` | 文本框按下键盘 | [事件响应](#事件响应) |

0 commit comments

Comments
 (0)