主頁 > 企業開發 > react 高效高質量搭建后臺系統 系列 —— 結尾

react 高效高質量搭建后臺系統 系列 —— 結尾

2023-02-21 08:47:54 企業開發

其他章節請看:

react 高效高質量搭建后臺系統 系列

尾篇

本篇主要介紹表單查詢表單驗證通知(WebSocket)、自動構建,最后附上 myspug 專案原始碼,

專案最終效果:

表單查詢

需求:給角色管理頁面增加表格查詢功能,通過輸入角色名稱,點擊查詢,從后端檢索出相應的資料,

效果如下:

spug 中的實作

spug 中的這類查詢都是在前端過濾出相應的資料(沒有查詢按鈕),因為 spug 中大多數的 table 都是一次性將資料從后端拿回來,

spug 中角色管理搜索相關代碼如下:

  • 隨著 input 中輸入要搜索的角色名稱更改 store 中的 f_name 欄位:
<SearchForm>
  <SearchForm.Item span={8} title="角色名稱">
    <Input allowClear value=https://www.cnblogs.com/pengjiali/archive/2023/02/20/{store.f_name} onChange={e => store.f_name = e.target.value} placeholder="請輸入"/>
  </SearchForm.Item>
</SearchForm>

:select 中的值不同于 input(e.target.value),直接就是第一個引數,所以得這么寫:onChange={v => store.f_xx = v}

  • 表格的資料源會動態過濾:
@computed get dataSource() {
  // 從 this.records 中過濾出資料
  let records = this.records;
  if (this.f_name) records = records.filter(x => x.name.toLowerCase().includes(this.f_name.toLowerCase()));
  return records
}

實作

相對 spug 的查詢,現在思路得變一下:通過點擊搜索按鈕,重新請求資料,附帶查詢關鍵字給后端,

核心邏輯如下:

// myspug\src\pages\system\role\index.js

import ComTable from './Table';
import { AuthDiv, SearchForm, } from '@/components';
import store from './store';

export default function () {
  return (
    <AuthDiv auth="system.role.view">
      <SearchForm>
        <SearchForm.Item span={6} title="角色名稱">
          <Input allowClear value=https://www.cnblogs.com/pengjiali/archive/2023/02/20/{store.f_name} onChange={e => store.f_name = e.target.value} placeholder="請輸入" />
        </SearchForm.Item>
        <SearchForm.Item span={6}>
          <Button type="primary" onClick={() => {
            // 重置為第一頁
            store.setCurrent(1)
            store.fetchRecords();
          }}>查詢</Button>
        </SearchForm.Item>
      </SearchForm>
      <ComTable />
    </AuthDiv>
  )
}

