本篇介绍一个无论是React还是Vue都是核心中的核心功能,组件。我们可以将单页面应用理解为一个页面中的无数组件拼接组成的,所以组件才是重中之重。
一、React组件
React组件分类两种,一是函数组件(无状态组件),二是类组件(状态组件)。这两种除了名字不一样外,最重要的还是两个字,状态。下面我们来详细的介绍一下这两种组件。
1.函数组件 (无状态组件)
import React from 'react'
export default function ComFun() {
return (
<div>函数组件</div>
)
}
这就是函数组件的最基础结构,也是我们在此之前举例的组件结构,他是无状态的,状态即数据,只能用户静态展示,如果有需要交互的功能则不能使用函数组件。函数组件是不能使用setState的,也不能使用state初始化数据,同时也没有生命周期。如果需要state则需要提升至父组件通过父子组件传值进行传递。
2.类组件(状态组件)
import React, { Component } from 'react'
export default class ComClass extends Component {
constructor() {
super()
this.state = {
// 数据
}
}
render() {
return (
<div>类组件</div>
)
}
}
我们可以看到,在类组件的构造函数constructor中可以通过this.state来初始化数据,这就是我们刚才说的状态组件特有的。这两种组件往往在开发过程中配合使用。
二、React组件间传值
1.函数父子组件传值
(1)父组件向子组件传值
将子组件引入父组件后,父组件只需在子组件上添加对应的属性和值即可,在Child1上添加了属性name,值为Tom。
// React/App
import React from 'react'
import Child1 from './views/Child/Child1'
export default function App() {
const parentStyle = {
background: '#bbb',
padding: '10px'
}
return (
<div style={parentStyle}>
React-App
我是父组件
<Child1 name='Tom'></Child1>
</div>
)
}
在子组件函数中需要形参props,在JSX结构中通过props.属性值,即可拿到所传递的数据。
// React/Child1
import React from 'react'
export default function Child1(props) {
const childStyle = {
background: '#666',
padding: '10px',
color: '#fff',
marginTop: '10px'
}
return (
<div style={childStyle}>
<p>我是子组件Child1</p>
<p>我是从父组件传递过来的数据:{props.name}</p>
</div>
)
}
效果
(2)子组件向父组件传值
子组件需要通过一个事件来触发向父组件传值,将需要传递的数据作为参数进行传递。
// React/Child1
import React from 'react'
export default function Child1(props) {
const childStyle = {
background: '#666',
padding: '10px',
color: '#fff',
marginTop: '10px'
}
const { getMessage } = props
const msg = '我是子组件数据'
return (
<div style={childStyle}>
<p onClick={() => getMessage(msg)}>我是子组件Child1,点击我可向父组件传值</p>
</div>
)
}
需要注意的是,子组件的getMessage函数需要跟父组件引入的子组件的属性getMessage一致
// React/App
import React from 'react'
import Child1 from './views/Child/Child1'
export default function App() {
const parentStyle = {
background: '#bbb',
padding: '10px'
}
const getData = (data) => {
console.log(data)
}
return (
<div style={parentStyle}>
React-App
我是父组件
<Child1 getMessage={getData}></Child1>
</div>
)
}
这样我们就拿到了子组件中定义的数据,效果
2.类组件父子组件传值
(1)父组件向子组件传值
类组件父传子与函数组件完全一致
// React/App
import React from 'react'
import Child2 from './views/Child/Child2'
export default function App() {
const parentStyle = {
background: '#bbb',
padding: '10px'
}
return (
<div style={parentStyle}>
React-App
我是父组件
<Child2 name='Jerry'></Child2>
</div>
)
}
接收上与函数组件是有不同的,类组件是一个有状态的组件,可以使用this。所以在接收的时候在构造函数和super中需要参数props,使用的时候也从直接props变为了this.props.属性
import React, { Component } from 'react'
export default class Child2 extends Component {
constructor(props) {
super(props)
this.state = {
childStyle: {
background: '#666',
padding: '10px',
color: '#fff',
marginTop: '10px'
}
}
}
render() {
return (
<div style={this.state.childStyle}>
<p>我是子组件</p>
<p>父组件传过来的数据是:{this.props.name}</p>
</div>
)
}
}
效果
(2)子组件向父组件传值
与函数子组件向父组件传递数据的思路是一样的,都是通过事件来触发,将子组件数据传递出去
// React/Child2
import React, { Component } from 'react'
export default class Child2 extends Component {
constructor(props) {
super(props)
this.state = {
childStyle: {
background: '#666',
padding: '10px',
color: '#fff',
marginTop: '10px'
}
}
}
getMessage = () => {
this.props.getMessage('我是来自子组件的数据')
}
render() {
return (
<div style={this.state.childStyle}>
<p onClick={this.getMessage}>我是子组件,点击我给父组件传值</p>
</div>
)
}
}
// React/App
import React from 'react'
import Child2 from './views/Child/Child2'
export default function App() {
const parentStyle = {
background: '#bbb',
padding: '10px'
}
const getData = (data) => {
console.log(data)
}
return (
<div style={parentStyle}>
React-App
我是父组件
<Child2 name='Jerry' getMessage={getData}></Child2>
</div>
)
}
效果
三、Vue组件
<template>
<div>Child</div>
</template>
<script>
export default{
data(){
return {
}
}
}
</script>
<style>
</style>
Vue只有一种组件,就是我们在此之前一直用的,并没有分有状态和无状态
四、Vue组件间传值
1.父组件向子组件传值
与React相同,父传子也是在子元素上设置对应属性即可
<template>
<div id="app">
Vue-App
<child name="Tom"></child>
</div>
</template>
<script>
import child from './views/components/child.vue'
export default {
name: 'App',
components:{
child
},
data() {
return {
}
},
methods: {
}
}
</script>
<style>
</style>
不同的是,子组件需要使用props对象接收,在props需要设置属性值作为key,同时可以设置类型和默认值等。在使用的时候则不需要this.props.属性,直接使用this.属性即可
<template>
<div>
<p>我是子组件</p>
<p>我是父组件传过来的数据:{{this.name}}</p>
</div>
</template>
<script>
export default{
props:{
name:{
type:String,
default:''
}
},
data(){
return {
}
}
}
</script>
<style>
</style>
效果
2.子组件向父组件传值
与React一样,同样需要通过事件触发传递,但是不同的是,Vue需要利用$emit函数才能完成,$emit第一个参数是父组件绑定的关键词,第二个参数是数据
<template>
<div>
<p @click="sendMessage">我是子组件,点击向父组件传值</p>
</div>
</template>
<script>
export default{
data(){
return {
}
},
methods:{
sendMessage(){
this.$emit('getData','我是子组件中的数据')
}
}
}
</script>
<style>
</style>
接收方式与React还是神似的,通过设置的关键字触发特定方法,拿到data的值
<template>
<div id="app">
Vue-App
<child name="Tom" @getData='getSonData'></child>
</div>
</template>
<script>
import child from './views/components/child.vue'
export default {
name: 'App',
components: {
child
},
data() {
return {
}
},
methods: {
getSonData(data) {
console.log(data)
}
}
}
</script>
<style>
</style>
效果
五、总结
好了,我们已经会使用这两大框架组件的基本用法,以及组件之间常用的通信方法。到此为止我们已经可以编写一些具有样式及结构的页面了,下一章将会为大家介绍量大框架的事件,让我们的页面能够与用户进行交互。