vue和react的组件封装之路

122 阅读3分钟

vue封装组件

vue组件三要素

props参数
slot定制插槽
event自定义事件

vue2

一、props:数据父组件传入子组件

 props: {
    // 基础类型检测 (`null` 意思是任何类型都可以)
    propA: Number,
    // 多种类型
    propB: [String, Number],
    // 必传且是字符串
    propC: {
      type: String,
      required: true
    },
    // 数字,有默认值
    propD: {
      type: Number,
      default: 100
    },
    // 数组/对象的默认值应当由一个工厂函数返回
    propE: {
      type: Object,
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        return value > 10
      }
    }
  }

二、子组件触发父组件事件

在通用组件中,通常会需要有各种事件,比如复选框的 change 事件,或者组件中某个按钮的 click 事件,有时子组件需要触发一个事件,并传递给父组件

// 子组件方法:触发父组件方法,并传递参数data到父组件
handleSubmit(data){
    this.$emit('submitToParent', data)
}


// 父组件调用子组件
<child-component @submitToParent="parentSubmit"></child-component>
... ...
// 父组件中被触发的方法,接受到子组件传来的参数
parentSubmit(data){
    // 父组件的逻辑处理
}


三、记得留一个 slot

开发通用组件的时候,只要不是独立性很高的组件,建议都留一个 slot,即使还没想好用来干什么。

子组件
<div class="child-btn">
    <!-- 具名插槽 -->
    <slot name="button"></slot>
    <!-- 匿名插槽(每个组件只能有一个) -->
    <slot><slot>
</div>
 
父组件
<child>
    <!-- 对应子组件中button的插槽 -->
    <button slot="button">slot按钮</button>
</child>


四、组件的css:合理运用 scoped 控制样式作用域

在编写组件的时候,可以在 style 标签中添加 scoped,让标签中的样式只对当前组件生效 但是一味的使用 scoped,肯定会产生大量的重复代码 所以在开发的时候,应该避免在组件中写样式 当全局样式写好之后,再针对每个组件,通过 scoped 属性添加组件样式

五、动态组件


          <component :is="componentName"
            :vehicleId="vehicleId"
            :groupIds="groupIds"
            ref="componentRef"
            :option="option"
            :tableDatas="tableDatas" />
   

vue3

父传子

<child :list='list'></child>

<script>
	let list:number[] = [1,2,3]
</script>

defineProps({
    list:number[]
})

子传父

<templete>
    <button @click='send'>子组件向父组件派发事件</button>
</templete>

<script>
    let str:string='我是子组件参数'
	const emit = defineEmits(['fatherFun'])
	const send = ()=>{
		 emit('fatherFun',str)     // 第一个参数是子组件派发的函数名(子传父是通过函数事件派发)   
	}
</script>

<child @fatherFun='getChildData' ></child>  // 子组件

<script>
const getChildData = (val)=>{               // val 子			组件传递的参数
    console.log(val)
}
</script>

react组件封装

类组件

父传子

父组件

import React, { Component } from 'react'
import Item from './Item'
export default class List extends Component {
    render() {
        return (
            <div>
                <ul className="list">
                    {
                        this.props.list.map(item=>{
                            return(
                                <Item  item={item} key={item.id}/>
                            )
                        })
                    }
                </ul>
            </div>
        )
    }
}

Item组件

import React, { Component } from 'react'

export default class Item extends Component {
    constructor(props) {
        super()
        this.state = {
            baseImgUrl: "http://yzs.can.com/img/"
        }
    }
    render() {
        let { image_path, name, recent_order_num, float_minimum_order_amount, piecewise_agent_fee, distance, order_lead_time } = this.props.item
        return (
                <li>
                    <div className="search-left">
                        <img src={this.state.baseImgUrl + image_path} alt={name}/>
                    </div>
                    <div className="search-right">
                        <p className="title"><strong>品牌</strong> {name}</p>
                        <p>月售{recent_order_num} 单</p>
                        <p>
                            ¥{float_minimum_order_amount}起送/{
                                piecewise_agent_fee.tips
                            }
                            <span>{distance}/ </span>
                            <i>{order_lead_time}</i>
                        </p>
                    </div>
                </li>
        )
    }
}

子传父

子组件

import React from 'react';

class Son extends React.Component {
    //构造方法
    constructor(){
        super();
        this.state = {
            inputValue:''
        }
    }
    //按钮点击事件
    handleClick(){
        //通过props属性获取父组件的getdata方法,并将this.state值传递过去
        this.props.getdata(this.state.inputValue);
    }
    //输入框事件,用于为this.state赋值
    handleChange(e){
        this.setState({
            inputValue: e.target.value
        });
    }

    render(){
        return (
            <React.Fragment>
                <input onChange={this.handleChange.bind(this)}></input>
                <button onClick={this.handleClick.bind(this)}>点击获取数据</button>
            </React.Fragment>
        );
    }

}

export default Son;

父组件

import React from 'react';
import Son from './Son';

class Parent extends React.Component {
    //构造方法
    constructor(){
        super();
        this.state = {
            mess: '' //初始化mess属性
        }
    }
    //用于接收子组件的传值方法,参数为子组件传递过来的值
    getDatas(msg){
        //把子组件传递过来的值赋给this.state中的属性
        this.setState({
            mess: msg
        });
    }

    render(){
        return (
            <React.Fragment>
                {/* 渲染子组件,设置子组件访问的方法,
                getdata属性名为子组件中调用的父组件方法名 */}
                <Son getdata={this.getDatas.bind(this)}></Son>
                <div>展示数据:{this.state.mess}</div>
            </React.Fragment>
        );
    }

}

export default Parent;

react-hook

父传子

import React, { useState } from 'react';

// 父组件
const PropsCom = () => {
    const [name, setName] = useState('winne');

    return (
        <div>
            <h2>父组件</h2>
            {/* 这里是重要代码,向子组件传递parentName这个prop,值为name变量 */}
            <ChildrenCom parentName={name} />
        </div>
    );
};

// 子组件
const ChildrenCom = (props) => (
    <div>
        <h4>子组件</h4>
        <p>获取父组件传过来的值:{props.parentName}</p>
    </div>
);

export default PropsCom;


子传父

import React, { useState } from 'react';
import { Button } from 'antd';

// 父组件
const CallbackCom = () => {
    const [count, setCount] = useState(0);

    // 获取子组件传过来的value值并设置到count,val参数就是子组件的value值
    const getChildrenValue = (val) => {
        setCount(val);
    };

    return (
        <div>
            <h2>父组件</h2>
            <p>获取子组件传过来的值:{count}</p>
            {/* 这里是重要代码,向子组件传递getValue这个prop,它的值是一个回调函数 */}
            <ChildrenCom getValue={getChildrenValue} />
        </div>
    );
};

// 子组件
const ChildrenCom = (props) => {
    const [value, setValue] = useState(0);

    const addValue = () => {
        setValue(value + 1);
        // 向父组件传递每次递增的value值
        props.getValue(value + 1);
    };

    return (
        <div>
            <h4>子组件</h4>
            <Button onClick={addValue}>点击改变子组件的value值:{value}</Button>
        </div>
    );
};

export default CallbackCom;