国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

從零實(shí)現(xiàn)一套低代碼(保姆級(jí)教程)【后端服務(wù)】 --- 【18】實(shí)現(xiàn)頁面接口對(duì)應(yīng)的前端

這篇具有很好參考價(jià)值的文章主要介紹了從零實(shí)現(xiàn)一套低代碼(保姆級(jí)教程)【后端服務(wù)】 --- 【18】實(shí)現(xiàn)頁面接口對(duì)應(yīng)的前端。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

摘要

在上一篇中,我們已經(jīng)把和頁面相關(guān)的接口完成的差不多了。從創(chuàng)建頁面,更新頁面等等:

從零實(shí)現(xiàn)一套低代碼(保姆級(jí)教程)【后端服務(wù)】 --- 【18】實(shí)現(xiàn)頁面接口對(duì)應(yīng)的前端,低代碼,前端
有了接口之后,我們就可以構(gòu)建前端頁面了。那這部分前端內(nèi)容我們應(yīng)該寫在哪里呢?

有兩種方式:

  1. 直接寫在我們的XinBuilder項(xiàng)目里面,然后通過前端路由拆分成兩個(gè)路由
  2. 在創(chuàng)建一個(gè)項(xiàng)目,然后打包到后端服務(wù)中,也就是通過后端路由去控制

因?yàn)槲也淮_定這個(gè)項(xiàng)目后面會(huì)有多少代碼,雖然我們目前只是想實(shí)現(xiàn)頁面的管理功能,但是后面我也不知道會(huì)增加到多少。

所以我準(zhǔn)備使用兩個(gè)React項(xiàng)目,和頁面相關(guān)的這些功能我都會(huì)寫在新的項(xiàng)目里,

1.創(chuàng)建項(xiàng)目

首先就是創(chuàng)建項(xiàng)目了,我們使用create-react-app創(chuàng)建一個(gè)項(xiàng)目:

>  npx create-react-app app-builder --template typescript

然后再安裝antD

 npm install antd --save

然后把項(xiàng)目里沒有用的文件刪一刪:

從零實(shí)現(xiàn)一套低代碼(保姆級(jí)教程)【后端服務(wù)】 --- 【18】實(shí)現(xiàn)頁面接口對(duì)應(yīng)的前端,低代碼,前端

最后,因?yàn)槲覀円?qǐng)求我們寫好的接口,在安裝一下axios。

npm install axios --save

2.路由的配置

對(duì)于這個(gè)項(xiàng)目,我們現(xiàn)在只準(zhǔn)備完成和pageJson相關(guān)的。但是后面可能會(huì)有其他的頁面,所以我們是需要路由的。

我們就先安裝一下react-router-dom,然后使用路由來管理前端的頁面。

 npm install react-router-dom --save

對(duì)于路由,我們?cè)趕rc下新建一個(gè)routes用來管理所有的路由頁面。

從零實(shí)現(xiàn)一套低代碼(保姆級(jí)教程)【后端服務(wù)】 --- 【18】實(shí)現(xiàn)頁面接口對(duì)應(yīng)的前端,低代碼,前端

page文件夾就是代表和pageJson相關(guān)的路由。

現(xiàn)在我們回到index.tsx中,對(duì)page路由進(jìn)行引入。

import React, { Suspense } from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import Page from './routes/page';
import { HashRouter as Router, Routes , Route} from "react-router-dom";


const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <Router>
    <Suspense>
    <Routes>
      <Route path={'/'} element={<Page />}></Route>
    </Routes>
    </Suspense>
  </Router>
);

3.服務(wù)端的CORS配置

這時(shí)候,如果我們?cè)陧?xiàng)目里調(diào)用服務(wù)端的接口,會(huì)有跨域的問題。所以在XinBuilderServer中,我們修改一下main.ts文件:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'
import { NestExpressApplication } from '@nestjs/platform-express';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule,{ cors: true });
  const options = new DocumentBuilder()
  .setTitle('API example')
  .addBearerAuth()
  .setVersion('1.0')
  .build()
  const document = SwaggerModule.createDocument(app, options)
  SwaggerModule.setup('api-docs', app, document)
  await app.listen(4000);
}
bootstrap();

通過修改CORS配置,來解決跨域的問題

的代碼提交在github上:
https://github.com/TeacherXin/XinBuilderServer2
commit: 第二節(jié):修改CORS配置解決跨域問題

4.構(gòu)建前端頁面

那我們需要的效果就是:

