目录
封装展示类组件
/src/examples/
/src/examples/
/src/examples/
封装容器类组件
封装输入组件
封装展示类组件
- Coding:纯展示类组件封装
- Coding:样式的处理
/src/examples/
.btn {
background-color: rgb(0, 119, 255);
}
.btn:hover {
background-color: rgb(0, 204, 255);
}
/src/examples/
.btn {
padding: 10px;
font-size: 18px;
border: none;
color: #fff;
}
.btn:hover {
color: #333;
}
/src/examples/
import { defineComponent, computed, ref, reactive, toRefs } from "vue";
import type { PropType, VNode, Ref } from 'vue'
// npm install scss 安装一下scss
import './'
import classes from "./" // 样式hash值全局不冲突
export const Component01 = () => {
return <Button text={"Hello button!!"} />
}
// 封装展示类组件
const Button = defineComponent({
props: {
text: {
type: String
}
},
setup({ text }) {
return () => {
// 样式的处理
// CSS Module
return <button class={[, "btn"]} style={{
border: "1px solid red",
}
}> {text}</button >
}
}
})
export const Component02 = () => {
// 样式的处理
return <Button2>
<span style={{ color: 'red', "font-size": '30px' }}>Hello button</span>
</Button2>
}
const Button2 = defineComponent({
setup(props, { slots }) {
const child = !
const Child = (!) as any as () =>
return () => {
return (
<div>
<button>【child()】:{child()}</button>
<button>【< Child />】:<Child /></button>
</div>
)
}
}
})
export const Component03 = () => {
return <Panel header={
<span>header:Title</span>
}
v-slots={{
header: <span>:Title</span>
}}>
<span>Hello Content</span>
</Panel >
}
const Panel = defineComponent({
props: {
header: Object as PropType<>
},
setup(props, { slots }) {
return () => {
return (
<div>
<header>{}</header>
<header>{!()}</header>
{!()}
</div>
)
}
}
})
封装容器类组件
- Coding:容器类组件封装
- Coding:Copy Props
import { defineComponent, computed, ref, reactive, toRefs } from "vue";
import type { PropType, VNode, Ref } from 'vue'
// 封装容器类组件
export const Component04 = () => {
return (
<Flex>
<div>
<div>a</div>
<div>b</div>
<div>c</div>
<div>d</div>
</div>
</Flex>
)
}
// 仅是举例,一般Flex不这样用,只有特别重要容器组件才会这样使用
const Flex = defineComponent({
setup(props, { slots }) {
return () => {
const vNode: VNode = !()[0] // 追求的是语义上的完美
if (!) {
= {}
}
= {
display: 'flex'
}
(vNode)
// <></>展示出来不占层级
return <>
{vNode}
</>
}
}
})
封装输入组件
- Coding:封装Input组件
追求的是语义上的完美
import { defineComponent, computed, ref, reactive, toRefs } from "vue";
import type { PropType, VNode, Ref } from 'vue'
// 封装输入类组件
export const Component05 = defineComponent({
setup() {
const form = reactive({
username: "abc"
})
setTimeout(() => {
= "def"
}, 1000)
const { username } = toRefs(form)
return () => {
return (
<Input value={username} />
)
}
}
})
const Input = ({ value }: { value: Ref<string> }) => {
('重绘:re render') // 非真实重绘,只是计算重绘,并没有渲染重绘
return <input value={} onInput={e => {
= ( as HTMLInputElement).value
}} />
}
export const Component06 = defineComponent({
setup() {
const { form } = useForm({ // 初始值,表单项
username: "abc",
password: '123456'
})
setTimeout(() => {
= "def"
= "jqkA123"
}, 1000)
return () => {
return (
<div>
<button onClick={() => {
(())
}}>submit</button>
<Input1
{...('username')}
/>
<Input1
value={}
onChange={v => {
// 会冒泡,覆盖这里
= v
}}
/>
</div>
)
}
}
})
const Input1 = ({
value,
onChange }: {
value: string,
onChange?: (v: string) => void
}) => { // value: Ref<string>过度包装
return <input value={value}
onChange={e => {
// 阻止一下这里冒泡
()
}}
onInput={e => {
onChange && onChange(( as HTMLInputElement).value)
}} />
}
// 表单类
class Form<T extends Record<string, any>> {
private data: {
[key: string]: any
}
constructor(data: T) {
= reactive(data)
}
public getValue(key: string) {// ver 当前版本号
return [key]
}
public setValue(key: string, value: any) {
[key] = value
}
public getValues = () => {
// return unref()
return (())
}
public getField = (key: string): { // === v-model
value: any
onChange: (v: any) => void
} => {
return {
value: [key],
onChange: (v: any) => {
[key] = v
}
}
}
}
// 接口
interface FormOperators<T> {
getValues(): T,
getField(key: string): { value: any, onChange: (v: any) => void }
}
// 表单函数 代理
function useForm<T extends Record<string, any>>(data: T) {
const form = new Form<T>(data)
const proxy = new Proxy(form, {
get(target, key) {
if (key === 'getValues') {
return
} else if (key === 'getField') {
return
}
return (key as string)
},
set(target, key, value) {
(key as string, value)
return true
}
})
return {
form: proxy as any as (T & FormOperators<T>) // 类型转换
}
}