整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          React:表單元素處理

          React 里,HTML 表單元素的工作方式和其他的 DOM 元素有些不同,這是因為表單元素通常會保持一些內部的 state。例如這個純 HTML 表單只接受一個名稱:

          <form>
            <label>
              名字:
              <input type="text" name="name" />
            </label>
            <input type="submit" value="提交" />
          </form>
          

          此表單具有默認的 HTML 表單行為,即在用戶提交表單后瀏覽到新頁面。如果你在 React 中執行相同的代碼,它依然有效。但大多數情況下,使用 JavaScript 函數可以很方便的處理表單的提交, 同時還可以訪問用戶填寫的表單數據。實現這種效果的標準方式是使用“受控組件”。
          受控組件

          在 HTML 中,表單元素(如<input>、 <textarea>和 <select>)之類的表單元素通常自己維護 state,并根據用戶輸入進行更新。而在 React 中,可變狀態(mutable state)通常保存在組件的 state 屬性中,并且只能通過使用 setState()來更新。

          我們可以把兩者結合起來,使 React 的 state 成為“唯一數據源”。渲染表單的 React 組件還控制著用戶輸入過程中表單發生的操作。被 React 以這種方式控制取值的表單輸入元素就叫做“受控組件”。

          例如,如果我們想讓前一個示例在提交時打印出名稱,我們可以將表單寫為受控組件:

          class NameForm extends React.Component {
            constructor(props) {
              super(props);
              this.state = {value: ''};
          
              this.handleChange = this.handleChange.bind(this);
              this.handleSubmit = this.handleSubmit.bind(this);
            }
          
            handleChange(event) {
              this.setState({value: event.target.value});
            }
          
            handleSubmit(event) {
              alert('提交的名字: ' + this.state.value);
              event.preventDefault();
            }
          
            render() {
              return (
                <form onSubmit={this.handleSubmit}>
                  <label>
                    名字:
                    <input type="text" value={this.state.value} onChange={this.handleChange} />
                  </label>
                  <input type="submit" value="提交" />
                </form>
              );
            }
          }
          

          由于在表單元素上設置了 value 屬性,因此顯示的值將始終為 this.state.value,這使得 React 的 state 成為唯一數據源。由于 handlechange 在每次按鍵時都會執行并更新 React 的 state,因此顯示的值將隨著用戶輸入而更新。

          對于受控組件來說,每個 state 突變都有一個相關的處理函數。

          這使得修改或驗證用戶輸入變得簡單。例如,如果我們要強制要求所有名稱都用大寫字母書寫,我們可以將 handlechange 改寫為:

          handleChange(event) {
            this.setState({value: event.target.value.toUpperCase()});
          }
          

          textarea 標簽

          在 HTML 中, <textarea> 元素通過其子元素定義其文本:

          <textarea>
            你好, 這是在 text area 里的文本
          </textarea>
          

          而在 React 中,<textarea> 使用 value 屬性代替。這樣,可以使得使用 <textarea> 的表單和使用單行 input 的表單非常類似:

          class EssayForm extends React.Component {
            constructor(props) {
              super(props);
              this.state = {
                value: '請撰寫一篇關于你喜歡的 DOM 元素的文章.'
              };
          
              this.handleChange = this.handleChange.bind(this);
              this.handleSubmit = this.handleSubmit.bind(this);
            }
          
            handleChange(event) {
              this.setState({value: event.target.value});
            }
          
            handleSubmit(event) {
              alert('提交的文章: ' + this.state.value);
              event.preventDefault();
            }
          
            render() {
              return (
                <form onSubmit={this.handleSubmit}>
                  <label>
                    文章:
                    <textarea value={this.state.value} onChange={this.handleChange} />
                  </label>
                  <input type="submit" value="提交" />
                </form>
              );
            }
          }
          

          請注意,this.state.value 初始化于構造函數中,因此文本區域默認有初值。

          select 標簽

          在 HTML 中,<select> 創建下拉列表標簽。例如,如下 HTML 創建了水果相關的下拉列表:

          <select>
            <option value="grapefruit">葡萄柚</option>
            <option value="lime">酸橙</option>
            <option selected value="coconut">椰子</option>
            <option value="mango">芒果</option>
          </select>
          

          請注意,由于 selected 屬性的緣故,椰子選項默認被選中。React 并不會使用 selected 屬性,而是在根 select 標簽上使用 value 屬性。這在受控組件中更便捷,因為您只需要在根標簽中更新它。例如:

          class FlavorForm extends React.Component {
            constructor(props) {
              super(props);
              this.state = {value: 'coconut'};
          
              this.handleChange = this.handleChange.bind(this);
              this.handleSubmit = this.handleSubmit.bind(this);
            }
          
            handleChange(event) {
              this.setState({value: event.target.value});
            }
          
            handleSubmit(event) {
              alert('你喜歡的風味是: ' + this.state.value);
              event.preventDefault();
            }
          
            render() {
              return (
                <form onSubmit={this.handleSubmit}>
                  <label>
                    選擇你喜歡的風味:
                    <select value={this.state.value} onChange={this.handleChange}>
                      <option value="grapefruit">葡萄柚</option>
                      <option value="lime">酸橙</option>
                      <option value="coconut">椰子</option>
                      <option value="mango">芒果</option>
                    </select>
                  </label>
                  <input type="submit" value="提交" />
                </form>
              );
            }
          }
          

          總的來說,這使得 <input type="text">, <textarea> 和 <select> 之類的標簽都非常相似—它們都接受一個 value 屬性,你可以使用它來實現受控組件。

          注意
          你可以將數組傳遞到 value 屬性中,以支持在 select 標簽中選擇多個選項:
          <select multiple={true} value={['B', 'C']}>

          文件 input 標簽

          在 HTML 中,<input type=“file”> 允許用戶從存儲設備中選擇一個或多個文件,將其上傳到服務器,或通過使用 JavaScript 的 File API 進行控制。

          <input type="file" />
          

          因為它的 value 只讀,所以它是 React 中的一個非受控組件。將與其他非受控組件在后續文檔中一起討論。

          處理多個輸入

          當需要處理多個 input 元素時,我們可以給每個元素添加 name 屬性,并讓處理函數根據 event.target.name 的值選擇要執行的操作。

          例如:

          class Reservation extends React.Component {
            constructor(props) {
              super(props);
              this.state = {
                isGoing: true,
                numberOfGuests: 2
              };
          
              this.handleInputChange = this.handleInputChange.bind(this);
            }
          
            handleInputChange(event) {
              const target = event.target;
              const value = target.type === 'checkbox' ? target.checked : target.value;
              const name = target.name;
          
              this.setState({
                [name]: value
              });
            }
          
            render() {
              return (
                <form>
                  <label>
                    參與:
                    <input
                      name="isGoing"
                      type="checkbox"
                      checked={this.state.isGoing}
                      onChange={this.handleInputChange} />
                  </label>
                  <br />
                  <label>
                    來賓人數:
                    <input
                      name="numberOfGuests"
                      type="number"
                      value={this.state.numberOfGuests}
                      onChange={this.handleInputChange} />
                  </label>
                </form>
              );
            }
          }
          

          這里使用了 ES6 計算屬性名稱的語法更新給定輸入名稱對應的 state 值:

          例如:

          this.setState({
            [name]: value
          });
          

          等同 ES5:

          var partialState = {};
          partialState[name] = value;
          this.setState(partialState);
          

          另外,由于 setState() 自動將部分 state 合并到當前 state, 只需調用它更改部分 state 即可。
          受控輸入空值

          在受控組件上指定 value 的 prop 可以防止用戶更改輸入。如果指定了 value,但輸入仍可編輯,則可能是意外地將value 設置為 undefined 或 null。

          下面的代碼演示了這一點。(輸入最初被鎖定,但在短時間延遲后變為可編輯。)

          ReactDOM.render(<input value="hi" />, mountNode);
          
          setTimeout(function() {
            ReactDOM.render(<input value={null} />, mountNode);
          }, 1000);
          

          受控組件的替代品

          有時使用受控組件會很麻煩,因為你需要為數據變化的每種方式都編寫事件處理函數,并通過一個 React 組件傳遞所有的輸入 state。當你將之前的代碼庫轉換為 React 或將 React 應用程序與非 React 庫集成時,這可能會令人厭煩。在這些情況下,你可能希望使用非受控組件, 這是實現輸入表單的另一種方式。
          成熟的解決方案

          如果你想尋找包含驗證、追蹤訪問字段以及處理表單提交的完整解決方案,使用 Formik 是不錯的選擇。然而,它也是建立在受控組件和管理 state 的基礎之上 —— 所以不要忽視學習它們。

          帶有兩個輸入字段和一個提交按鈕的 HTML 表單:

          <form action="demo_form.php" method="get">

          First name: <input type="text" name="fname"><br>

          Last name: <input type="text" name="lname"><br>

          <input type="submit" value="提交">

          </form>

          (更多實例見頁面底部)


          瀏覽器支持

          所有主流瀏覽器都支持 <form> 標簽。


          標簽定義及使用說明

          <form> 標簽用于創建供用戶輸入的 HTML 表單。

          <form> 元素包含一個或多個如下的表單元素:

          • <input>

          • <textarea>

          • <button>

          • <select>

          • <option>

          • <optgroup>

          • <fieldset>

          • <label>


          HTML 4.01 與 HTML5之間的差異

          HTML5 新增了兩個新的屬性:autocomplete 和 novalidate,同時不再支持 HTML 4.01 中的某些屬性。


          HTML 與 XHTML 之間的差異

          在 XHTML 中,name 屬性已被廢棄。使用全局 id 屬性代替。


          屬性

          New :HTML5 中的新屬性。

          屬性描述
          acceptMIME_typeHTML5 不支持。規定服務器接收到的文件的類型。(文件是通過文件上傳提交的)
          accept-charsetcharacter_set規定服務器可處理的表單數據字符集。
          actionURL規定當提交表單時向何處發送表單數據。
          autocompleteNewonoff規定是否啟用表單的自動完成功能。
          enctypeapplication/x-www-form-urlencodedmultipart/form-datatext/plain規定在向服務器發送表單數據之前如何對其進行編碼。(適用于 method="post" 的情況)
          methodgetpost規定用于發送表單數據的 HTTP 方法。
          nametext規定表單的名稱。
          novalidateNewnovalidate如果使用該屬性,則提交表單時不進行驗證。
          target_blank_self_parent_top規定在何處打開 action URL。

          全局屬性

          <form> 標簽支持 HTML 的全局屬性。


          事件屬性

          <form> 標簽支持 HTML 的事件屬性。

          實例

          帶有復選框的表單

          此表單包含兩個復選框和一個提交按鈕。

          帶有單選按鈕的表單

          此表單包含兩個單選框和一個提交按鈕。

          如您還有不明白的可以在下面與我留言或是與我探討QQ群308855039,我們一起飛!

          ## 什么是表單:

          django中的表單不是html中的那個表單.**這個表單是用來驗證數據的合法性的一個東西**,也可以生成HTML代碼.

          ### 使用表單:

          1. 創建一個`forms.py`的文件,放在指定的app當中,然后在里面寫表單.

          2. 表單是通過類實現的,繼承自`forms.Form`,然后在里面定義要驗證的字段.

          3. 在表單中,創建字段跟模型是一模一樣的,但是沒有`null=True`或者`blank=True`等這幾種參數了,有的參數是`required=True/False`.

          4. 使用`is_valid()`方法可以驗證用戶提交的數據是否合法,而且HTML表單元素的`name`必須和`django`中的表單的`name`保持一致,否則匹配不到.

          5. `is_bound`屬性:用來表示`form`是否綁定了數據,如果綁定了,則返回`True`,否則返回`False`.

          6. `cleaned_data`:這個是在`is_valid()`返回`True`的時候,保存用戶提交上來的數據.

          ```

          username = form.cleaned_data.get('username',None)

          password = form.cleaned_data.get('password',None)

          password_repeat = form.cleaned_data.get('password_repeat',None)

          email = form.cleaned_data.get('email',None)

          ```

          7. 表單生成HTML元素:

          ```

          **views.py**

          if request.method == 'GET':

          return render(request,'regist_form.html',{'form':RegistForm()})

          ```

          ```

          **regist.html**

          <form action="" method='POST'>

          {%csrf_token%}

          {{form}}

          <input type="submit" vlaue='注冊'>

          </form>

          ```

          * 使用django的Form類生成的表單,不包含form和submit按鈕兩個標簽,需要手動添加。

          * 這個模塊用得比較少,這個功能確實很雞肋,把前端該做的事情放到后臺來實現,增加了代碼的耦合性也增加了服務器的壓力。在真正開發中,是講究前后端代碼分離的。

          ### 上傳文件:

          1. 在相應的模型里面定義`FileField`或者是`ImageField`類型的字段,并且設置好`upload_to`參數來指定上傳的路徑.

          2. 需要在`settings.py`文件中指定媒體路徑`MEDIA_ROOT`.

          3. 數據庫保存的是文件的路徑,不會保存文件本身.

          4. 文件上傳需要在HTML代碼中的form表單中添加`enctype="multipart/form-data"`以及在views當中,使用`request.FILES`來接收文件.

          ### 表單錯誤消息:

          1. 表單驗證沒有通過后,表單會產生一個`errors`屬性,這個屬性包括所有的驗證錯誤信息。

          2. 通過`form.errors`即可訪問。

          3. 通過`form.errors.as_json()`可以將錯誤消息轉換成json數據。

          4. 自定義錯誤消息:在`Field`中添加一個`error_messages`的`dict`類型的參數,然后根據`code`值設置對應的`message`,例如以下代碼:

          ```

          password = forms.CharField(max_length=10,error_messages={'required':u'密碼不能少'})

          ```

          其中`code`為`required`.

          ### 表單自定義錯誤消息:

          1. 在表單中,重寫方法`clean_field`,可以自定義針對某一個`field`的驗證機制,如果出現錯誤,拋出一個`ValidationError`異常就可以了。

          ```

          def clean_password(self):

          password = self.cleaned_data.get('password',None)

          if len(password) < 6:

          raise forms.ValidationError(u'password at least 6 length',code='min_length')

          ```

          2. 重寫`clean`方法可以在完成`django`默認的驗證后,再重新執行`clean`方法的驗證,如果某個`field`出現驗證錯誤,通過`add_error`方法給指定的field添加錯誤消息。如果想拋出一個不屬于任何field的錯誤,直接`raise ValidationError(message)`就可以了。然后通過`__all__`進行訪問。也可以通過`form.non_field_errors()`進行訪問。

          3. `clean_fieldname`在判斷沒有問題以后,需要返回這個值,比如以下代碼,如果不返回`password`,那么后面就不能獲取到`password`這個值了:

          ```

          def clean_password(self):

          password = self.cleaned_data.get('password',None)

          if len(password) < 6:

          raise forms.ValidationError(u'password at least 6 length',code='min_length')

          return password

          ```

          `clean`方法可以不用返回`cleaned_data`,但是為了代碼健全和可讀性,應該返回`cleaned_data`.


          主站蜘蛛池模板: 国产中文字幕一区| 中文日韩字幕一区在线观看| 精品无人乱码一区二区三区| 国产激情一区二区三区在线观看| 久久精品岛国av一区二区无码| 免费在线观看一区| 日韩一区二区三区在线| 无码精品黑人一区二区三区| 日本高清成本人视频一区| 麻豆一区二区三区蜜桃免费| 麻豆精品人妻一区二区三区蜜桃| 老熟女五十路乱子交尾中出一区| 99精品国产一区二区三区| 日本视频一区二区三区| 国产成人无码精品一区不卡| 国产一区二区在线| 久久成人国产精品一区二区| 内射少妇一区27P| 日本精品高清一区二区2021| 亚洲一区无码中文字幕乱码| 日本免费一区二区三区四区五六区| 中文字幕永久一区二区三区在线观看| 无码精品人妻一区二区三区影院 | 免费无码A片一区二三区| 亚洲福利秒拍一区二区| 国产精品一区在线播放| 亚洲AV无码一区二区乱子仑| 亚洲性色精品一区二区在线| 麻豆国产在线不卡一区二区| 日韩AV片无码一区二区不卡| 麻豆视频一区二区三区| 精品乱子伦一区二区三区高清免费播放 | 男人的天堂亚洲一区二区三区 | 久久精品一区二区三区四区| 亚洲日本va午夜中文字幕一区| 久久久久成人精品一区二区| 国产一区二区久久久| 国产福利一区二区| 久久国产精品一区二区| 精品无码成人片一区二区98| 日本精品无码一区二区三区久久久 |