其他分享
首页 > 其他分享> > vue和react的组件传值

vue和react的组件传值

作者:互联网

vue组件传值

1. 父组件给子组件传值

<!-- 父组件中使用子组件 -->
<!-- n和list是一个自定义属性 后面的num和list是父组件的data数据 -->
<child-1 :n="num" :list="list"></child-1>

<!-- 子组件在default中用prop接受数据 -->
props:["n","list"], //接受父组件传递过来的数据的一个自定义属性

2. 子组件给父组件传值

<!-- 父组件中使用子组件 -->
<!-- 通过自定义的事件利用方法获取到子组件的数据 -->
<Child2 @abcd="setUsername"></Child2>
并在default中定义方法
    methods:{
        setUsername(value){
            this.username = value;
        }
    }

<!-- 子组件中使用this.$emit调用事件abcd传递数据this.uesername -->
<button @click="fn">将数据传给父组件</button>
methods:{
	fn(){
		this.$emit("abcd",this.username);
	}
}

3. 子传子(非父子组件传值)

利用公共父组件

需求: 将 child1 更新或改变的数据传递给同级的 child2接受

思路: 利用公共的父元素

步骤: 先实现子传父(利用自定义事件) => 再父传子(利用)

中央事件总线bus传值
const bus = new Vue()

// 接受数据
bus.$on('my-event', (val) => {
  // val 即为接收的数据 1000
})

// 传递数据
bus.$emit('my-event', 1000)

4. 跨层级

provide 和 inject

  这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,
  不论组件层次有多深,并在起上下游关系成立的时间里始终生效。
  provide 和 inject 绑定并不是可响应的。这是刻意为之的。
  然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。

{
	data () { return { msg: 'hello world'} },
    provide: { // ✅
      str: 'hi'
    }
  // provide: {// ❌
  //   str: this.msg 
  // }
  provide () { // ✅
    return {
      str: this.msg
    }
  }
}

{inject: ['str']}

5. 子组件直接获取父组件的实例

子组件直接通过 $parent 可以获取到父组件的实例

6. 父组件直接获取子组件的实例

父组件调用子组件时添加 ref 属性, 通过 this.$refs 获取到子组件的实例

7. 全局数据管理

//vuex的五个核心概念:
state: {},   数据源(保存全局数据)
getters: {},   计算属性(将store中的数据加工后输出)
actions: {},   异步方法(异步操作必需放到Action中,但只能通过触发同步方法更新数据)
mutations: {},  同步方法(保存更改数据的回调函数,不能包含异步操作)
modules: {   模块(让代码更好维护,数据分类更明确)
	moduleA: {
		namespaced: true, //开启命名空间
		state: {},
    actions: {},
    mutations: {},
	},
	moduleB: {
		namespaced: true,
		state: {},
    actions: {},
    mutations: { 
    	[常量](){} //可以使用常量代替Mutation事件类型
    },
	}
}
# 数据在页面中的使用和更新
---
## 访问state中数据
1. this.$store.state.全局数据名称 (在页面中直接使用/计算属性)
2. mapState映射为计算属性 : 通过导入的`mapState函数`将当前组件需要的全局数据, 映射为当前组件的computed计算属性,在页面中直接使用
computed:{
  ...mapState(['count']) //利用展开运算符将全局数据映射为当前组件的计算属性
}

## 访问getters计算属性
1. $store.getters.名称 访问
2. mapGetters 映射为计算属性
computed:{
	...mapGetters(['showNum'])
}

## 调用Mutation中的方法
1. this.$store.commit() 触发 mutations
2. MapMutations 映射为方法

## 调用Action中的方法
1. this.$store.dispatch 触发 Actions
2. mapActions 映射为方法

computed: {
	...mapState(),
	...mapGetters()
},
methods: {
	...mapActions({ fn: 'user/fn' })
	...mapMutations({ change: 'user/change'})
}

react组件传值

1. 父组件给子组件传值