Store 中就是在請求表格時將過濾引數帶上:

 class Store {
+  @observable f_name;

   @observable records = [];

   _getTableParams = () => ({current: this.current, ...this.tableOptions})

+  @action setCurrent(val){
+    this.current = val
+  }

   fetchRecords = () => {
     const realParams = this._getTableParams()
+    // 過濾引數
+    if(this.f_name){
+      realParams.role_name = this.f_name
+    }
+    console.log('realParams', realParams)
     this.isFetching = true;
     http.get('/api/account/role/', {params: realParams})
       .then(res => {

Tip:剩余部分就沒什么了,比如樣式直接復制 spug 中(筆者直接拷過來頁面有點問題,稍微注釋了一段 css 即可);SearchForm 就是對表單簡單封裝,統一 spug 中表單的寫法:

// myspug\src\components\SearchForm.js
import React from 'react';
import { Row, Col, Form } from 'antd';
import styles from './index.module.less';

export default class extends React.Component {
  static Item(props) {
    return (
      <Col span={props.span} offset={props.offset} style={props.style}>
        <Form.Item label={props.title}>
          {props.children}
        </Form.Item>
      </Col>
    )
  }

  render() {
    return (
      <div className={styles.searchForm} style={this.props.style}>
        <Form style={this.props.style}>
          <Row gutter={{md: 8, lg: 24, xl: 48}}>
            {this.props.children}
          </Row>
        </Form>
      </div>
    )
  }
}

效果

實作效果如下:

輸入關鍵字name,點擊查詢按鈕,重新請求表格資料(從第一頁開始)

表單驗證

spug 中的表單驗證

關于表單驗證,spug 中前端寫的很少,請看以下一個典型示例:

新建角色時,為空等校驗都是后端做的,

雖然后端一定要做校驗,但前端最好也做一套,

實作

筆者表單的驗證思路是:

  • 必填項都有值(還可以包括其他邏輯),提交按鈕才可點,否則置灰
  • 點擊提交后,前端根據需求做進一步驗證,例如名字不能有空格

以下是新增和編輯時的效果(重點關注確定按鈕):

  • 當必填項都有值時確定按鈕可點,否則置灰
  • 必填項都有值時,點擊確定按鈕做進一步校驗(例如名字不能有空格)
  • 編輯時如果都有值,則確定按鈕可點擊

表單

先實作表單,效果如下:

核心代碼如下:

  • 首先定義表單模塊:
// myspug\src\pages\system\role\Form.js
import http from '@/libs/http';
import store from './store';

export default observer(function () {
    // 檔案中未找到這種解構使用方法
    const [form] = Form.useForm();
    // useState 函陣列件中使用 state
    // loading 默認是 flase
    const [loading, setLoading] = useState(false);

    function handleSubmit() {
        setLoading(true);
        // 取得表單欄位的值
        const formData = https://www.cnblogs.com/pengjiali/archive/2023/02/20/form.getFieldsValue();
        // 新建時 id 為 undefined
        formData['id'] = store.record.id;
        http.post('/api/account/role/', formData)
            .then(res => {
                message.success('操作成功');
                store.formVisible = false;
                store.fetchRecords()
            }, () => setLoading(false))
    }

    return (
        // Modal 對話框
        <Modal
            visible
            maskClosable={false}
            title={store.record.id ? '編輯角色' : '新建角色'}
            onCancel={() => store.formVisible = false}
            confirmLoading={loading}
            onOk={handleSubmit}>
            <Form form={form} initialValues={store.record} labelCol={{ span: 6 }} wrapperCol={{ span: 14 }}>
                <Form.Item required name="name" label="角色名稱">
                    <Input placeholder="請輸入角色名稱" />
                </Form.Item>
                <Form.Item name="desc" label="備注資訊">
                    <Input.TextArea placeholder="請輸入角色備注資訊" />
                </Form.Item>
            </Form>
        </Modal>
    )
})
  • 然后在入口頁中根據 store 中的 formVisible 控制顯隱藏表單組件
// myspug\src\pages\system\role\index.js
export default observer(function () {
   return (
     <AuthDiv auth="system.role.view">
       <SearchForm>
         </SearchForm.Item>
       </SearchForm>
       <ComTable />
+      {/* formVisible 控制表單顯示 */}
+      {store.formVisible && <ComForm />}
     </AuthDiv>
   )
})
  • 點擊新建是呼叫 store.showForm() 讓表單顯示出來
 // myspug\src\pages\system\role\store.js

 class Store {
+  @observable formVisible = false;
+  @observable record = {};


+  // 顯示新增彈框
+  // info 或許是為了編輯
+  showForm = (info = {}) => {
+    this.formVisible = true;
+    this.record = info
+  };
表單校驗

在表單基礎上實作校驗,

主要在 Form.js 中修改,思路如下:

  • 首先利用 okButtonProps 控制確定按鈕是否可點
  • 然后通過 shouldUpdate={emptyValid} 自定義欄位更新邏輯
  • 可提交后,在做進一步判斷,例如名字不能為空
 // myspug\src\pages\system\role\Form.js
-import React, { useState } from 'react';
+import React, { useEffect, useState } from 'react';
 import { observer } from 'mobx-react';
 import { Modal, Form, Input, message } from 'antd';
 import http from '@/libs/http';
     // useState 函陣列件中使用 state
     // loading 默認是 flase
     const [loading, setLoading] = useState(false);
+    const [canSubmit, setCanSubmit] = useState(false);
     function handleSubmit() {
         // 取得表單欄位的值
         const formData = https://www.cnblogs.com/pengjiali/archive/2023/02/20/form.getFieldsValue();
+
+        if(formData.name && (/s+/g).test(formData.name)){
+            message.error('名字不允許有空格')
+            return
+        }
+        if(formData.tel && (/\s+/g).test(formData.tel)){
+            message.error('電話不允許有空格')
+            return
+        }

         // 新建時 id 為 undefined
         formData['id'] = store.record.id;
         http.post('/api/account/role/', formData).then(...)
         
     }

+    function emptyValid() {
+        const formData = https://www.cnblogs.com/pengjiali/archive/2023/02/20/form.getFieldsValue();
+        const { name, tel } = formData;
+        const isNotEmpty = !!(name && tel);
+        setCanSubmit(isNotEmpty)
+    }

+    useEffect(() => {
+        // 主動觸發,否則編輯時即使都有資料,`確定`按鈕扔不可點
+        emptyValid()
+    }, [])
+
     return (
         // Modal 對話框
         

:有兩點需要注意

  • 需要兩個欄位都增加 shouldUpdate,如果只有一個,修改該項則不會觸發 emptyValid()
  • 組件加載后主動觸發 emptyValid(),否則編輯時即使都有資料,確定按鈕扔不可點

效果

以下演示了新建和編輯時的效果:

  • 當必填項都有值時確定按鈕可點,否則置灰
  • 必填項都有值時,點擊確定按鈕做進一步校驗(例如名字不能有空格)
  • 編輯時如果都有值,則確定按鈕可點擊

WebSocket

通知

后端系統通常會有通知功能,用輪詢的方式去和后端要資料不是很好,通常是后端有資料后再告訴前端,

spug 中的通知使用的是 webSocket

Tip:WebSockets 是一種先進的技術,它可以在用戶的瀏覽器和服務器之間打開互動式通信會話,使用此 API,您可以向服務器發送訊息并接收事件驅動的回應,而無需通過輪詢服務器的方式以獲得回應,

以下是 spug 中通知模塊的代碼片段:

  // spug\src\layout\Notification.js
  function fetch() {
    setLoading(true);
    http.get('/api/notify/')
      .then(res => {
        setReads(res.filter(x => !x.unread).map(x => x.id))
        setNotifies(res);
      })
      .finally(() => setLoading(false))
  }

  function listen() {
    if (!X_TOKEN) return;
    const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
    // Create WebSocket connection.
    ws = new WebSocket(`${protocol}//${window.location.host}/api/ws/notify/?x-token=${X_TOKEN}`);
    // onopen - 用于指定連接成功后的回呼函式,
    // Connection opened
    ws.onopen = () => ws.send('ok');
    // onmessage - 用于指定當從服務器接受到資訊時的回呼函式,
    // Listen for messages
    ws.onmessage = e => {
      if (e.data !== 'pong') {
        fetch();
        const {title, content} = JSON.parse(e.data);
        const key = `open${Date.now()}`;
        const description = <div style={{whiteSpace: 'pre-wrap'}}>{content}</div>;
        const btn = <Button type="primary" size="small" onClick={() => notification.close(key)}>知道了</Button>;
        notification.warning({message: title, description, btn, key, top: 64, duration: null})
      }
    }
  }

通過 WebSocket 創建 webSocket 連接,然后通過 onmessage 監聽服務端的訊息,這里好像是后端告訴前端有新訊息,前端在通過另一個介面發起 http 請求,

服務端

筆者接下來用 node + ws 實作 WebSocket 服務端,

效果如下(每3秒客戶端和服務器都會向對方發送一個訊息):

對應的請求欄位:

實作如下:

  • 新建專案,安裝依賴
$ mkdir websocket-test
$ cd websocket-test
// 初始化專案,生產 package.json
$ npm init -y
// 安裝依賴
$ npm i ws express
  • 新建服務器 server.js
const express = require('express')
const app = express()
app.get('/', function (req, res) {
    res.sendfile(__dirname + '/index.html');
});
app.listen(3020);

const WebSocketServer = require('ws');
const wss = new WebSocketServer.Server({ port: 8080 });
wss.on('connection', function connection(ws) {

    // 監聽來自客戶端的訊息
    ws.on('message', function incoming(message) {
        console.log('' + message);
    });

    setInterval(() => {
        ws.send('客戶端你好');
    }, 3000)
});
  • 客戶端代碼 index.html:
<body>
    <script>
        var ws = new WebSocket('ws://localhost:8080');
        ws.onopen = function () {
              ws.send('ok');
        };
        ws.onmessage = function (e) {
            console.log(e.data)
        };

        setInterval(() => {
            ws.send('服務器你好');
        }, 3000)
    </script>
</body>
  • 最后啟動服務 node server.js,瀏覽器訪問 http://localhost:3020/

擴展

面包屑

spug 中的面包屑(導航)僅對 antd 面包屑稍作封裝,不支持點擊,

要實作點擊跳轉的難點是要有對應的路由,而 spug 這里對應的是 404,所以它干脆就不支持跳轉

自動構建

筆者代碼提交到 gitlab,使用其中的 CICD 模塊可用于構建流水線,以下是 wayland(匯入 wayland 官網到內網時發現的,開源精神極高,考慮到網友有這個需求,) 的一個構建截圖:

這里不過多展開介紹 gitlab cicd 流水線,總之通過觸發流水線,gitlab 就會執行專案下的一個 .yml 腳本,我們則可以通過腳本實作編譯部署

需求:通過流水線實作 myspug 的部署,

  • 新建入口檔案:.gitlab-ci.yml
// .gitlab-ci.yml

stages:
  - deploy
# 部署到測驗環境
deplay_to_test:
  state: deply
  tags:
    # 運行流水線的機器
    - ubuntu2004_27.141-myspug
  rules:
    # 觸發流水線時的變數,EFPLOY_TO_TEST 不為空則運行 deploy-to-test.sh 這個腳本
    - if: EFPLOY_TO_TEST != null && $DEPLOY_TO_TEST != ""
  script:
    - chmod + x deploy-to-test.sh && ./deploy-to-test.sh
# 部署到生產環境
deplay_to_product:
  state: deply
  tags:
    - ubuntu2004_27.141-myspug
  rules:
    - if: EFPLOY_TO_product != null && $DEPLOY_TO_product != ""
  script:
    - chmod + x deploy-to-product.sh && ./deploy-to-product.sh 
  • 部署到生產環境的腳本:deploy-to-product.sh
// deploy-to-product.sh 

#!/bin/bash
# 部署到生產環境
# 開啟:如果命令以非零狀態退出,則立即退出
set -e
DATETIME=$(date +%Y-%m-%d_%H%M%S)
echo DATETIME=$DATETIME

SERVERIP=192.168.27.135

SERVERDIR=/data/docker_data/myspug_web

BACKDIR=/data/backup/myspug

# 將構建的檔案傳給服務器
zip -r build.zip build
scp ./build.zip root@${SERVERIP}:${BACKDIR}/
rm -rf build.zip

# 登錄生產環境服務器
ssh root${SERVERIP}<< reallssh
echo login:${SERVERIP}

# 備份目錄
[ ! -d "${BACKDIR}/${DATETIME}" ] && mkdir -p "${BACKDIR}/${DATETIME}"

echo 備份目錄已創建或已存在

# 洗掉30天以前的包
find ${BACKDIR}/ -mtime +30 -exec rm -rf {} \;

# 將包備份一份
cp ${BACKDIR}/build.zip ${BACKDIR}/${DATETIME}

mv ${BACKDIR}/build.zip ${SERVERDIR}/

cd ${SERVERDIR}/

rm -rf ./build

unzip build.zip

rm -rf build.zip

echo 部署完成

exit

reallssh

完整專案

專案已上傳至 github(myspug),

克隆后執行以下兩條命令即可在本地啟動服務:

$ npm i
$ npm run start

瀏覽器訪問效果如下:

后續

后續有時間還想再寫這3部分:

  • 專案檔案,一個系統通常得有對應的檔案,就像這樣:

  • 系統概要設計,用于其他人快速接手這個專案

  • 互動設計,spug 中有不少的互動點可以提高相關系統的見識,例如這個抽屜互動

其他章節請看:

react 高效高質量搭建后臺系統 系列

作者:彭加李
出處:https://www.cnblogs.com/pengjiali/p/17139099.html
本文著作權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連接,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/544497.html

標籤:其他

上一篇:Vue學習隨筆(一)Vue的引入

下一篇:立即執行函式在前端國際化方案中的應用

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more