vue3实战技巧 - 组件的封装

目录

封装展示类组件

/src/examples/button.module.scss

/src/examples/button.scss

/src/examples/Components.tsx

封装容器类组件

封装输入组件


封装展示类组件

  • Coding:纯展示类组件封装
  • Coding:样式的处理

/src/examples/button.module.scss

.btn {
  background-color: rgb(0, 119, 255);
}
.btn:hover {
  background-color: rgb(0, 204, 255);
}

/src/examples/button.scss

.btn {
  padding: 10px;
  font-size: 18px;
  border: none;
  color: #fff;
}
.btn:hover {
  color: #333;
}

/src/examples/Components.tsx

import { defineComponent, computed, ref, reactive, toRefs } from "vue";
import type { PropType, VNode, Ref } from 'vue'
// npm install scss 安装一下scss
import './button.scss'
import classes from "./button.module.scss" // 样式hash值全局不冲突classes.btn
export const Component01 = () => {
  return 
    }
  }
})
export const Component02 = () => {
  // 样式的处理
  return 
    Hello button
  
}
const Button2 = defineComponent({
  setup(props, { slots }) {
    const child = slots.default!
    const Child = (slots.default!) as any as () => JSX.Element
    return () => {
      return (
        
                           
      )     }   } }) export const Component03 = () => {   return header:Title   }     v-slots={{       header: slots.header:Title     }}>     Hello Content   } const Panel = defineComponent({   props: {     header: Object as PropType   },   setup(props, { slots }) {     return () => {       return (        
         
{props.header}
         
{slots.header!()}
          {slots.default!()}        
      )     }   } })

封装容器类组件

  • Coding:容器类组件封装
  • Coding:Copy Props
import { defineComponent, computed, ref, reactive, toRefs } from "vue";
import type { PropType, VNode, Ref } from 'vue'
// 封装容器类组件
export const Component04 = () => {
  return (
    
      
       
a
       
b
       
c
       
d
     
   
  ) } // 仅是举例,一般Flex不这样用,只有特别重要容器组件才会这样使用 const Flex = defineComponent({   setup(props, { slots }) {     return () => {       const vNode: VNode = slots.default!()[0] // 追求的是语义上的完美       if (!vNode.props) {         vNode.props = {}       }       vNode.props.style = {         display: 'flex'       }       console.log(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(() => {
      form.username = "def"
    }, 1000)
    const { username } = toRefs(form)
    return () => {
      return (
        
      )
    }
  }
})
const Input = ({ value }: { value: Ref }) => {
  console.log('重绘:re render') // 非真实重绘,只是计算重绘,并没有渲染重绘
  return  {
    value.value = (e.target as HTMLInputElement).value
  }} />
}
export const Component06 = defineComponent({
  setup() {
    const { form } = useForm({ // 初始值,表单项
      username: "abc",
      password: '123456'
    })
    setTimeout(() => {
      form.username = "def"
      form.password = "jqkA123"
    }, 1000)
    return () => {
      return (
        
                              {               // 会冒泡,覆盖这里               form.password = v             }}           />        
      )     }   } }) const Input1 = ({   value,   onChange }: {     value: string,     onChange?: (v: string) => void   }) => { // value: Ref过度包装   return {       // 阻止一下这里冒泡       e.stopImmediatePropagation()     }}     onInput={e => {       onChange && onChange((e.target as HTMLInputElement).value)     }} /> } // 表单类 class Form> {   private data: {     [key: string]: any   }   constructor(data: T) {     this.data = reactive(data)   }   public getValue(key: string) {// ver 当前版本号     return this.data[key]   }   public setValue(key: string, value: any) {     this.data[key] = value   }   public getValues = () => {     // return unref(this.data)     return JSON.parse(JSON.stringify(this.data))   }   public getField = (key: string): { // === v-model     value: any     onChange: (v: any) => void   } => {     return {       value: this.data[key],       onChange: (v: any) => {         this.data[key] = v       }     }   } } // 接口 interface FormOperators {   getValues(): T,   getField(key: string): { value: any, onChange: (v: any) => void } } // 表单函数 代理 function useForm>(data: T) {   const form = new Form(data)   const proxy = new Proxy(form, {     get(target, key) {       if (key === 'getValues') {         return form.getValues       } else if (key === 'getField') {         return form.getField       }       return form.getValue(key as string)     },     set(target, key, value) {       form.setValue(key as string, value)       return true     }   })   return {     form: proxy as any as (T & FormOperators) // 类型转换   } }

你可能感兴趣的:(vue相关,#,vue3实战技巧,前端,javascript,vue.js)