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;