從零實(shí)現(xiàn)一套低代碼(保姆級(jí)教程)【后端服務(wù)】 --- 【18】實(shí)現(xiàn)頁面接口對(duì)應(yīng)的前端,低代碼,前端
至于這部分比較簡單,我把代碼的注釋寫一下,讀者自己看就行。

不過編輯頁面和預(yù)覽頁面,一會(huì)再細(xì)說。

import React, { useEffect, useState } from 'react'
import { Card, Col, Row, Button,Input, message, Modal,Divider, Select  } from 'antd';
import {DeleteOutlined,DatabaseOutlined,FormOutlined,InsertRowBelowOutlined,UsergroupDeleteOutlined} from '@ant-design/icons';
import axios from 'axios'
import './index.css'
const { Search } = Input

interface PageJson {
  pageName: string,
  pageId: string,
  pageJson: {
    [key: string]: any
  },
  _id: string
}

export default function Page() {
  const [messageApi, contextHolder] = message.useMessage();
  const [pageList, setPageList] = useState<PageJson []>()
  const [isModalOpen,setIsModalOpen] = useState<boolean>(false)
  const [pageName,setPageName] = useState<string>('')
  const [searchValue,setSearchValue] = useState<string>('')

  useEffect(() => {
    getPageList()
  }, [])

  /**
   * 獲取全部List的接口
   */
  const getPageList = () => {
    axios.post(`http://localhost:4000/page-json/findAllPage`)
    .then(res => {
      setPageList(res.data.data)
    })
    .catch(err => {
      messageApi.open({
        type: 'error',
        content: '獲取頁面列表失敗',
      });
    })
  }

  /**
   * 更改搜索框的內(nèi)容
   * @param value 搜索框的內(nèi)容
   */
  const onSearch = (value: string) => {
    setSearchValue(value)
  }

  /**
   * 新建頁面的彈窗
   */
  const addNewPage = () => {
    setIsModalOpen(true);
    setPageName('')
  }

  /**
   * 搜索內(nèi)容的過濾
   * @param list 頁面列表
   * @returns 過濾后的頁面列表
   */
  const getSearchList = (list: PageJson [] | undefined) => {
    return (list || []).filter(item => {
      return item.pageName.indexOf(searchValue) > -1
    })
  }

  /**
   * 根據(jù)頁面ID進(jìn)行刪除
   * @param pageId 頁面的ID
   * @returns 
   */
  const deletePage = (pageId: string) => {
    return () => {
      axios.post(`http://localhost:4000/page-json/deletePage`,{
        pageId
      })
      .then(res => {
        messageApi.open({
          type: 'success',
          content: '刪除成功',
        });
        getPageList()
      })
      .catch(err => {
        messageApi.open({
          type: 'error',
          content: '刪除失敗',
        });
      })
    }
  }

  /**
   * 新增頁面掉的接口
   */
  const handleOk = () => {
    const user = JSON.parse(localStorage.getItem('user') || '{}');
    axios.post(`http://localhost:4000/page-json/addPage`,{
      pageName: pageName,
      pageId:'pageInfo_' + new Date().getTime(),
      pageJson: {},
    })
    .then(res => {
      messageApi.open({
        type: 'success',
        content: '新建頁面成功',
      });
      getPageList()
      setIsModalOpen(false)
    })
    .catch(err => {
      messageApi.open({
        type: 'error',
        content: '新建頁面失敗',
      });
    })
  }

  /**
   * 新建頁面彈窗的取消回調(diào)
   */
  const handleCancel = () => {
    setIsModalOpen(false)
  }

  /**
   * 更改輸入的頁面名稱
   * @param e 頁面名稱
   */
  const changePageName = (e: any) => {
    setPageName(e.target.value)
  }

  const toBuilderPage = (pageId: string) => {
    return () => {

    }
  }

  

  return (
    <div className='PageList'>
      {contextHolder}
      <div className='pageLeft'>
        <div className='leftHeader'>XinBuilder</div>
        <div className='leftDiscribe'>輕量級(jí)的低代碼平臺(tái)</div>
        <Divider />
      </div>
      <div className='pageRight'>
        <div className='PageHeader'>
          <Search
            style={{ width: 304 }}
            onSearch={onSearch}
          />
          <Button className='pageButton' onClick={addNewPage}>新建頁面</Button>
        </div>
        <Divider />
        <div className='PageBody'>
          <Row style={{width:'100%'}} gutter={16}>
            {
              (getSearchList(pageList) || []).map(item => {
                return <Col style={{marginTop:'10px'}} key={item._id} span={6}>
                  <Card
                    title={<div><span>{item.pageName || '匿名'}</span><DeleteOutlined onClick={deletePage(item.pageId)}style={{float:'right',cursor:'pointer'}} /></div>}
                    bordered={false}
                    headStyle={{fontSize:'14px'}}
                  >
                    <div style={{height:'50px'}}>
                      <Button type='text' onClick={toBuilderPage(item.pageId)}>編輯頁面</Button>
                      <Button type='text'>預(yù)覽頁面</Button>
                    </div>
                  </Card>
                </Col>
              })
            }
          </Row>
        </div>
      </div>
      <Modal title="創(chuàng)建頁面" open={isModalOpen} onOk={handleOk} onCancel={handleCancel} okText='創(chuàng)建' cancelText='取消'>
          <Input addonBefore="頁面名稱" value={pageName} onChange={changePageName} />
      </Modal>
    </div>
  )
}

