>  기사  >  웹 프론트엔드  >  Pastate.js 반응형 반응 프레임워크 양식 렌더링 및 작업

Pastate.js 반응형 반응 프레임워크 양식 렌더링 및 작업

不言
不言원래의
2018-04-10 16:29:351559검색

이 글에서 공유한 내용은 Pastate.js 반응형 반응 프레임워크의 양식 렌더링 및 작동에 관한 것입니다. 이는 특정 참조 값을 가지고 있습니다. 필요한 친구는 이를 참조할 수 있습니다.

Pasate.js 반응형 반응 상태 관리입니다. 프레임워크 튜토리얼 시리즈의 네 번째 장입니다. 관심을 갖고 계속 업데이트해 주시기 바랍니다. Pastate.js Github

이번 장에서는 Pastate에서 폼 요소를 렌더링하고 조작하는 방법을 살펴보겠습니다.

기본 양식 요소 사용

BasicInfoView 구성 요소의 두 버튼 아래에 이름을 입력할 수 있는 입력 상자를 추가하고, 성별을 선택할 수 있는 확인란을 추가합니다. BasicInfoView 组件的两个按钮下面添加一个输入框用于输入姓名,并添加一个勾选框用于选择性别,更改如下:

class BasicInfoView extends PureComponent {
    render() {
        ...
        return (
            <p style={{ padding: 10, margin: 10 }}>
                ...
                <p>
                    <button onClick={this.decreaseAge}> decrease age </button>
                    <button onClick={this.increaseAge}> increase age </button>
                </p>
                <p>
                    name: <input type="text" value={state.name} onChange={this.handleNameChange}/> <br />
                    Is boy: <input type="checkbox" checked={state.isBoy == true} onChange={this.handleIsBoyChange}/>
                </p>
            </p>
        )
    }
}

上面添加两个了 input 标签,第一个 input 使用 name 数据, 第二个 input 使用 isBoy 数据。同时我们也先指定两个 input 的 onChange 处理函数。    
注意:如前面章节所提及,对于 imState 布尔值,请记得使用显式布尔值方式:checked={state.isBoy == true}

接下来看看如何实现两个 onChange 处理函数:

class BasicInfoView extends PureComponent {
    ...
    handleNameChange(e){
        state.basicInfo.name = e.target.value
        store.sync() // 编辑中的输入框,需手动同步store
    }
    handleIsBoyChange(e){
        state.basicInfo.isBoy = e.target.checked
    }
    ...
}

非常熟悉和简单!你只需把更新的值赋给目标state节点即可。我们会发现多了个 store.sync() ,这个函数是让 pastate 立刻执行数据同步更新。由于很多输入法会在输入过程中会把带下划线的 “拼音字母” 输入到 input 中,如下:

Pastate.js 반응형 반응 프레임워크 양식 렌더링 및 작업

如果 pastate 执行异步更新会使带下划线 “拼音字母” 中断,因此我们在更新 编辑中的输入框 时,需要简单地使用  store.sync() 执行同步更新,让 “拼音” 连续。如果不是对 编辑中的输入框  进行修改或不需要支持输入法输入(如密码等),无需使用 store.sync()

初步完成!我们试着往输入框输入文字,或点击勾选框, 可以看到文字区域的值与 input 区域的视图都正常地进行更新!

与普通 react 表单的处理模式一样,我们可以通过 onChange 函数的实时控制输入的内容,如转化大小写、控制字符串长度等:

class BasicInfoView extends PureComponent {
    ...
    // 把输入值都转化为大写
    handleNameChange_uppercase(e){
        state.basicInfo.name = e.target.value.toUpperCase()
        store.sync()
    }

    // 控制文本长度在10个字符以内
    handleNameChange_limitedLength(e){
        if(e.target.value.length > 10) return;
        state.basicInfo.name = e.target.value
        store.sync()
    }
    ...
}

使用 pastate 双向绑定输入组件

