獲取form表單_【第1535期】前端 Form 的表單的一個通用解決方案

前言

今日早讀文章由阿里@布達投稿分享。

@布達,Alibaba Fusion項目組的。花名潕量。主要專注在設計系統、組件、可視化搭建這個領域

正文從這開始~~

Fusion Next - Form 表單解決方案

前端的Form 表單主要用于解決數據獲取、數據校驗、數據賦值 這三大類問題。這篇文章里面的提供的解決方案能夠比較完美的用在 React 框架上,但是解決問題的思路相信應該是可以使用于任何框架語言。

中后臺的表單組件已經不僅僅有 input 和 select,可能還擴展到 范圍選擇器、日期選擇器 等,這些組件往往為了實現更優雅的UI和更使用的交互會在原生的組件上面做多層封裝,而經過多層疊加后可能已經看不到原生表單元素的影子了。比如經過封裝下面這段 DOM 結構經過樣式修改也可能成為一個輸入組件,雖然完全看不到 input 的影子

 contentEditable>

所以為了便于大家理解我這里從傳統的原生 form 說起,好讓大家有一個遞進的過程。

引子:原生 form 表單

最初始的一份代碼如下,代碼很簡單,看著也很舒服。

 action="/api/post" method="post">
?username: name="username" />
?password: name="password" /> type="submit">submit

但是你開始做數據校驗相關,表單就立刻變得復雜多了。如下:代碼增多了一倍。