5.跳轉(zhuǎn)頁面詳情

當(dāng)我點(diǎn)擊編輯頁面的時(shí)候,應(yīng)該跳轉(zhuǎn)到對(duì)應(yīng)頁面的編輯狀態(tài)。也就是我們之前實(shí)現(xiàn)的項(xiàng)目。
那我在我們的設(shè)計(jì)器項(xiàng)目怎么知道當(dāng)前的頁面ID呢?

所以我們需要再跳轉(zhuǎn)的時(shí)候,將pageId帶過去,怎么帶呢,只能通過URL上面的參數(shù)實(shí)現(xiàn),所以我們現(xiàn)在可以實(shí)現(xiàn)一下toBuilderPage方法。

  /**
   * 根據(jù)頁面ID跳轉(zhuǎn)到詳情頁
   * @param pageId 頁面ID
   * @returns 
   */
  const toBuilderPage = (pageId: string) => {
    return () => {
      window.open(`http://localhost:3000?pageId=${pageId}`)
    }
  }

6.修改XinBuilder項(xiàng)目

OK,現(xiàn)在我們現(xiàn)在回到我們的低代碼項(xiàng)目里,在builder目錄下的index.tsx中,我們要根據(jù)URL上的pageId,調(diào)取接口來獲取到頁面詳情

獲取到之后,我們?cè)偻ㄟ^Store去更新redux。

import { useEffect } from 'react'
import DesignTop from './designTop'
import LeftCom from './leftPart'
import MainCom from './mainPart'
import RightCom from './rightPart'
import axios from 'axios'
import Store from '../../store'
import { message } from 'antd'

export default function Builder() {

  useEffect(() => {
    const search = window.location.search || '';
    const pageId = search.replace('?pageId=', '');
    axios.post('http://localhost:4000/page-json/findPageByID', {
      pageId
    })
    .then(res => {
      if(res.data.data) {
        Store.dispatch({type: 'changeComList', value: res.data.data.pageJson || []})
      }else{
        message.error('獲取頁面詳情失敗')
      }
    })
  }, [])

  return (
    <div>
      <DesignTop />
      <LeftCom />
      <MainCom />
      <RightCom />
    </div>
  )
}

OK,現(xiàn)在我們還需要就是給設(shè)計(jì)器增加保存的功能,我們來到designTop中,給它添加一個(gè)保存的按鈕。

import { Button, message } from 'antd'
import './index.css'
import Store from '../../../store'
import axios from 'axios'

export default function DesignTop() {

  const savePage = () => {
    const search = window.location.search || '';
    const pageId = search.replace('?pageId=', '');
    const comList = Store.getState().comList;
    axios.post('http://localhost:4000/page-json/updatePage', {
      pageId,
      pageJson: comList
    })
    .then(res => {
      if(res.data.code == 200) {
        message.success('保存成功')
      }
    })
  }

  return (
    <div className='designTop'>
      <span className='title'>XinBuilder</span>
      <Button onClick={savePage} type='primary' ghost>保存</Button>
    </div>
  )
}

到此為止,在上一篇中實(shí)現(xiàn)的所有接口,我們就實(shí)現(xiàn)完對(duì)它的調(diào)用了。

和XinBuilder相關(guān)的代碼提交在github上:
https://github.com/TeacherXin/XinBuilder2
commit: 第十七節(jié):實(shí)現(xiàn)頁面的保存以及加載

博主補(bǔ)充