使用过 vue.js 或 angular.js 的人都体验过自动双向数据绑定 (two-ways data binding) 的便捷性,但由于 react state 渲染的单向数据流原则,在 react 中没有默认提供这个功能。而 pastate 的 imState 具有保存节点信息的特殊性,能够很容易实现自动双向数据绑定功能!

pastate 为你提供了四个已实现双向数据绑定的高阶表单组件 (Higher Order Component, 通常简称 HOC) ,这些组件都是基于 PureComponent 实现的,具有良好的渲染性能,你可以尽情享用他们!这四个表单组件如下:

  • Input : 文本框

  • Checkbox : 复选框

  • RadioGroup : 单选框选项组

  • Select

    import { ..., Input } from &#39;pastate&#39;
    ...
    render(){
        let state = this.props.state
        return(
            ...
            <Input value={state.text1} /> {/** 单行输入框,内部使用 <input type="text" /> 实现 */}
            <Input value={state.text2} type="textarea" /> {/** 多行输入框,内部使用 <textarea /> 实现 */}
            ...
        )
    }
    ...

    위에 두 개의 입력 태그가 추가되었습니다. 첫 번째 입력은 이름 데이터를 사용하고 두 번째 입력은 isBoy 데이터를 사용합니다. 동시에 두 입력의 onChange 핸들러 함수도 먼저 지정합니다.
    참고: 이전 장에서 언급한 것처럼 imState 부울 값의 경우 명시적인 부울 값 방법(checked={state.isBoy == true})을 사용해야 합니다.
두 가지 onChange 핸들러 함수를 구현하는 방법을 살펴보겠습니다.

...

handleTextBeforeChange(newValue, oldValue) {
    // 把输入的字符转化为大写
    return newValue.toUpperCase()
}

render(){
    let state = this.props.state
    return(
        ...
        <Input value={state.text1} beforeChange={this.handleTextBeforeChange} /> 
        ...
    )
}
...

매우 친숙하고 간단합니다! 업데이트된 값을 대상 상태 노드에 할당하기만 하면 됩니다. 추가 store.sync() 가 있음을 알 수 있습니다. 이 함수를 사용하면 데이터 동기화 업데이트를 즉시 수행할 수 있습니다. 많은 입력 방법이 입력 과정에서 입력에 밑줄이 그어진 "병음 문자"를 입력하기 때문에 다음과 같습니다:

Pastate.js 반응형 반응 프레임워크 양식 렌더링 및 작업