function checkname(target) {const value = target.value;if (value.length < 10) {
? ? ?document.getElementById('username_msg').innerHTML = '長度必須>10'} else {
? ? ?document.getElementById('username_msg').innerHTML = ''}}function checkpassword(target) {const value = target.value;if (!value.match(/^[\w]{6,16}$/)) {
? ? ?document.getElementById('password_msg').innerHTML = '密碼必須 6-16 位字母數字'} else {
? ? ?document.getElementById('password_msg').innerHTML = ''}}function getInitData() {
? ?ajax({
? ? ?url:'/api/data',
? ? ?success:function(data) {
? ? ? ?document.getElementById('username') = data.username;});}
?getInitData(); action="/api/post" method="post">
username: name="username" onchange="checkname(this)"/> id="username_msg">
passowrd: name="password" onchange="checkpassword(this)"/> id="password_msg"> type="submit">submit

如果把DOM的部分也用JS來實現,基本可以做到只修改JS不需要再動DOM結構,但是也讓JS的復雜度增高不少。

React 里面所有的DOM結構都是自己通過JS 生成的,JSX也可以方便的實現DOM結構。但這里我拿原生表單舉例,只是想說用 React 寫出來的原生表單,并不比用原生 JS 的優雅多少!!!

React 中的原生 form 表單

同樣一段最簡單的功能,套在 react 框架下面是這個樣子。

class Demo extends React.Component {
?render() {return <form action="/api/post" method="post">
? ? ?username: <input name="username" />
? ? ?passowrd: <input name="password" /><button type="submit">submitbutton>form>}}

比如同樣想要實現校驗輸入自動校驗 和 賦值,看下面一段代碼,想想就是一大堆事情要做。

class Demo extends React.Component {
?state = {
? ?username: '',
? ?password: '',
? ?usernameMsg: '',
? ?passwordMsg: '',};
?checkname = e => {// 獲取數據const value = e.target.value;// 受控模式賦值this.setState({
? ? ?username: value,});// 校驗數據if (value.length < 10) {this.setState({
? ? ? ?usernameMsg: '長度必須>10',});} else {this.setState({
? ? ? ?usernameMsg: '',});}};
?checkpassword = e => {// 獲取數據const value = e.target.value;// 受控模式賦值this.setState({
? ? ?password: value,});// 校驗數據if (!value.match(/^[\w]{6,16}$/)) {this.setState({
? ? ? ?passwordMsg: '密碼必須 6-16 位字母數字',});} else {this.setState({
? ? ? ?passwordMsg: '',});}};
?handleSubmit = () => {
? ?ajax({
? ? ?url: '/api/post',
? ? ?data: {
? ? ? ?username: this.state.username,
? ? ? ?password: this.state.password,},
? ? ?success: () => { // success},});};
?render() {// 獲取數據和錯誤信息const { username, password, usernameMsg, passwordMsg } = this.state;return (<form action="/api/post" method="post">
? ? ? ?username: <input value={username} onChange={this.checkname} />{usernameMsg}span>
? ? ? ?passowrd: <input value={password} onChange={this.checkpassword} />{passwordMsg}span><button type="submit" onClick={this.handleSubmit}>
? ? ? ? ?submit ? ? ? ?button>form>);}}

代碼有點長,大家大致看一眼干什么的就行,從上面一系列代碼中基本可以總結出一個現象,要想實現表單數據獲取、校驗,基本離不開 onChange 這個方法,而且是有幾個表單控件,就要寫幾個 onChange 。(以上代碼可直接運行,可以在?https://codepen.io/frankqian/pen/XOROBw?editors=0010?調試)

其實這里和框架并沒有什么關系,因為不管用什么框架要想做到 賦值和校驗 這兩個功能,基本一定要在 input 上面綁定 onChange。 所以如果有個通用的工具可以自動幫你把這些onChange的綁定都做了,再把校驗規則固定下,是不是所有的表單問題都可以解決了呢?是的通用表單解決方案就是按照這種思路設計出來的!

適用于所有 React 表單組件的解決方案

所有的用 React 寫成的組件都可以使用該方案。甚至 非 React 體系也可以使用改思路來解決問題。

基于所有表單控件都需要綁定 onChange 做數據獲取和校驗的原則,所以我設計了一個 Field 工具。這個工具原理很簡單,就是可以自動幫你綁定 value + onChange 解決上面一長串代碼的問題。

const field = new Field(this);
field.init('username');

field.init 會自動返回 value + onChange ,內容如下:

{
?value: "",
?onChange: ? ()}

下面這張圖簡單表面 Field 和 React 體系之間的關系。

dbfbe0e106a84ceaeb0466531e1dec47.png
1. 使用 Field 獲取數據
import {Field} from '@alifd/next';class Demo extends React.Component {
?field = new Field(this);
?handleSubmit = () => {
? ?console.log(this.field.getValues()); // 獲取數據}
?render() {const {init} = this.field;return
? ? ?username: <input {...init('username')} />
? ? ?passowrd: <input {...init('password')} /><button onClick={this.handleSubmit} >submitbutton>form>}}

這樣一個表單的數據獲取問題就解決了,代碼簡潔了很多。 Demo 在這里?https://codepen.io/frankqian/pen/xMdoxZ?editors=0010?可以自己調試

2. 表單校驗

既然能夠獲取到數據了,那邊表單校驗是順手的事情,因為校驗只依賴數據。我們只需要對集中固定的交互性形式和校驗規則做抽象就好了。

交互形式上大概包含以下三類

  • 輸入的時候實時校驗,一般 onChange 觸發

  • 離開焦點的時候校驗,一般 onBlur 觸發

  • 通過自定義的操作來觸發校驗,自己調用 api 觸發

常見的校驗規則抽象
規則名稱描述類型觸發條件/數據類型
required不能為空Booleanundefined/null/“”/[]
pattern校驗正則表達式正則
minLength字符串最小長度 / 數組最小個數NumberString/Number/Array
maxLength字符串最大長度 / 數組最大個數NumberString/Number/Array
length字符串精確長度 / 數組精確個數NumberString/Number/Array
min最小值NumberString/Number
max最大值 / 數組精確個數NumberString/Number
format對常用 pattern 的總結url/email/tel/numberString
validator自定義校驗Function

這里說明下表單是弱類型的數據。比如 input 框里面你希望用戶輸入的是整數,返回的 value 類型可能有兩種

  • “123456”, String 類型的整數校驗方式為 :/\d+/

  • 123456, Number 類型的整數校驗方式為: typeof Value === ‘number’

這個時候要求用戶一定要返回 Number 類型才能校驗非常不友好,所以在 Field 校驗邏輯里面就把類型的問題處理掉了,而不是交給用戶去判斷。

上面是小插曲,我們繼續看如下 Field + 表單的代碼,解決了數據獲取、表單校驗的所有功能。

import { Field } from '@alifd/next';class Demo extends React.Component {
?field = new Field(this);
?handleSubmit = (e) => {
? ?e.preventDefault();this.field.validate(); // 自定義校驗
? ?console.log(this.field.getValues()); // 獲取數據}
?render() {const {init, getError} = this.field;return
? ? ?username: <input {...init('username', {rules: { required: true, minLength: 10}})} /><span style={{color: 'red'}}>{getError('username')}</span> ?{/**錯誤信息**/}
? ? ?passowrd: <input {...init('password', {rules: {
? ? ? ? ?pattern: /^[\w]{6,16}$/,
? ? ? ? ?message: '密碼必須 6-16 位字母數字'}})} /><span style={{color: 'red'}}>{getError('password')}</span> ?{/**錯誤信息**/}<button onClick={this.handleSubmit} >validatebutton>form>}}

這樣之前可能需要 70 行的代碼 24 行就可以解決了,可以讓代碼清晰不少。調試demo見:?https://codepen.io/frankqian/pen/vbZmXE?editors=0010

94600d5deae519f69e4fa8311a7124ee.png
3. 寫自定義的事件

既然 init 會自動返回 onChange,那么如果我希望自己在 onChange 里面加一些邏輯改怎么處理呢。

如果直接寫 onChange 會被 init 覆蓋掉,不管寫前面還是后面總有一個onChange會被覆蓋掉

 onChange={(value) => console.log(value)}
?{...init('username')} />

所以在 init 提供了 props 可以把組件原生的 props 透傳進去,Field內部會做好 hook 邏輯處理。

 {...init('username', {props: {onChange:(value) => console.log(value)}
})} />

大家用起來覺得很麻煩,后面會再介紹如果在 Form 層面設計的更加趨向于原生方法的使用

4. 自己寫的表單組件怎么用

現在很多React 組件是在原生組件之上又做了封裝,還有很多組件可能并沒有包裹表單元素(比如 Fusion Select 里面并沒有 select 元素,下拉框是自己做的 )。但是只要你自己寫的組件也遵循表單的規則就可以使用該方案。

4.1 基本: value + onChange 受控規則

這個規則其實來自原生 html 的組件,我們自己寫的組件只要按照標準來都可以使用 Field。

184d9d46e022a6aa9b23e36c9a65c54e.png

自己寫的組件比起原生的表單組件會更加美觀,交互更友好。只要遵循規范都能在 field 里面使用,詳細demo 見?https://codepen.io/frankqian/pen/gqRWJx?editors=0010這個規則其實來自原生?html 的組件,我們自己寫的組件只要按照標準來都可以使用 Field。

4.2 高級功能:滿足更加人性化的需求

還有一些其他更加細粒度的規則,是為了讓你的組件更加好的適配高級功能,比如:

一鍵 reset 清空所有數據。因為每個組件的接收數據類型不一樣,所以統一為在 willReceiveProps 里面接收 value=undefined

componentWillReceiveProps(nextProps) {if ('value' in nextProps ) {this.setState({
? ? ? ? ? value: nextProps.value === undefined? []: nextProps.value ? // ?設置組件的被清空后的數值})}}

一次交互操作只拋一次 onChange

比如 upload 上傳,如果一次上傳觸發上百次 onChange,那么整個頁面會跟著一起 Render 幾百次,非常影響性能

9030697bde1b6c962533aef997515038.png
Upload 上傳完成才是用戶想要的結果

比如 Slider, 在拖動的時候如果實時觸發 onChange,那么在拖動滑塊的時候可能會非常卡頓。所以鼠標松開的那個瞬間觸發才是比較合理的操作,其他的拖拽事件可以交給 onProgress

82a5568bb89a99982b0e2dbdcecb892b.png
Slider 的拖動釋放的那一刻可能才是用戶想要的數據

Fusion Next 的表單組件基本都已經是按照這套規范標準實現了,詳細可以查看這里的文檔?https://fusion.design/component/field?拉到最下面

Form 組件讓體驗持續升級

上面知道了 Field 可以解決校驗、獲取、賦值等數據方面的問題,但是并不能解決 UI 和 交互的問題,在布局和錯誤展示的時候需要自己來控制。

常用場景抽象讓布局更輕松

場景的布局有水平 inline 布局、垂直的分欄布局,通過 FormItem 的 api 可以非常輕松的做到。

垂直布局

 label="Username:"> name="first" ?placeholder="first"/> name="second" placeholder="second"/> label="Password:" required> htmlType="password" name="pass" placeholder="Please enter your password!"/> label=" ">Submit
e5911a84553a5ef8a4f3e52942c48938.png
垂直布局

水平布局

 inline>...
7da35389ab0d2cccf6fb8467306109be.png
水平布局

標簽內置

 labelAligin="inset">...
e029f02d19c54f8801a4ea3a828f1223.png
標簽內嵌
  1. 輔助錯誤展示

出錯的時候自動展示錯誤信息,不需要自己 getError 判斷。 每種狀態怎么展現由各自的組件自己實現。減少和Form的耦合

77295a1396ec9a508444811ecad5ed67.png

每個組件的加載中、成功、失敗,都由組件自己實現,Form 只是在校驗的時候傳遞 state 給各個組件,這樣不需要 Form 去關心每個組件應該展現為什么樣!

 state="error" /> ?// 錯誤狀態 state="loading" /> // 加載中 state="success" /> // 成功 state="error" /> // 錯誤狀態

進一步優化 Form 讓使用更簡單

以上我們還是 Field + Form 配合來使用的,代碼基本是這個樣子。

import { Form, Input, Field, Button } from '@alifd/next';const FormItem = Form.Item;class Demo extends React.Component {
?field = new Field(this);
?handleSubmit = () => {this.field.validate();}
?render() {const {init} = this.field;return ?<Form field={this.field}><FormItem label="Username:"><Input {...init('username', {
? ? ? ? ? ? ?rules: {required}})} />FormItem><FormItem label="Password:"><Input {...init('password', {
? ? ? ? ? ? ?rules: {pattern:/[\w]{6,16}/}})} htmlType="password" />FormItem><FormItem label=" "><Button onClick={this.handleSubmit} >SubmitButton>FormItem>Form>}}

可能寫多了之后就會想,每個組件都要使用 init 、都需要寫 rules 規則,而且在 jsx 中寫一大串的 JSON 數據。

是否有方法讓數據獲取和校驗變得更簡單,讓代碼再進一步的簡化呢?

進一步集成 Field 能力而弱化用法

針對以上問題對 Form 進一步優化,把 Field 的能力整合進了 Form,而把 Field 的用法進一步弱化,讓大家不需要再關心 init/取數據 等問題。代碼如下:

import { Form, Input, Button } from '@alifd/next';const FormItem = Form.Item;class Demo extends React.Component {
?handleSubmit = (values, errors) => {if (errors) {// 校驗出錯 return;}
? ?console.log(values) // 獲取數據}
?render() {return ?<Form><FormItem label="Username:" required><Input name"username" />FormItem><FormItem label="Password:" pattern={/[\w]{6,16}/}><Input name="password" htmlType="password" />FormItem><FormItem label=" "><Form.Submit validate onClick={this.handleSubmit} >SubmitForm.Submit>FormItem>Form>}}

上面代碼中可以看出幾個優化點:

  • 不需要關注 Field 用法,改成 Form API 的方式。用法簡單直接不少

  • 通過 name 來進行數據初始化,也更加接近原生 form 的用法,大家更容易理解。

  • 校驗功能 API 化,代碼更加簡潔,可讀性增強

后記

Form 的優化一定不會僅僅止于此,因為在實際業務中會遇到更加復雜的功能。

很多業務為了更加方便快捷,會抽象常用的組件布局,通過后端接口吐出JSON schema的方式直接在前端動態展示表單,雖然比較業務化當時確實方便快捷,能夠極大的解決效率問題;

又或者把常用的表單類場景做成業務組件、模塊模板,在使用的時候直接下載使用。比如:Fusion的表單類模塊:https://fusion.design/module?category=表單

方案很多,總有適合自己的一套。

相關鏈接

  • field 組件 demo: https://fusion.design/component/field

  • form 組件 demo: https://fusion.design/component/form

  • Fusion Next 組件倉庫: https://github.com/alibaba-fusion/next

關于本文
作者:@布達
原文:https://www.yuque.com/docs/share/8238bd4e-cfb2-42de-afa7-bc2b2f2ab0dc

e2e64abc9c5c86d7d926f7afaa5fc02e.png

最后,為你推薦

【第998期】JSON schema與表單驗證

【第937期】探索兩種優雅的表單驗證——策略設計模式和ES6的Proxy代理模式

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/530630.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/530630.shtml
英文地址,請注明出處:http://en.pswp.cn/news/530630.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

c語言表白用代碼(1)

不多說&#xff0c;直接上代碼&#xff0c;有用拿走&#xff0c;侵權立刪。 希望大家盡早找到自己的另一半。 #include <stdio.h> #include <math.h> #include <stdlib.h> #define I 20 #define R 340 #include <string.h> int main() {char answer[4…

react取消捕獲_React學習筆記(三)

React學習筆記&#xff08;三&#xff09;&#xff0c;組件的生命周期React中組件也有生命周期&#xff0c;也就是說也有很多鉤子函數供我們使用, 組件的生命周期&#xff0c;我們會分為四個階段&#xff0c;初始化、運行中、銷毀、錯誤處理(16.3之后)初始化在組件初始化階段會…

zzulioj1111: 多個整數的逆序輸出(函數專題)

1111: 多個整數的逆序輸出&#xff08;函數專題&#xff09;時間限制: 1 Sec 內存限制: 128 MB 提交: 3521 解決: 2617 [提交] [狀態] [討論版] [命題人:admin] 題目描述 輸入n和n個整數&#xff0c;以與輸入順序相反的順序輸出這n個整數。要求不使用數組&#xff0c;而使用遞歸…

快捷鍵_AutoCAD 2021中的默認快捷鍵、新建或編輯快捷鍵

文&#xff1a;CAD鐘日銘。歡迎關注和點贊支持。在使用AutoCAD進行制圖的過程中&#xff0c;掌握一些快捷鍵會提高操作效率。所謂的快捷鍵是指用于啟動命令的鍵組合。例如&#xff0c;按CtrlN組合鍵(快捷鍵)新建圖形文件&#xff0c;按 CtrlO組合鍵可打開圖形文件&#xff0c;按…

1112: 進制轉換(函數專題)

1112: 進制轉換&#xff08;函數專題&#xff09; 時間限制: 1 Sec 內存限制: 128 MB 提交: 3448 解決: 2599 [提交] [狀態] [討論版] [命題人:admin] 題目描述 輸入一個十進制整數n&#xff0c;輸出對應的二進制整數。常用的轉換方法為“除2取余&#xff0c;倒序排列”。將一個…

出現畫面抖動_連續抖動20小時!虎門大橋橋面如波浪翻滾,專家:個人感覺沒問題...

前兩天(5月5日)&#xff0c;虎門大橋橋面出現如波浪翻滾的起伏&#xff0c;引發廣泛的關注&#xff1a;次日&#xff0c;廣東交通集團通報&#xff0c;虎門大橋震動是渦振現象&#xff0c;懸索橋結構安全。專家初步判斷此次渦振和橋上設置水馬有關。但直到6日早上11時&#xff…

1098: 復合函數求值(函數專題)

1098: 復合函數求值&#xff08;函數專題&#xff09; 時間限制: 1 Sec 內存限制: 128 MB 提交: 5545 解決: 4335 [提交] [狀態] [討論版] [命題人:admin] 題目描述 求復合函數F(G(x))&#xff0c;其中函數F(x)|x-3||x1|&#xff0c;函數G(x)x^2-3x。要求編寫函數funF()和funG(…

安全模式 提權_記一次滲透挖洞提權實戰

摘要&#xff1a;這是一次挖掘cms通用漏洞時發現的網站&#xff0c;技術含量雖然不是很高&#xff0c;但是也拿出來和大家分享一下吧&#xff0c;希望能給一部分人帶來收獲。0x01 進入后臺在通過googlehack語法挖掘beescms時發現了這個站點利用網上的payload&#xff0c;在/mx_…

win7無法連接打印機拒絕訪問_“Windows無法連接打印機,操作失敗,錯誤為0x000003e3”...

請求大家幫助&#xff0c;昨天在共享打印機時出現“Windows無法連接打印機&#xff0c;操作失敗&#xff0c;錯誤為0x000003e3”。在百度百科查詢的資料修改了都不行(在不重裝系統前提下&#xff0c;聯想臺式機都是win732位系統)&#xff0c;給大家一一列舉&#xff0c;請求廣大…

1108: 打印數字圖形(函數專題)

1108: 打印數字圖形&#xff08;函數專題&#xff09; 時間限制: 1 Sec 內存限制: 128 MB 提交: 4040 解決: 2786 [提交] [狀態] [討論版] [命題人:admin] 題目描述 從鍵盤輸入一個整數n(1≤n≤9),打印出指定的數字圖形。要求在程序中定義并調用如下函數&#xff1a;PrintSpace…

類型全部為string_python小講堂丨學了這么久的,這6種基本數據類型你真的理解了嗎...

哈嘍&#xff0c;大家好&#xff0c;歡迎來到python小講堂&#xff0c;間歇性的努力&#xff0c;會導致持續性的一事無成&#xff0c;即使今天是除夕&#xff0c;我們也不能懈怠啊&#xff0c;今天我給大家帶來的是關于python的6種基本數據類型的深入講解&#xff0c;話不多說讓…

1105: 判斷友好數對(函數專題)

1105: 判斷友好數對&#xff08;函數專題&#xff09; 時間限制: 1 Sec 內存限制: 128 MB 提交: 5790 解決: 2629 [提交] [狀態] [討論版] [命題人:admin] 題目描述 輸入兩個正整數m和n&#xff0c;順序輸出m到n之間的所有友好數對。 如果兩個整數的所有正因子之和&#xff08;…

防抖 節流_【前端面試】節流與防抖

我們用兩張圖表示什么是節流和防抖。防抖節流由圖可見&#xff0c;防抖的意思是&#xff0c;當用戶在一段時間內連續頻繁的試圖執行一個函數的時候&#xff0c;只有最后一次&#xff0c;函數被真正的執行。節流的意思是&#xff0c;當用戶在某一個時刻執行了一次函數的時候&…

沒數據時y軸不顯示_Matplotlib數據可視化

1.Matplotlib介紹什么是MatplotlibMatplotlib是一個Python的繪圖庫&#xff0c;它可與 NumPy 一起使用&#xff0c;可以代替MMatplotlib安裝由于Matplotlib是第三方庫&#xff0c;所以我們需要安裝它才可以使用。注意&#xff0c;Matplotlib3.0要求python3版本才可安裝使用。安…

1099: 角谷猜想(多實例測試)

1099: 角谷猜想&#xff08;多實例測試&#xff09; 時間限制: 1 Sec 內存限制: 128 MB 提交: 5930 解決: 3888 [提交] [狀態] [討論版] [命題人:admin] 題目描述 任何一個自然數&#xff0c;如果是偶數&#xff0c;就除以2&#xff0c;如果是奇數&#xff0c;就乘以3再加1。最…

python軟件運行界面_python運行界面 python的圖形用戶界面怎么運行

為什么用Python開發界面應用程序1)wxWidgets是一個比MFC優雅的庫&#xff0c;TortoiseCVS用wxWidges而不用MFC&#xff0c;就是因為wxWidgets好用&#xff0c;而不是為了可以移植。 2)Python的面向對象腳本語言編程適合快速界面開發 3)Python在服務器端和客戶端都非常有前途&am…

1100: 求組合數(函數專題)

1100: 求組合數&#xff08;函數專題&#xff09; 時間限制: 1 Sec 內存限制: 128 MB 提交: 6264 解決: 4653 [提交] [狀態] [討論版] [命題人:admin] 題目描述 馬上要舉辦新生程序設計競賽了&#xff0c;與以往不同的是&#xff0c;本次比賽以班為單位&#xff0c;為了全面衡量…

python畫圖隱藏畫筆_python畫圖

轉至&#xff1a;https://blog.csdn.net/weixin_43943977/article/details/1026913921、灰色櫻花樹from turtle import *from random import *from math import *def tree(n,l):pd()#下筆#陰影效果t cos(radians(heading()45))/80.25pencolor(t,t,t)pensize(n/3)forward(l)#畫…

1101: 逆序數字(函數專題)

1101: 逆序數字&#xff08;函數專題&#xff09; 時間限制: 1 Sec 內存限制: 128 MB 提交: 6333 解決: 4717 [提交] [狀態] [討論版] [命題人:admin] 題目描述 輸入一個正整數n&#xff0c;計算n的逆序數m&#xff0c;輸出m與n的和。要求程序定義一個inverse()函數和一個main(…

循環劃線_經濟內外雙循環下的思考!

原創&#xff1a;群贏說到這個內外雙循環&#xff0c;我們汽車后市場朋友們&#xff0c;應該知道車子發動機水冷系統就是一個雙循環&#xff0c;內部小循環&#xff0c;外部大循環。在發動機溫度不高的時候&#xff0c;水在做小循環&#xff0c;在發動機周邊流動。當發動機溫度…