本篇相關(guān)的代碼提交在github上:
https://github.com/TeacherXin/AppBuilder
commit: 第一節(jié):初始化項(xiàng)目,實(shí)現(xiàn)頁面的創(chuàng)建等操作

目前我們已經(jīng)有三個(gè)項(xiàng)目了:

  1. AppBuilder 最外層的殼子,提供創(chuàng)建頁面等操作
  2. XinBuilder 設(shè)計(jì)器項(xiàng)目,負(fù)責(zé)對(duì)頁面進(jìn)行配置
  3. XinBuilderServer 后端服務(wù),負(fù)責(zé)數(shù)據(jù)的存儲(chǔ)

后面還會(huì)有一個(gè)運(yùn)行時(shí)的項(xiàng)目。。。。。文章來源地址http://www.zghlxwxcb.cn/news/detail-815978.html

到了這里,關(guān)于從零實(shí)現(xiàn)一套低代碼(保姆級(jí)教程)【后端服務(wù)】 --- 【18】實(shí)現(xiàn)頁面接口對(duì)應(yīng)的前端的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 保姆級(jí)教程從零搭建云服務(wù)器(小彩蛋,請(qǐng)大家看煙花秀)

    保姆級(jí)教程從零搭建云服務(wù)器(小彩蛋,請(qǐng)大家看煙花秀)

    筆者已從零搭建好云服務(wù)器,在文章開始筆者請(qǐng)大家看一場簡單的煙花秀,該篇博文是寫給小白的保姆級(jí)教程,不論是有基礎(chǔ)還是沒基礎(chǔ)的,都可以根據(jù)本篇博文,輕松搭建個(gè)人云服務(wù)器。 煙花秀:瀏覽器直接輸入ysw.world:666回車即可,由于個(gè)人域名沒有備案,所以目前只能

    2024年02月03日
    瀏覽(20)
  • 保姆級(jí)教程!!教你通過【Pycharm遠(yuǎn)程】連接服務(wù)器運(yùn)行項(xiàng)目代碼

    保姆級(jí)教程??!教你通過【Pycharm遠(yuǎn)程】連接服務(wù)器運(yùn)行項(xiàng)目代碼

    這篇文章主要解決一個(gè)問題—— 我有服務(wù)器,但是不知道怎么拿來寫代碼,跑深度學(xué)習(xí)項(xiàng)目 。確實(shí),玩深度學(xué)習(xí)的成本比較高,無論是前期的學(xué)習(xí)成本,還是你需要具備的硬件成本,都是攔路虎。小羅沒有辦法幫你解決硬件上的問題,所以只能幫你們理清一下有了服務(wù)器以

    2024年03月27日
    瀏覽(21)
  • 【模型+代碼/保姆級(jí)教程】使用Pytorch實(shí)現(xiàn)手寫漢字識(shí)別

    【模型+代碼/保姆級(jí)教程】使用Pytorch實(shí)現(xiàn)手寫漢字識(shí)別

    參考文章: 最初參考的兩篇: 【Pytorch】基于CNN手寫漢字的識(shí)別 「Pytorch」CNN實(shí)現(xiàn)手寫漢字識(shí)別(數(shù)據(jù)集制作,網(wǎng)絡(luò)搭建,訓(xùn)練驗(yàn)證測試全部代碼) 模型: EfficientNetV2網(wǎng)絡(luò)詳解 數(shù)據(jù)集(不必從這里下載,可以看一下它的介紹): CASIA Online and Offline Chinese Handwriting Databases 鑒于

    2024年02月07日
    瀏覽(20)
  • Unity教程2:保姆級(jí)教程.幾行代碼實(shí)現(xiàn)輸入控制2D人物的移動(dòng)

    Unity教程2:保姆級(jí)教程.幾行代碼實(shí)現(xiàn)輸入控制2D人物的移動(dòng)

    目錄 人物的創(chuàng)建以及剛體的設(shè)置 圖層渲染層級(jí)設(shè)置 角色碰撞箱設(shè)置 使用代碼控制人物移動(dòng) 創(chuàng)建腳本文件 ?初始函數(shù)解釋 控制移動(dòng)代碼 初始化變量 ?獲得鍵盤輸入 ?調(diào)用函數(shù) 手冊(cè)鏈接在這:Unity User Manual (2019.3) - Unity 手冊(cè) 沒有控制人物移動(dòng)的2D游戲就太說不過去了!那么接

    2024年02月06日
    瀏覽(17)
  • docker從零部署jenkins保姆級(jí)教程

    docker從零部署jenkins保姆級(jí)教程

    jenkins,基本是最常用的持續(xù)集成工具。在實(shí)際的工作中,后端研發(fā)一般沒有jenkins的操作權(quán)限,只有一些查看權(quán)限,但是我們的代碼是經(jīng)過這個(gè)工具構(gòu)建出來部署到服務(wù)器的,所以我覺著有必要了解一下這個(gè)工具的搭建過程以及簡單的一些使用。盡可能多的了解公司中和你開

    2024年02月10日
    瀏覽(21)
  • 高級(jí)圣誕樹代碼實(shí)現(xiàn)合集-保姆級(jí)教程【前端三件套實(shí)現(xiàn)—0基礎(chǔ)直接運(yùn)行】

    高級(jí)圣誕樹代碼實(shí)現(xiàn)合集-保姆級(jí)教程【前端三件套實(shí)現(xiàn)—0基礎(chǔ)直接運(yùn)行】

    0基礎(chǔ)直接運(yùn)行教程: 1.新建txt文本: 2.將代碼粘貼到txt文本里: 3.將后綴改為html 4.雙擊打開html文件,觀察效果~ 這段代碼是一個(gè)用HTML和JavaScript實(shí)現(xiàn)的圣誕樹動(dòng)畫效果。我將代碼分成幾個(gè)部分進(jìn)行講解。 HTML結(jié)構(gòu): 在 head 標(biāo)簽中定義了頁面的標(biāo)題、字符集和樣式。 樣式部分

    2024年02月04日
    瀏覽(20)
  • docker從零部署jenkins保姆級(jí)教程(上)

    docker從零部署jenkins保姆級(jí)教程(上)

    jenkins,基本是最常用的持續(xù)集成工具。在實(shí)際的工作中,后端研發(fā)一般沒有jenkins的操作權(quán)限,只有一些查看權(quán)限,但是我們的代碼是經(jīng)過這個(gè)工具構(gòu)建出來部署到服務(wù)器的,所以我覺著有必要了解一下這個(gè)工具的搭建過程以及簡單的一些使用。盡可能多的了解公司中和你開

    2024年02月09日
    瀏覽(17)
  • docker從零部署jenkins保姆級(jí)教程(下)

    docker從零部署jenkins保姆級(jí)教程(下)

    上一篇文章,我們完成了以下工作。 1)、docker部署jenkins 2)、建立第一個(gè)jenkins job 3)、通過jenkins job自動(dòng)編譯構(gòu)建我們的github項(xiàng)目 上面所做的3個(gè)工作,其實(shí)都是為了這一篇文章打基礎(chǔ),不管是部署docker還是部署jenkins,我們最終的目的還是部署我們的項(xiàng)目,讓項(xiàng)目跑起來,讓流

    2024年02月09日
    瀏覽(18)
  • 保姆級(jí)教程:從零構(gòu)建GitHub Pages靜態(tài)網(wǎng)站

    保姆級(jí)教程:從零構(gòu)建GitHub Pages靜態(tài)網(wǎng)站

    Github Pages官網(wǎng):https://pages.github.com/ GitHub Pages 是 GitHub 提供的一個(gè)免費(fèi)的靜態(tài)網(wǎng)站托管服務(wù),它允許 GitHub 用戶創(chuàng)建和托管自己的靜態(tài)網(wǎng)站,這些網(wǎng)站可以通過特定的 GitHub 倉庫進(jìn)行管理和托管。 GitHub Pages 的主要特點(diǎn)包括 : 免費(fèi)托管 : GitHub Pages 提供免費(fèi)的靜態(tài)網(wǎng)站托管服務(wù)

    2024年02月04日
    瀏覽(26)
  • 「教程」如何使用一套代碼在多種程序中接入天氣預(yù)警API

    「教程」如何使用一套代碼在多種程序中接入天氣預(yù)警API

    天氣預(yù)警的重要性不言而喻,在遭受自然災(zāi)害和極端天氣時(shí),及時(shí)獲得預(yù)警信息可以拯救生命和減少財(cái)產(chǎn)損失。如今,隨著科技的進(jìn)步,開發(fā)者和企業(yè)可以借助天氣預(yù)警 API 這款強(qiáng)大的服務(wù),將實(shí)時(shí)預(yù)警信息集成到自己的應(yīng)用中,為用戶提供準(zhǔn)確的預(yù)警通知。 本文將重點(diǎn)探討

    2024年02月14日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包