pasate가 비동기 업데이트를 수행하면 밑줄 친 "병음 문자"가 중단되므로입력 상자 편집을 업데이트 중입니다. , store.sync() 를 사용하여 동기 업데이트를 수행하여 "병음"을 연속적으로 만들기만 하면 됩니다. 편집 시 입력 상자를 수정하지 않거나 입력 방법 입력(예: 비밀번호 등)을 지원할 필요가 없는 경우에는 store.sync() . <p></p>첫번째 완료! 입력창에 텍스트를 입력해 보거나, 체크박스를 클릭하면 텍스트 영역의 값과 입력 영역의 뷰가 정상적으로 업데이트되는 것을 확인할 수 있습니다! <ul class=" list-paddingleft-2"><li>일반 반응 형식의 처리 모드와 동일하게 onChange 함수를 통해 대소문자 변환, 문자열 길이 제어 등 입력 내용을 실시간으로 제어할 수 있습니다. <table><pre class="brush:js;toolbar:false;">import { ..., Checkbox } from &amp;#39;pastate&amp;#39; ... render(){ let state = this.props.state return( ... I am a boy: &lt;Checkbox value={state.isBoy} /&gt; ... ) } ...</pre><tbody>paste를 사용하여 입력 구성 요소를 두 개로 바인딩합니다. 방향<tr class="firstRow"></tr>vue.js나 angle.js를 사용하는 사람들은 자동 양방향 데이터 바인딩(two-ways data Binding)의 편리함을 경험했지만, 반응 상태 렌더링의 단방향 데이터 흐름 원칙으로 인해 이 기능은 그렇지 않습니다. 반응에서 기본적으로 제공됩니다. 페이스트의 imState는 노드 정보를 저장한다는 특징을 가지고 있으며 자동 양방향 데이터 바인딩을 쉽게 구현할 수 있습니다! </tbody> </table>pastate는 양방향 데이터 바인딩을 구현한 4개의 Higher Order Form 컴포넌트(Higher Order Component, 일반적으로 HOC라고 함)를 제공합니다. 이러한 컴포넌트는 PureComponent를 기반으로 구현되며 좋은 렌더링 성능을 제공합니다. 당신이 좋아하는만큼! 네 가지 양식 구성 요소는 다음과 같습니다. 🎜🎜🎜🎜<code>Input : 텍스트 상자 🎜🎜🎜🎜Checkbox : 확인란 🎜🎜🎜🎜RadioGroup : 라디오 버튼 옵션 그룹🎜🎜🎜🎜선택 : 드롭다운 선택 상자🎜🎜🎜🎜입력 텍스트 상자🎜🎜입력 구성 요소를 사용하여 한 줄 입력 상자와 여러 줄 입력 상자를 표시할 수 있습니다. 바인딩할 값을 전달하기만 하면 됩니다. 인터페이스를 통해 입력 상자의 값을 변경하면 입력 구성 요소가 자동으로 바인딩 상태를 업데이트합니다. 🎜
import { ..., RadioGroup } from &#39;pastate&#39;
const goodNames = [&#39;Peter&#39;, &#39;Tom&#39;, &#39;Allen&#39;]

...
render(){
    let state = this.props.state
    return(
        ...
        Choose a name:  <RadioGroup options={goodNames} value={state.name}/>
        ...
    )
}
...
🎜입력 구성 요소의 속성과 설명은 다음과 같습니다. : 🎜🎜속성 | 값 설명🎜 🎜🎜🎜🎜🎜🎜🎜🎜

value | string | number , 必填 | 绑定的值,需要使用 this.props.state 中的节点 , 即 imState
type | "text" | "textarea" | "password" | "number" | 输入框类型,默认为 "text"
beforeChange | (newValue: string |  number, oldValue: string |  number) => string |  number | 在绑定值更新前会被调用,可用于实现自定义字符串更新逻辑, 如控制大小写或限制字符串长度等;返回值为最终要更新的值
afterChange | (newValue: string |  number) => void | 在绑定值更新后会被调用
disabled | boolean | 指定输入框是否处于禁止状态,默认为 false
className | string | 传递给输入框的 class 名 ( 用于指定 css 样式等 )
id | string | 传递给输入框的 id 名 ( 用于指定 css 样式等 )
useComposedValue | boolean |  [ 实验特性 ]  指定是否在输入法完成拼音过程时才更新 state 的模式,开启后,在输入拼音的过程中绑定的值不会更新,默认为 false

Input 组件实现了自动绑定数据双向绑定功能,如果你需要自定义字符串更新逻辑,或者在字符值更新后做一些操作,可以通过指定可选的 beforeChange 函数和 afterChange 函数来实现。

...

handleTextBeforeChange(newValue, oldValue) {
    // 把输入的字符转化为大写
    return newValue.toUpperCase()
}

render(){
    let state = this.props.state
    return(
        ...
        <Input value={state.text1} beforeChange={this.handleTextBeforeChange} /> 
        ...
    )
}
...

Input 组件的属性 useComposedValue 开启后,可以实现在输入法输入拼音的过程中绑定的值不会更新的功能,等拼音输入完成后 state 值才更新,减少拼音输入过程中不必要的 state 更新和视图渲染动作:

Pastate.js 반응형 반응 프레임워크 양식 렌더링 및 작업

useComposedValue 属性目前为实验特性,如果发现在某个浏览器或某种输入法中有问题,欢迎提交 issue 。

Checkbox 复选框

每个 Checkbox 是一个勾选框组件,只需传递要绑定的布尔值 state 节点,即可完成绑定:

import { ..., Checkbox } from &#39;pastate&#39;
...
render(){
    let state = this.props.state
    return(
        ...
        I am a boy: <Checkbox value={state.isBoy} />
        ...
    )
}
...

Pastate.js 반응형 반응 프레임워크 양식 렌더링 및 작업

Checkbox 组件的属性及其说明如下:

属性 | 值 | 说明

value | boolean,必填 | 绑定的数据值,可直接传入 this.props.state 中的节点值,无需state.xxx == true 转化。
afterChange | (newValue: boolean) => void | 在绑定值更新后会被调用
disabled | boolean | 指定禁止点击状态,默认为 false
className | string | 传递 class 名 ( 用于指定 css 样式等 )
id | string | 传递 id 名 ( 用于指定 css 样式等 )

RadioGroup 单选框选项组

RadioGroup 是一个单选框选项组,只要传入选项数组 options 常数和要绑定的选项值 value, 即可完成绑定:

import { ..., RadioGroup } from &#39;pastate&#39;
const goodNames = [&#39;Peter&#39;, &#39;Tom&#39;, &#39;Allen&#39;]

...
render(){
    let state = this.props.state
    return(
        ...
        Choose a name:  <RadioGroup options={goodNames} value={state.name}/>
        ...
    )
}
...

Pastate.js 반응형 반응 프레임워크 양식 렌더링 및 작업

RadioGroup 组件的属性及其说明如下:

属性 | 值 | 说明

options | Arrayb3642d4c1bbe188f2264a1d93e963eb8 | Arrayc20d85f48d46354c5561c6166559a7cc, 必填 | 选项数据数组
value | string | number | boolean,必填 | 绑定的选中值
disabled | boolean | 指定禁止选择状态,默认为 false
vertical | boolean | 指定选项为垂直排列状态,默认为 false
afterChange | (newValue: string | number | boolean) => void  | 在绑定值更新后会被调用
id | string | 传递给选项组根元素的 id
className |  string | 传递给选项组根元素的 className
radioClassName | string | 传递给圆形按钮的 className
tagClassName | string | 传递给选项标签的 className
disabledTagClassName | string | 传递给禁用状态的选项标签的附加的 className

options 属性接受两种格式的选项数据格式:

// 简单格式: Array<string> 
const nameOptions = [&#39;Peter&#39;, &#39;Tom&#39;, &#39;Allen&#39;]

// 完备格式: Array<{value: string, tag: string, disabled?: boolean}>
const nameOptionsChinese = [{
    value: &#39;Peter&#39;, // 数据值
    tag: &#39;彼得&#39;, // 选项标签值
    disabled: true // 可选地指定某个选项为不可选
},{
    value: &#39;Tom&#39;,
    tag: &#39;汤姆&#39;
},{
    value: &#39;Allen&#39;,
    tag: &#39;艾伦&#39;
}]

RadioGroup 是基于 PureComponent 实现的,对于 options 属性的值,建议定义一个 文件级 的选项数组常量, 这样可以提高渲染效率。如果把 options 值定义在 render 函数里或写成直接赋值的匿名对象(5196972e5a78b4540509c19f0f6fa6ba), 在每次父组件渲染时,无论绑定的 value 数据有没有更新,RadioGroup 获取到的 options 属性的引用值都不一样,会使 RadioGroup 进行多余的渲染动作。 当你使用其他基于 PureComponent 实现的组件时,在向其传递数组 / 对象类型的常量的时候也可以做这样的性能优化。

Select 下拉选择框

Select 是一个选择框组件,使用方法与 RadioGroup 类似,只要传入选项数组和要绑定的选择值即可完成绑定:

import { ..., Select } from &#39;pastate&#39;

const nameOptionsChinese = [{
    value: &#39;DEFAULT&#39;,
    tag: &#39;请选择&#39;,
    disabled: true
},{
    value: &#39;Peter&#39;,
    tag: &#39;彼得&#39;
}, {
    value: &#39;Tom&#39;,
    tag: &#39;汤姆&#39;
}, {
    value: &#39;Allen&#39;,
    tag: &#39;艾伦&#39;
}]

...
render(){
    let state = this.props.state
    return(
        ...
        Choose a name:  <Select options={nameOptionsChinese} value={state.name}/>
        ...
    )
}
...

Pastate.js 반응형 반응 프레임워크 양식 렌더링 및 작업

Pastate.js 반응형 반응 프레임워크 양식 렌더링 및 작업

Seclect 组件的属性及其说明如下:

属性 | 值 | 说明

options | Arrayc75eec7597418609098cc9cfad3bb2a5 | Arrayab7dfcd85a89b209aac5f66d4698aea9, 必填 | 选项数据数组
value | string  | number | boolean,必填 | 绑定的选中值
disabled | boolean | 指定禁止点击状态,默认为 false
afterChange | (newValue: string  | number | boolean) => void  | 在绑定值更新后会被调用
id | string | 传递的 id
className |  string | 传递的 className

如有需要显示没有选择的状态,可以多设置一个选项元素,通过元素的 tag 设置其提示文本, 并把元素的 disabled 设为 true 即可,没选中时的 value 值自行定义,不可为 null 或 undefined:

const nameOptionsChinese = [{
    value: &#39;DEFAULT&#39;,
    tag: &#39;请选择&#39;,
    disabled: true
}, ... ]

Seclect 组件目前仅支持最常用的单选功能,以后将支持多选功能。

pastate 表单组件的类型定义

Pastate 的高阶组件均是使用 Typescript 进行开发 , 提供完整的类型定义文件,当你在 javascript 项目使用它们时,也可以得到良好的组件属性 intelliSense 类型提示:

Pastate.js 반응형 반응 프레임워크 양식 렌더링 및 작업

你也可以右键点击组件名,选择转到类型定义, 查看组件的所有属性声明:

Pastate.js 반응형 반응 프레임워크 양식 렌더링 및 작업

Pastate.js 반응형 반응 프레임워크 양식 렌더링 및 작업

上图的 type 属性的类型是枚举字符串,在输入时,你可以在空双括号中按下 vsCode 的 “触发提示” 快捷键(具体快捷键因不同系统操作系统和不同设置而异,请到编辑器的 “首选项->设置快捷方式” 处查看,该功能很实用):

Pastate.js 반응형 반응 프레임워크 양식 렌더링 및 작업

对现有组件库进行双向数据绑定

很多时候,我们会使用 react 视图组件库来开发应用,如 ant.design、 material-ui 等,pastate 为这些现有的视图组件提供两个数据双向绑定方法!下面我们以 ant.design 的 Rate 星级评分组件为例进行介绍。

使用 Bind 高阶组件

你可以使用 pastate 提供的 Bind 组件去包围一个原始的视图组件,实现双向数据绑定。
我们先简单地安装 ant.design 组件库: $ npm install antd --save$ yarn add antd,引入 Rate 组件,并使用 Bind 组件进行包装,实现双向数据绑定:

import { ..., Bind } from &#39;pastate&#39;;

import Rate from &#39;antd/lib/rate&#39;;
import &#39;antd/lib/rate/style/css&#39;;
// 或经过简单配置后,使用 import { Rate } from &#39;antd&#39;, 详见 ant.design 文档
...

// 我们使用 state.basicInfo.age  数据进行演示

class BasicInfoView extends PureComponent {
    ...
    render() {
        /** @type {initState[&#39;basicInfo&#39;]} */
        let state = this.props.state;
        return (
            <p style={{ padding: 10, margin: 10 }}>
                ...
                <p>
                    年龄(Bind): 
                    <Bind value={state.age} > 
                        <Rate />
                    </Bind>
                </p>
                ...
            </p>
        )
    }
}

我们使用 Bind 组件对 Rate 组件进行包装,并把本来需要传递给 Rate 组件的 value 值传递通过 Bind 组件进行传递,这样就实现了双向数据绑定!如果我们要传递其他属性值给 Rate, 可以不通过 Bind 直接传递给 Rate,如下:

...
<Bind value={state.age} > 
    <Rate count={10} /> {/* 根据 ant design 文档, count 属性指定采用 n 级评分 */}
</Bind>
...

这样我们就实现了对 Rate 进行双向数据绑定:

Pastate.js 반응형 반응 프레임워크 양식 렌더링 및 작업

你可以通过点击 Rate 组件的星星或点击 descrease age ,increase age 按钮对年龄值进行改变,可以发现当通过按钮更新数据时,Rate 组件可以正确响应。而且 Bind 是一个关于 value 的纯组件,当其他无关数据发生改变时,Bind 元素不会发生多余的渲染动作。

Bind 元素还有两个可选的属性:

  • valueProp: 指定被包装的组件接收数据的属性名,默认是 value, 绝大多数组件也是用 value,因此无需指定该值。如果被包装的组件使用的是 checked 或其他属性名接收数据值,那么请把 Bind 元素的 valueProp 设为对应的 checked 或其他属性名。

  • afterChange: 当组件绑定的值通过该组件发生改变后,会调用该函数,该函数的签名为 (newValue) => void。当绑定的属性值不是通过该组件发生改变时,afterChange 函数不会被调用。

使用 makeBindable 函数

你也可以使用 makeBindable(RawComponent, valueProp = 'value') 函数生成一个可以复用的可绑定组件

import { ..., makeBindable } from &#39;pastate&#39;;
...

// 使用 makeBindable 生成对应的可以绑定数据的 Rate 组件
const MyRate = makeBindable(Rate)

class BasicInfoView extends PureComponent {
    ...
    render() {
        /** @type {initState[&#39;basicInfo&#39;]} */
        let state = this.props.state;
        return (
            <p style={{ padding: 10, margin: 10 }}>
                ...
                <p>
                    年龄(makeBindable): 
                    <MyRate count={10} value={state.age}/> 
                </p>
                ...
            </p>
        )
    }
}

你可以通过  makeBindable 函数的第二个参数指定 valueProp 值,如 const MyCheckbox = makeBindable(Checkbox, 'checked'), 同样,你可以通过新组件的 afterChange 属性去响应组件值更新后的个性化操作。

对于绑定的值为空的情况

无论使用 pastate 的表单输入组件还是包装现有的组件库,对于组件绑定的数据值,不支持被设为 null 值 或 undefind 值。通常情况下,我们不会有这种需求。如果需要实现表单的“未选择”状态, 我们一般通过设置一个默认值且不可选的 default 值来代替。例如有个表单需要选择性别,并且需要一个未选择的状态,这样使用一个 RadioGroup 组件来实现:

let initState = {
  sex: &#39;&#39; // 用字符串表示性别,并设置为选择状态是的值为空字符串 &#39;&#39; 或 &#39;default&#39;
}
const sexOptions = [&#39;boy&#39;, &#39;girl&#39;] // 只包含目标值
...
render(){
  let state = this.props.state;
  return <RadioGroup options={sexOptions} value={state.sex} />
}
...

如果你的需求场景一定要用到 null 或 undefined 值,欢迎在 issues 中分享。 Pastate 能实现绑定的值支持空值,但如果这个需求只有在非常特殊的情况下才用到,我们就暂不把它默认实现在 pastate 库中,因为这会增加计算量,你可以自行实现这个特殊组件的数据绑定逻辑。

下一章,我们来看看 pastate 应用如何进行模块化。

相关推荐:

Pastate.js 响应式框架之数组渲染与操作

Pastate.js 响应式框架之多组件应用

Pastate.js 之响应式 react state 管理框架

위 내용은 Pastate.js 반응형 반응 프레임워크 양식 렌더링 및 작업의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.