cms系统,网络推广seo教程,关于网站建设征求意见,网站开发的背景知识与相关技术大家好#xff0c;我是若川。持续组织了6个月源码共读活动#xff0c;感兴趣的可以点此加我微信 ruochuan12 参与#xff0c;每周大家一起学习200行左右的源码#xff0c;共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。今天#xff0c;你… 大家好我是若川。持续组织了6个月源码共读活动感兴趣的可以点此加我微信 ruochuan12 参与每周大家一起学习200行左右的源码共同进步。同时极力推荐订阅我写的《学习源码整体架构系列》 包含20余篇源码文章。今天你将为自己创建一个最重要的应用程序——你的作品集。每个 React 开发者或者 Web 开发者通常需要向潜在的客户或者雇主展示自己能做什么。在这篇文章里我们将使用 React、Tailwind CSS、Netlify 等等行业标准工具创建一个作品集网站。开始吧作品集是怎样的这是你将要建立的最终版本。它的作用是展示你自己、你做过什么项目、你在做这些项目时用了什么技能还有一个联系表单以便客户或者雇主联系上你。我们将使用什么工具- 我们将用 React 来创建应用程序的用户界面。它将允许我们通过可重复使用的组件来组成登录页面的每一部分以及添加我们想要的功能例如博客。- 为了设计我们的应用程序我们将使用 Tailwind CSS。Tailwind 允许我们通过组合类名classnames将多种样式轻松应用到 React 项目上给应用程序一个专业的外观。- 为了把我们的应用程序部署到网络上我们将使用免费的 Netlify。通过 CDN 的帮助下用户可以通过我们自己的的域名快速访问到我们的项目。如何开始你可以在这里下载我们项目的启动文件https://reedbarger.ck.page/react-portfolio-2021。当你获取到代码你要做的是把解压好的项目文件夹拖到代码编辑器中然后在终端运行命令。npm install然后可以开始了我需要使用什么工具来构建作品集从创建到部署应用程序需要- 你的电脑安装 Node.js你可以在 nodejs.org 下载安装程序。- 在你的电脑安装 Git你可以在 git-scm.com 下载。- 我建议使用 VS Code 作为你的代码编辑器。你可以在 code.visualstudio.com 下载它。- 一个在 Netlify.com 上的免费的 Netlify 账户。- 一个免费的 GitHub 账号。如何建立作品集的结构使用 React 的好处是我们可以将我们的应用程序扩展到任意多的页面并添加大量的内容这是非常容易的。但是由于我们只处理一个页面所以可以在应用程序组件中非常快速地找到需要的不同组件。我们将在顶部放一个导航栏通过上面的链接可以跳转到作品集的不同部分。然后我们将有一个“关于”部分这里包含我们的项目介绍、客户推荐以及联系表单。这种快速的规划使我们能够弄清楚组件怎样命名以什么顺序命名。下一步把它们全部添加到我们的 App.js 文件夹中在 src 文件夹// src/App.jsimport React from react;export default function App() {return (mainNavbar /About /Projects /Skills /Testimonials /Contact //main);
}如何创建组件现在我们已经列出了所有这些组件我们需要继续创建它们。在源代码src文件夹中我们将创建一个 components 文件夹里面有我们需要的所有文件。my-portfolio
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
└── src├── App.js├── data.js├── index.css├── index.js└── components├── About.js├── Contact.js├── Navbar.js├── Projects.js├── Skills.js└── Testimonials.js然后我们将创建每个 React 组件的基本结构并使用 export default 从该文件导出// src/components/About.jsexport default function About() {}// repeat the same basic structure for all 6 components在所有的 6 个组件中重复相同的结构最后在 App.js 中导入它// src/App.jsimport React from react;
import About from ./components/About;
import Contact from ./components/Contact;
import Navbar from ./components/Navbar;
import Projects from ./components/Projects;
import Skills from ./components/Skills;
import Testimonials from ./components/Testimonials;export default function App() {return (mainNavbar /About /Projects /Skills /Testimonials /Contact //main);
}请注意总共应该有 6 个组件Tailwind CSS 介绍做完上面的我们可以开始使用 Tailwind CSS 给我们的应用程序一个基本的外观。使用 Tailwind CSS 的好处是我们不必在 CSS 中手动编写任何样式而是组合多个类class来创建我们想要的外观。// src/App.jsimport React from react;
import About from ./components/About;
import Contact from ./components/Contact;
import Navbar from ./components/Navbar;
import Projects from ./components/Projects;
import Skills from ./components/Skills;
import Testimonials from ./components/Testimonials;export default function App() {return (main classNametext-gray-400 bg-gray-900 body-fontNavbar /About /Projects /Skills /Testimonials /Contact //main);
}如何构建 About 组件现在开始第一部分即 about 部分介绍我们的基本情况和擅长的技能。它还将包含联系表单的链接以及我们过去的项目。由于这些链接将指向同一页面的不同部分我们能使用 /#projects 和 /#contact。为了使这些链接能跳转到每个部分我们把项目部分 id 的属性设置为 projects把联系部分的 id 属性设置为 contact。// src/components/About.jsimport React from react;export default function About() {return (section idaboutdiv classNamecontainer mx-auto flex px-10 py-20 md:flex-row flex-col items-centerdiv classNamelg:flex-grow md:w-1/2 lg:pr-24 md:pr-16 flex flex-col md:items-start md:text-left mb-16 md:mb-0 items-center text-centerh1 classNametitle-font sm:text-4xl text-3xl mb-4 font-medium text-whiteHi, Im Reed.br classNamehidden lg:inline-block /I love to build amazingapps./h1p classNamemb-8 leading-relaxedLorem ipsum dolor sit amet, consectetur adipisicing elit. Quilaborum quasi, incidunt dolore iste nostrum cupiditate voluptas?Laborum, voluptas natus?/pdiv classNameflex justify-centerahref#contactclassNameinline-flex text-white bg-green-500 border-0 py-2 px-6 focus:outline-none hover:bg-green-600 rounded text-lgWork With Me/aahref#projectsclassNameml-4 inline-flex text-gray-400 bg-gray-800 border-0 py-2 px-6 focus:outline-none hover:bg-gray-700 hover:text-white rounded text-lgSee My Past Work/a/div/divdiv classNamelg:max-w-lg lg:w-full md:w-1/2 w-5/6imgclassNameobject-cover object-center roundedaltherosrc./coding.svg//div/div/section);
}对于本部分右侧的图片我使用的 public 文件夹中的一个 svg 文件coding.svg。这个图片只是作为一个临时的占位符我强烈建议你使用你自己的图片。如何构建 Projects 组件我们的项目部分是由一个 section 元素组成id为 prpjects。这将是包含所有项目的图片集。// src/components/Projects.jsimport { CodeIcon } from heroicons/react/solid;
import React from react;
import { projects } from ../data;export default function Projects() {return (section idprojects classNametext-gray-400 bg-gray-900 body-fontdiv classNamecontainer px-5 py-10 mx-auto text-center lg:px-40div classNameflex flex-col w-full mb-20CodeIcon classNamemx-auto inline-block w-10 mb-4 /h1 classNamesm:text-4xl text-3xl font-medium title-font mb-4 text-whiteApps Ive Built/h1p classNamelg:w-2/3 mx-auto leading-relaxed text-baseLorem ipsum, dolor sit amet consectetur adipisicing elit. Explicabofacilis repellat ab cupiditate alias vero aliquid obcaecati quisquamfuga dolore./p/divdiv classNameflex flex-wrap -m-4{projects.map((project) (ahref{project.link}key{project.image}classNamesm:w-1/2 w-100 p-4div classNameflex relativeimgaltgalleryclassNameabsolute inset-0 w-full h-full object-cover object-centersrc{project.image}/div classNamepx-8 py-10 relative z-10 w-full border-4 border-gray-800 bg-gray-900 opacity-0 hover:opacity-100h2 classNametracking-widest text-sm title-font font-medium text-green-400 mb-1{project.subtitle}/h2h1 classNametitle-font text-lg font-medium text-white mb-3{project.title}/h1p classNameleading-relaxed{project.description}/p/div/div/a))}/div/div/section);
}注意我们还将使用库 heroicons/react以便将 SVG 图标写成 React 组件。我们从同一个文件夹中的 data.js 文件导入一个项目数组。在那里我们导出一个对象数组每个对象包含项目的数据。// src/data.jsexport const projects [{title: React Reserve,subtitle: MERN Stack,description:Lorem ipsum dolor sit amet consectetur adipisicing elit. Praesentium dolore rerum laborum iure enim sint nemo omnis voluptate exercitationem eius?,image: ./project-1.gif,link: https://reactbootcamp.com,},{title: React Tracks,subtitle: React and Python,description:Lorem ipsum dolor sit amet consectetur adipisicing elit. Praesentium dolore rerum laborum iure enim sint nemo omnis voluptate exercitationem eius?,image: ./project-2.gif,link: https://reedbarger.com,},{title: DevChat,subtitle: React and Firebase,description:Lorem ipsum dolor sit amet consectetur adipisicing elit. Praesentium dolore rerum laborum iure enim sint nemo omnis voluptate exercitationem eius?,image: ./project-3.gif,link: https://jsbootcamp.com,},{title: Epic Todo App,subtitle: React Hooks,description:Lorem ipsum dolor sit amet consectetur adipisicing elit. Praesentium dolore rerum laborum iure enim sint nemo omnis voluptate exercitationem eius?,image: ./project-4.gif,link: https://pythonbootcamp.com,},
];如何构建 Skills 组件我们在这部分填写自己会的技能和技术。这将包含一个简单的清单列出在我们熟悉的主要工具可用于雇主或客户的项目中。再一次我们将从 data 文件夹导入一个数组。但是这个数组是由字符串组成是我们所知道的技能如 JavaScript、React 和 Node。// src/components/Skills.jsimport { BadgeCheckIcon, ChipIcon } from heroicons/react/solid;
import React from react;
import { skills } from ../data;export default function Skills() {return (section idskillsdiv classNamecontainer px-5 py-10 mx-autodiv classNametext-center mb-20ChipIcon classNamew-10 inline-block mb-4 /h1 classNamesm:text-4xl text-3xl font-medium title-font text-white mb-4Skills amp; Technologies/h1p classNametext-base leading-relaxed xl:w-2/4 lg:w-3/4 mx-autoLorem ipsum dolor sit amet consectetur, adipisicing elit. Nisi sitipsa delectus eum quo voluptas aspernatur accusantium distinctiopossimus est./p/divdiv classNameflex flex-wrap lg:w-4/5 sm:mx-auto sm:mb-2 -mx-2{skills.map((skill) (div key{skill} classNamep-2 sm:w-1/2 w-fulldiv classNamebg-gray-800 rounded flex p-4 h-full items-centerBadgeCheckIcon classNametext-green-400 w-6 h-6 flex-shrink-0 mr-4 /span classNametitle-font font-medium text-white{skill}/span/div/div))}/div/div/section);
}如何构建 Testimonials 组件在 Testimonials 组件中我们将列出一些过去的比较熟悉的客户的推荐信。这些将由几个卡片组成里面有推荐人和推荐人所在的公司。我们将导入一个包含推荐信息的数组里面的对象包含了评价、图片和公司。// src/components/Testimonialsimport React from react;
import { TerminalIcon, UsersIcon } from heroicons/react/solid;
import { testimonials } from ../data;export default function Testimonials() {return (section idtestimonialsdiv classNamecontainer px-5 py-10 mx-auto text-centerUsersIcon classNamew-10 inline-block mb-4 /h1 classNamesm:text-4xl text-3xl font-medium title-font text-white mb-12Client Testimonials/h1div classNameflex flex-wrap m-4{testimonials.map((testimonial) (div classNamep-4 md:w-1/2 w-fulldiv classNameh-full bg-gray-800 bg-opacity-40 p-8 roundedTerminalIcon classNameblock w-8 text-gray-500 mb-4 /p classNameleading-relaxed mb-6{testimonial.quote}/pdiv classNameinline-flex items-centerimgalttestimonialsrc{testimonial.image}classNamew-12 rounded-full flex-shrink-0 object-cover object-center/span classNameflex-grow flex flex-col pl-4span classNametitle-font font-medium text-white{testimonial.name}/spanspan classNametext-gray-500 text-sm uppercase{testimonial.company}/span/span/div/div/div))}/div/div/section);
}如何构建 Contact 组件在登录页的尾部我们将加入联系表单以便潜在的雇主能联系到我们。这个表格包含 3 个输入姓名、电子邮件和输入信息。为了接收这些表格所提交的信息我们将使用 Netlify 表格工具以轻松保存这些信息。// src/components/Contact.jsimport React from react;export default function Contact() {return (section idcontact classNamerelativediv classNamecontainer px-5 py-10 mx-auto flex sm:flex-nowrap flex-wrapdiv classNamelg:w-2/3 md:w-1/2 bg-gray-900 rounded-lg overflow-hidden sm:mr-10 p-10 flex items-end justify-start relativeiframewidth100%height100%titlemapclassNameabsolute inset-0frameBorder{0}marginHeight{0}marginWidth{0}style{{ filter: opacity(0.7) }}srchttps://www.google.com/maps/embed/v1/place?q97warrenstnewyorkcitykeyAIzaSyBFw0Qbyq9zTFTd-tUY6dZWTgaQzuU17R8/div classNamebg-gray-900 relative flex flex-wrap py-6 rounded shadow-mddiv classNamelg:w-1/2 px-6h2 classNametitle-font font-semibold text-white tracking-widest text-xsADDRESS/h2p classNamemt-197 Warren St. br /New York, NY 10007/p/divdiv classNamelg:w-1/2 px-6 mt-4 lg:mt-0h2 classNametitle-font font-semibold text-white tracking-widest text-xsEMAIL/h2a classNametext-indigo-400 leading-relaxedreedbargeremail.com/ah2 classNametitle-font font-semibold text-white tracking-widest text-xs mt-4PHONE/h2p classNameleading-relaxed123-456-7890/p/div/div/divformnetlifynamecontactclassNamelg:w-1/3 md:w-1/2 flex flex-col md:ml-auto w-full md:py-8 mt-8 md:mt-0h2 classNametext-white sm:text-4xl text-3xl mb-1 font-medium title-fontHire Me/h2p classNameleading-relaxed mb-5Lorem ipsum dolor sit amet consectetur, adipisicing elit. Illumsuscipit officia aspernatur veritatis. Asperiores, aliquid?/pdiv classNamerelative mb-4label htmlForname classNameleading-7 text-sm text-gray-400Name/labelinputtypetextidnamenamenameclassNamew-full bg-gray-800 rounded border border-gray-700 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-900 text-base outline-none text-gray-100 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out//divdiv classNamerelative mb-4label htmlForemail classNameleading-7 text-sm text-gray-400Email/labelinputtypeemailidemailnameemailclassNamew-full bg-gray-800 rounded border border-gray-700 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-900 text-base outline-none text-gray-100 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out//divdiv classNamerelative mb-4labelhtmlFormessageclassNameleading-7 text-sm text-gray-400Message/labeltextareaidmessagenamemessageclassNamew-full bg-gray-800 rounded border border-gray-700 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-900 h-32 text-base outline-none text-gray-100 py-1 px-3 resize-none leading-6 transition-colors duration-200 ease-in-out//divbuttontypesubmitclassNametext-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lgSubmit/button/form/div/section);
}如何嵌入 Google Maps 位置在表格的左边我们将一个 Google Maps 嵌入显示我们的所在位置。我们可以在一个在线工具embed-map.com的帮助下这样做。你所要做的事只是输入你的位置并点击Generate HTML code。在给我们生成的代码中不要复制所有的代码只要复制 ifame 中的 src 属性然后替换掉 src 的默认值。向 Netlify 发送任何提交的表单数据Netlify Forms 需要将从静态 HTML 中识别表单。因为我们的 React 应用是由 JavaScript 控制的而不是普通的 HTML 组成所以我们需要在 public 文件夹下的 index.html 文件中添加一个隐藏的表单。!-- public/index.html --!DOCTYPE html
html langenhead!-- head content skipped --/headbodyform namecontact netlify netlify-honeypotbot-field hiddeninput typetext namename /input typeemail nameemail /textarea namemessage/textarea/formnoscriptYou need to enable JavaScript to run this app./noscriptdiv idroot/div/body
/html我们需要隐藏这个表单因为它不需要被用户看到它只需要被Netlify看到。如何从联系表单提交完成上面这些我们将回到 Contact.js。我们将使用 JavaScript 提交这个表单。const [name, setName] React.useState();
const [email, setEmail] React.useState();
const [message, setMessage] React.useState();我们将在 onChange 处理程序的帮助下将用户在每个输入项的信息存储在 state。// src/components/Contact.jsimport React from react;export default function Contact() {const [name, setName] React.useState();const [email, setEmail] React.useState();const [message, setMessage] React.useState();function encode(data) {return Object.keys(data).map((key) encodeURIComponent(key) encodeURIComponent(data[key])).join();}function handleSubmit(e) {e.preventDefault();fetch(/, {method: POST,headers: { Content-Type: application/x-www-form-urlencoded },body: encode({ form-name: contact, name, email, message }),}).then(() alert(Message sent!)).catch((error) alert(error));}return (section idcontact classNamerelativediv classNamecontainer px-5 py-10 mx-auto flex sm:flex-nowrap flex-wrapdiv classNamelg:w-2/3 md:w-1/2 bg-gray-900 rounded-lg overflow-hidden sm:mr-10 p-10 flex items-end justify-start relativeiframewidth100%height100%titlemapclassNameabsolute inset-0frameBorder{0}marginHeight{0}marginWidth{0}style{{ filter: opacity(0.7) }}srchttps://www.google.com/maps/embed/v1/place?q97warrenstnewyorkcitykeyAIzaSyBFw0Qbyq9zTFTd-tUY6dZWTgaQzuU17R8/div classNamebg-gray-900 relative flex flex-wrap py-6 rounded shadow-mddiv classNamelg:w-1/2 px-6h2 classNametitle-font font-semibold text-white tracking-widest text-xsADDRESS/h2p classNamemt-197 Warren St. br /New York, NY 10007/p/divdiv classNamelg:w-1/2 px-6 mt-4 lg:mt-0h2 classNametitle-font font-semibold text-white tracking-widest text-xsEMAIL/h2a classNametext-indigo-400 leading-relaxedreedbargeremail.com/ah2 classNametitle-font font-semibold text-white tracking-widest text-xs mt-4PHONE/h2p classNameleading-relaxed123-456-7890/p/div/div/divformnetlifynamecontactonSubmit{handleSubmit}classNamelg:w-1/3 md:w-1/2 flex flex-col md:ml-auto w-full md:py-8 mt-8 md:mt-0h2 classNametext-white sm:text-4xl text-3xl mb-1 font-medium title-fontHire Me/h2p classNameleading-relaxed mb-5Lorem ipsum dolor sit amet consectetur, adipisicing elit. Illumsuscipit officia aspernatur veritatis. Asperiores, aliquid?/pdiv classNamerelative mb-4label htmlForname classNameleading-7 text-sm text-gray-400Name/labelinputtypetextidnamenamenameclassNamew-full bg-gray-800 rounded border border-gray-700 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-900 text-base outline-none text-gray-100 py-1 px-3 leading-8 transition-colors duration-200 ease-in-outonChange{(e) setName(e.target.value)}//divdiv classNamerelative mb-4label htmlForemail classNameleading-7 text-sm text-gray-400Email/labelinputtypeemailidemailnameemailclassNamew-full bg-gray-800 rounded border border-gray-700 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-900 text-base outline-none text-gray-100 py-1 px-3 leading-8 transition-colors duration-200 ease-in-outonChange{(e) setEmail(e.target.value)}//divdiv classNamerelative mb-4labelhtmlFormessageclassNameleading-7 text-sm text-gray-400Message/labeltextareaidmessagenamemessageclassNamew-full bg-gray-800 rounded border border-gray-700 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-900 h-32 text-base outline-none text-gray-100 py-1 px-3 resize-none leading-6 transition-colors duration-200 ease-in-outonChange{(e) setMessage(e.target.value)}//divbuttontypesubmitclassNametext-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lgSubmit/button/form/div/section);
}正如你在上面看到的我们正在用一个特殊的encode(编码)函数对表单数据进行编码。如何构建 Navbar 组件最后一步是构建我们的 Navbar 组件。// src/components/Navbar.jsimport { ArrowRightIcon } from heroicons/react/solid;
import React from react;export default function Navbar() {return (header classNamebg-gray-800 md:sticky top-0 z-10div classNamecontainer mx-auto flex flex-wrap p-5 flex-col md:flex-row items-centera classNametitle-font font-medium text-white mb-4 md:mb-0a href#about classNameml-3 text-xlReed Barger/a/anav classNamemd:mr-auto md:ml-4 md:py-1 md:pl-4 md:border-l md:border-gray-700 flex flex-wrap items-center text-base justify-centera href#projects classNamemr-5 hover:text-whitePast Work/aa href#skills classNamemr-5 hover:text-whiteSkills/aa href#testimonials classNamemr-5 hover:text-whiteTestimonials/a/navahref#contactclassNameinline-flex items-center bg-gray-800 border-0 py-1 px-3 focus:outline-none hover:bg-gray-700 rounded text-base mt-4 md:mt-0Hire MeArrowRightIcon classNamew-4 h-4 ml-1 //a/div/header);
}如何在较大的设备上将 Navbar 组件在页面的顶部显示我们将使用 md:sticky 类添加到 header 元素。如何部署作品集现在为了使我们的作品集上线我们需要把应用程序推送到 GitHub。一旦你熟悉了这个流程我们可以首先创建一个新的 GitHub 仓库。之后我们将运行 git add .、git commit -m Deploy创建 git 远程然后 git push -u orgin master。一旦我们的项目建立在 GitHub 上我们就可以去 Netlify选择 Choose Site from Git。然后选择 GitHub 作为持续部署并选择我们刚刚推送代码的 GitHub 仓库。之后我们的项目将自动部署到网络上下一步是什么祝贺你你现在可以通过一个在线的作品集应用程序向潜在雇主展示你的所有项目和技能了下一步要做的事设置一个自己的域名最好用你的名字例如 reedbarger.com。由于 Netlify 包含一个 DNS你可以很容易在那里设置一个自己的域名。可以考虑在你的 React 应用程序中添加一个博客向潜在的雇主展示你更多的开发知识。通过个人作品集表达你自己以及你作为开发者的热情所在你将获得成功原文链接https://www.freecodecamp.org/news/build-portfolio-website-react/作者Reed Barger译者luojiyin················· 若川简介 ·················你好我是若川毕业于江西高校。现在是一名前端开发“工程师”。写有《学习源码整体架构系列》20余篇在知乎、掘金收获超百万阅读。从2014年起每年都会写一篇年度总结已经写了7篇点击查看年度总结。同时最近组织了源码共读活动帮助3000前端人学会看源码。公众号愿景帮助5年内前端人走向前列。识别上方二维码加我微信、拉你进源码共读群今日话题略。分享、收藏、点赞、在看我的文章就是对我最大的支持