父组件给子组件传值的地方,添加自定义的属性,属性的值就是需要传递给子组件的值,如果属性的值为变量,boolean类型,number类型,对象,数组,null,undefined,函数,需要使用 {} 包裹

<my-com num={1000} fn={fn}></mycom>

在子组件中通过 this.props 或者 props获取父组件传递的数据

可以使用 prop-types 校验数据

2. 子组件给父组件传值

子组件给父组件传值实际上还是 父组件给子组件传值,只不过父传给子的是一个 函数,该函数由父组件定义(实现),该函数的默认值即为子组件需要传给父组件的值

const getData = (val) => {
	console.log(val) // 子传给父的
}

<my-com fn={getData}></mycom>

在子组件的某一个事件内部,通过 this.props.fn(参数) 或者 props.fn(参数) 完成传值

3. 非父子组件传值

react没有

4. 跨层级

1) 创建Context容器对象:
const XxxContext = React.createContext()  

2) 渲染子组时,外面包裹xxxContext.Provider, 通过value属性给后代组件传递数据:
<xxxContext.Provider value={数据}>
  子组件
</xxxContext.Provider>

3) 后代组件读取数据:

//第一种方式:仅适用于类组件 
static contextType = xxxContext  // 声明接收context
this.context // 读取context中的value数据

//第二种方式: 函数组件与类组件都可以
<xxxContext.Consumer>
  {
  value => ( // value就是context中的value数据
  要显示的内容
  )
}
  </xxxContext.Consumer>
// 类组件 contextType
class Com extends Component {
	static contextType = ColorContext
  render () {
    return (
    	<div>{ this.context }</div> 
    )
  }
}
//类组件 Context.Consumer
class Com extends Component { 
  render () {
    return (
    	<div>
      	<ColorContext.Consumer>
      	{
          (val) => {
      			return <div>{val}</div>
    			}
        }
      	</ColorContext.Consumer>
      </div> 
    )
  }
}
 
// 函数式组件  Context.Consumer
const App = () => {
  return (
  	<div>
      	<ColorContext.Consumer>
      	{
          (val) => {
      			return <div>{val}</div>
    			}
        }
      	</ColorContext.Consumer>
      </div> 
	)
}
// 函数式组件 useContext
const App = () => { // 推荐
  const color = useContext(ColorContext)
  return (
  	<div>{color}</div>
  )
}

// 如果使用开发者工具,发现多Context传值,指示不明确,使用 dispalyName
const ColorContext = React.createContext()
ColorContext.displayName = 'ColorContext'

5. 父组件获取子组件的实例

——————————————————————————————————子组件———————————————————————
import React, { useRef, forwardRef, useImperativeHandle } from 'react'

function Child4(props, ref) {
  let userageInput = useRef()
  useImperativeHandle(ref, () => ({
    getUserage: () => {
      return userageInput.current.value
    }
  }))
  return (
    <div>age:
      <input type="text" ref={userageInput}></input>
    </div>
  )
}
export default forwardRef(Child4)
//如果不使用forwardRef: Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

————————————————————————————父组件————————————————————————————
import React, { useRef } from 'react'
import Child4 from '../component/Child4'
export default function UseRef() {
  let usernameInput = useRef()
  let child4 = useRef() //给组件Child4声明一个唯一的名字
  return (
    <div>UseRef
      <div>name
        <input type="text" ref={usernameInput}></input>
        <button onClick={() => {
            console.log("name:", usernameInput.current.value);
          }}>取到input中的值</button>
      </div>
      <Child4 ref={child4}></Child4>
      <button onClick={() => {
          console.log("age:", child4.current.getUserage());
        }}>取到子组件中input中的值</button>
    </div>
  )
}

6. 全局管理(状态管理器)

多个视图依赖于同一个状态, 来自不同视图的行为需要变更同一个状态

react的状态管理器由多种, 都有各自的特性, react项目中常用的状态管理模式有

标签:vue,return,react,props,组件,redux,传值,属性
来源: https://www.cnblogs.com/welcometoxixi/p/16383175.html