preface
Before this to rax.js official documents to learn to read a general understanding of the Rax framework, after the actual project practice and familiarity, the following is the source code warehouse of the whole project:
github
gitee
background
Because there is really no practical project tutorial or video about RAx. js framework online (except for fees), I have found a more appropriate React actual project video based on the package of React. Js, “Build a responsive travel website through React, Gatsby, GraphQL”. P】, rax.js + Ts + ESLint simple refactoring, with detailed comments on each page function point.
During this time, I was reading the React official website documents simultaneously, which really made sense by analogy.
Project overview
PC
The mobile terminal
The main directory
Interpret the main contents of the project
. ├ ─ ─ the README. Md ├ ─ ─ package. The json ├ ─ ─ SRC / / home directory │ ├ ─ ─ app. Json │ ├ ─ ─ app. Ts │ ├ ─ ─ assets / / static file directory │ │ ├ ─ ─ images / / picture │ │ │ ├ ─ ─ 1. JPG │ │ │ ├ ─ ─ 2. JPG │ │ │ ├ ─ ─ 21062901. Jpeg │ │ │ ├ ─ ─ 21062902. Jpeg │ │ │ ├ ─ ─ 21063001. Jpeg │ │ │ ├ ─ ─ 3. JPG │ │ │ └ ─ ─ 4. JPG │ │ └ ─ ─ SVG / / navigation bar │ │ └ ─ ─ bar. The SVG │ ├ ─ ─ the components / / head and tail components │ │ ├ ─ ─ Footer │ │ │ ├ ─ ─ Index. The module. The CSS │ │ │ └ ─ ─ index. The TSX │ │ └ ─ ─ the Header │ │ ├ ─ ─ index. The module. The CSS │ │ └ ─ ─ index. The TSX │ ├ ─ ─ config. Ts │ ├ ─ ─ │ ├─ Heavy Metal Exercises // Heavy metal exercises // Heavy metal exercises // Heavy metal exercises Has nothing to do with this project │ │ │ ├ ─ ─ components │ │ │ ├ ─ ─ index. The module. The CSS │ │ │ └ ─ ─ index. The TSX │ │ ├ ─ ─ Email │ │ │ ├ ─ ─ index. The module. The CSS │ │ │ └ ─ ─ index. The TSX │ │ ├ ─ ─ Hero │ │ │ ├ ─ ─ index. The module. The CSS │ │ │ └ ─ ─ index. The TSX │ │ ├ ─ ─ Home / / main page │ │ │ └ ─ ─ index. The TSX │ │ ├ ─ ─ Stats │ │ │ ├ ─ ─ index. The module. The CSS │ │ │ └ ─ ─ index. The TSX │ │ ├ ─ ─ Testimonials │ │ │ ├ ─ ─ index. The module. The CSS │ │ │ └ ─ ─ Index. The TSX │ │ └ ─ ─ Trips │ │ ├ ─ ─ index. The module. The CSS │ │ └ ─ ─ index. The TSX │ ├ ─ ─ typings. Which s / / ts configuration file │ └ ─ ─ utils / / │ ├ ─ index.ts │ ├ ─ ch.txtCopy the code
The project of actual combat
Before the actual project, we need to build the rax.js framework first.
The built-in configuration for personal choice is
App (Build universal application)
Web single-page application
TypeScript
configuration
app.json
The application configures routing information
{
"routes": [{"path": "/"."source": "pages/Home/index"}]."window": {
"title": "Suzuki 🎈"}}Copy the code
global.css
Global Style configuration
/* Global */
* {
font-family: 'Roboto', sans-serif;
margin: 0;
padding: 0;
box-sizing: border-box;
}
a {
color: red;
}
p {
color: #000;
}
.button {
white-space: nowrap;
font-weight: bold;
color: #fff;
outline: none;
border: none;
min-width: 100px;
cursor: pointer;
text-decoration: none;
transition: 0.3s ! important; } .button:hover {transform: translateY(-2px);
}
.buttonPrimary {
background: #f26a2e;
}
.buttonPrimary:hover {
background: #077bf1;
}
.buttonNoPrimary {
background: #077bf1;
}
.buttonNoPrimary:hover {
background: #f26a2e;
}
.buttonBig {
padding: 16px 40px;
font-size: 20px;
}
.buttonNoBig {
padding: 10px 32px;
font-size: 16px;
}
.buttonRound {
border-radius: 50px;
}
.buttonNoRound {
border-radius: 4px;
}
.icon {
font-size: 1.4rem ! important; } .color1 {color: #047bf1;
}
.color2 {
color: #f3a82e;
}
.color3 {
color: #f34f2e;
}
.color4 {
color: #3af576;
}
Copy the code
typings.d.ts
Used by ts to declare file types (such as image types)
declare module '*.module.css' {
const classes: { [key: string] :string };
export default classes;
}
// Configure the TS file suffix
declare module '*.jpg';
declare module '*.jpeg';
Copy the code
page
Home
A container for the entire project
src/pages/Home/
index.tsx
import { createElement } from 'rax';
import View from 'rax-view';
import Header from '@/components/Header';
import Footer from '@/components/Footer';
import Hero from '.. /Hero';
import Trips from '.. /Trips';
import Testimonials from '.. /Testimonials';
import State from '.. /Stats';
import Email from '.. /Email';
function Home() {
// The project container
return (
<View id="home">
<Header />
<main>
<Hero />
<Trips />
<Testimonials />
<State />
<Email />
</main>
<Footer />
</View>
);
}
export default Home;
Copy the code
Header
Item header navigation bar
src/components/Header/
index.tsx
import { createElement, useEffect, useState } from 'rax';
import styles from './index.module.css';
import { routerLink } from '@/utils/index';
function Header() {
/ / navigation
const menuData: {
title: string;
link: string;
}[] = [
{
title: 'Trips'.link: 'trips'}, {title: 'About'.link: 'about'}, {title: 'Careers'.link: 'careers'}, {title: 'Contact'.link: 'contact',},];// Listen for events
const [hasVerticalScrolled, setState] = useState(false);
useEffect(() = > {
window.addEventListener('scroll', bindHandleScroll);
return () = > {
window.removeEventListener('scroll', bindHandleScroll);
};
});
const bindHandleScroll = (event) = > {
// The height of the roll
const scrollTop =
(event.srcElement ? event.srcElement.documentElement.scrollTop : false) | |window.pageYOffset ||
(event.srcElement ? event.srcElement.body.scrollTop : 0);
window.console.log(scrollTop, scrollTop > 100);
setState(() = > scrollTop > 100);
};
return (
/ / header bar
<div className={` ${styles.navContainer} ${hasVerticalScrolled ? styles.navContainer2 :"'} `} >{labels / * * /}<div className={styles.navLink} onClick={()= > routerLink('home')}>
EXPLORIX
</div>{/* Respond back bar icon */}<div className={styles.navBar} />
{/* navMenu */}
<div className={styles.navMenu}>
{menuData.map((item) => {
return (
<div className={styles.navLink} key={item.link} onClick={()= > routerLink(item.link)}>
{item.title}
</div>
);
})}
</div>
{/* navBtn */}
<div className={styles.navBtn}>
<div className="button buttonPrimary buttonNoBig buttonRound" onClick={()= > routerLink('trips')}>
Book a Flight
</div>
</div>
</div>
);
}
export default Header;
Copy the code
index.module.css
.navContainer {
background: transparent;
height: 80rpx;
display: flex;
justify-content: space-evenly;
padding: 0.5 rem calc((100vw - 1300rpx) / 2);
z-index: 100;
position: relative;
}
.navContainer2 {
background: rgba(0.0.0.0.4);
position: sticky;
top: 0;
}
.navLink {
color: #fff;
display: flex;
font-size: 20px;
align-items: center;
text-decoration: none;
padding: 0 2rem;
height: 100%;
cursor: pointer;
}
.navBar {
background: url('.. /.. /assets/svg/bar.svg') no-repeat;
background-size: 1.8 rem;
display: block;
color: #fff;
}
@media screen and (max-width: 768px) {
.navBar {
display: block;
position: absolute;
width: 100%;
height: 100%;
top: 0;
right: 0;
transform: translate(90%.40%); }}.navMenu {
display: flex;
align-items: center;
margin-right: 48rpx;
}
@media screen and (max-width: 768px) {
.navMenu {
display: none; }}.navBtn {
display: flex;
align-items: center;
margin-right: 24px;
}
@media screen and (max-width: 768px) {
.navBtn {
display: none; }}Copy the code
src/utils/
index.ts
Changes the jump of the hash route to a native anchor point jump
/ * * *@description Jump anchor point *@param url* /
export const routerLink = (url: string) = > {
if (url) {
// Find the anchor point
const anchorElement = document.getElementById(url);
// Jump to the anchor point if the corresponding id exists
if (anchorElement) {
anchorElement.scrollIntoView({ block: 'start'.behavior: 'smooth'}); }}};Copy the code
src/assets/svg/
bar.svg
Hero
Giant screen video and project introduction on the home page
src/pages/Hero/
index.tsx
import { createElement } from 'rax';
import { history } from 'rax-app';
import View from 'rax-view';
import styles from './index.module.css';
function Hero() {
return (
// Home screen
<View id="hero">
<div className={styles.HeroContainer}>{/* Background video */}<div className={styles.HeroBg}>
<video src="https://mp4.vjshi.com/2020-11-19/34b1f460a8a9fcc283c4edc8fe43b32f.mp4" type="video/mp4" autoPlay loop muted playsInline className={styles.VideoBg} />
</div>Content of {/ * * /}<div className={styles.HeroContent}>
<div className={styles.HeroItems}>
<h1 className={styles.HeroH1}>On the way to your dreams</h1>
<p className={styles.HeroP}>Out of this world!</p>
<span onClick={()= >History.push ('/trips')} className="button buttonPrimary buttonBig buttonNoRound"</span>
</div>
</div>
</div>
</View>
);
}
export default Hero;
Copy the code
An attempt to import a local background video failed. Asked the corresponding community, the suggestion is to use online links, CDN and other forms of introduction
index.module.css
.HeroContainer {
background: #0c0c0c;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
padding: 0 1rem;
position: relative;
margin-top: -80rpx;
color: #fff;
}
.HeroContainer::before {
content: ' ';
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
z-index: 2;
background: linear-gradient(180deg.rgba(0.0.0.0.2) 0%.rgba(0.0.0.0.6) 100%),
linear-gradient(180deg.rgba(0.0.0.0.2) 0%, transparent 100%);
}
.HeroBg {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
.VideoBg {
width: 100%;
height: 100%;
-o-object-fit: cover;
object-fit: cover;
}
.HeroContent {
z-index: 3;
height: calc(100vh - 80rpx);
max-width: 100%;
padding: 0 calc((100vw - 1300rpx) / 2);
}
.HeroItems {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
height: 100vh;
max-height: 100%;
padding: 0;
color: beige;
line-height: 1.1;
font-weight: bold;
}
.HeroH1 {
font-size: clamp(1.5 rem.6vw.4rem);
margin-bottom: 1.5 rem;
letter-spacing: 3px;
padding: 0 1rem;
}
.HeroP {
font-size: clamp(1rem.3vw.3rem);
margin-bottom: 2rem;
color: #fff;
font-weight: 400;
}
Copy the code
Trips
Travel page
src/pages/Trips/
index.tsx
import { createElement } from 'rax';
import View from 'rax-view';
import Image from 'rax-image';
import styles from './index.module.css';
import { Icon } from '@alifd/meet';
import img1 from '@/assets/images/1.jpg';
import img2 from '@/assets/images/2.jpg';
import img3 from '@/assets/images/3.jpg';
import img4 from '@/assets/images/4.jpg';
function Trips() {
/ / attractions
const trips: {
id: number;
img: any;
alt: string;
name: string;
button: string;
}[] = [
{
id: 1.img: img1,
alt: 'Snow Mountain '.name: 'Snow Mountain '.button: 'View Destination'}, {id: 2.img: img2,
alt: 'Snow Mountain '.name: 'Snow Mountain '.button: 'View Destination'}, {id: 3.img: img3,
alt: 'Aurora BeiJi'.name: 'Aurora BeiJi'.button: 'View Destination'}, {id: 4.img: img4,
alt: 'Church '.name: 'Church '.button: 'View Destination',},];return (
<View id="trips">
<div className={styles.productsContainer}>The title * /} {/ *<div className={styles.productsHeading}>Our Favorite Destinations</div>{/* picture card */}<div className={styles.productsWrapper}>
{trips.map((item) => (
<div key={item.id} className={styles.productCard}>Picture * /} {/ *<Image className={styles.productsImg} source={{ uri: item.img }} alt={item.alt} />Content of {/ * * /}<div className={styles.productInfo}>
<div className={styles.textWrap}>
{/* icon */}
<Icon className="icon" type="heart-filling" />
<div className={styles.productTitle}>
{item.name}
</div>
</div>* /} {/ * button<span className={` ${styles.tripBtn} button buttonPrimary buttonNoBig buttonRound`} >
{item.button}
</span>
</div>
</div>
))}
</div>
</div>
</View>
);
}
export default Trips;
Copy the code
You cannot import images directly in JSX. Use import to import image files, and you need to set the declaration image files because of TS
index.module.css
.productsContainer {
min-height: 100vh;
padding: 5rem calc((100vw - 1300rpx) / 2);
color: #fff;
}
.productsHeading {
font-size: clamp(1.2 rem.5vw.3rem);
text-align: center;
margin-bottom: 5rem;
color: # 000;
}
.productsWrapper {
display: grid;
grid-template-columns: repeat(4.1fr);
grid-gap: 10px;
justify-items: center;
padding: 0 3rem;
}
@media screen and (max-width: 1200px) {
.productsWrapper {
grid-template-columns: 1fr 1fr; }}@media screen and (max-width: 868px) {
.productsWrapper {
display: grid;
grid-template-columns: 1fr; }}.productCard {
line-height: 2;
display: flex;
justify-content: center;
width: 100%;
height: 70vh;
position: relative;
border-radius: 10px;
transition: 0.2 s ease;
}
.productsImg {
height: 100%;
max-width: 100%;
position: absolute;
border-radius: 10px;
filter: brightness(70%);
transition: 0.4 s cubic-bezier(0.075.0.82.0.165.1);
}
.productsImg:hover {
filter: brightness(100%);
}
.productInfo {
display: flex;
flex-direction: column;
align-items: center;
padding: 0 3rem;
}
@media screen and (max-width: 280px) {
.productInfo {
padding: 0 1.5 rem; }}.textWrap {
display: flex;
align-items: center;
position: absolute;
top: 360px;
}
.productTitle {
font-weight: 400;
font-size: 1rem;
margin-left: 0.5 rem;
}
.tripBtn {
position: absolute;
top: 420px;
font-size: 14px;
}
Copy the code
src/assets/images/
Tourism image
Testimonials
Customer evaluation recommendation page
src/pages/Testimonials/
index.tsx
import { createElement } from 'rax';
import View from 'rax-view';
import styles from './index.module.css';
import { Icon } from '@alifd/meet';
import Image from 'rax-image';
import img1 from '@/assets/images/21062901.jpeg';
import img2 from '@/assets/images/21062902.jpeg';
function Testimonials() {
/ / picture
const images: {
id: number;
img: any;
}[] = [
{
id: 1.img: img1,
},
{
id: 2.img: img2,
},
];
return (
// About us
<View id="about">
<div className={styles.testimonialsContainer}>The title * /} {/ *<div className={styles.topLine}>Testimonials</div>
<div className={styles.description}>What People are Saying</div>{/ * * / container}<div className={styles.contentWrapper}>
<div className={styles.columnOne}>{/* Description 1 */}<div className={styles.testimonial}>
<Icon className={` ${styles.color1} ${styles.icon} `}type="success" />
<h3>Ling Mu</h3>
<p>
You have unique gifts and talents that no one else in this world has. Sometimes we feel that we needto
be someone else in order to fit in be a better mother or wife or portray an image that we believele else
will love. No matter how hard you try to be someone else you will never be good enoughYou will do the
best and be the happiest only if you st op living by someone else's standards and startusing your
unique potential to shine like a light in this world
</p>
</div>{/* Description 2 */}<div className={styles.testimonial}>
<Icon className={` ${styles.color2} ${styles.icon} `}type="favorites-filling" />
<h3>Qi Qiu</h3>
<p>
Sooner or later, the time comes when we all must become responsible adults and learn to give up what we
want, so we can choose to do what is right. Of course, a lifetime of responsibility isn't always
easy. And as the years go on, it's a burden that can become too heavy for some to bear. But still
we try to do what is best, what is good. Not only for ourselves, but for those we love. Yes, sooner or
later we must all become responsible adults. No one knows this better than the young.
</p>
</div>
</div>Picture * /} {/ *<div className={styles.columnTwo}>
{images.map((item) => (
<div key={item.id}>
<Image className={styles.Images} source={{ uri: item.img}} / >
</div>
))}
</div>
</div>
</div>
</View>
);
}
export default Testimonials;
Copy the code
You cannot import images directly in JSX. Use import to import image files, and you need to set the declaration image files because of TS
index.module.css
.testimonialsContainer {
width: 100%;
background: #fcfcfc;
color: # 000;
padding: 5rem calc((100vw - 1300rpx) / 2);
height: 100%;
}
.topLine {
color: #077bf1;
font-size: 2rem;
padding-left: 6rem;
margin-bottom: 0.75 rem;
}
.description {
text-align: start;
padding-left: 6rem;
margin-bottom: 4rem;
font-size: clamp(1.5 rem.5vw.2rem);
font-weight: bold;
}
.contentWrapper {
display: grid;
grid-template-columns: 1fr 1fr;
padding: 0 6rem;
}
@media screen and (max-width: 1200px) {
.contentWrapper {
grid-template-columns: 1fr; }}.columnOne {
display: grid;
grid-template-rows: 1fr 1fr;
}
.testimonial {
padding-top: 1rem;
padding-right: 2rem;
}
h3 {
margin-bottom: 1rem;
font-size: 2rem;
font-style: italic;
}
p {
color: #3b3b3b;
font-size: 1.2 rem;
}
.columnTwo {
display: grid;
grid-template-columns: 1fr 1fr;
margin-top: 2rem;
grid-gap: 10rpx;
}
@media screen and (max-width: 1200px) {
.columnTwo {
grid-template-columns: 1fr; }}.Images {
border-radius: 10px;
height: 100%;
width: 100%;
}
.icon {
font-size: 2rem;
margin-bottom: 1rem;
}
.color1 {
color: #3fffa8;
}
.color2 {
color: #f9b19b;
}
Copy the code
src/assets/images/
State
The characteristics of the page
src/pages/State/
index.tsx
import styles from './index.module.css';
import { createElement } from 'rax';
import View from 'rax-view';
import { Icon } from '@alifd/meet';
function State() {
/ / Icon Icon
const statsData: {
id: number;
icon: string;
title: string;
desc: string;
}[] = [
{
id: 1.icon: 'camera'.title: 'Over 100 Destinations'.desc: 'Travel to over 100 unique places'}, {id: 2.icon: 'exit'.title: '1 Million Trips Made'.desc: 'Over 1 million trips completed last year'}, {id: 3.icon: 'dashboard'.title: 'Fastest Support'.desc: 'Access our support team 24/7'}, {id: 4.icon: 'smile'.title: 'Best Deals'.desc: 'We offer the best prices',},];return (
/ / features
<View id="careers">
<div className={styles.statsContainer}>Description * /} {/ *<h1 className={styles.heading}>Why choose us ?</h1>{/* Icon container */}<div className={styles.statsWrapper}>
{statsData.map((item, index) => {
return (
<div className={styles.statsBox} key={item.id}>
<Icon type={item.icon} className={` ${styles.icon} colorThe ${index + 1} `} / >
<p className={styles.title}>{item.title}</p>
<p className={styles.desc}>{item.desc}</p>
</div>
);
})}
</div>
</div>
</View>
);
}
export default State;
Copy the code
The main use of Icon
index.module.css
.testimonialsContainer {
width: 100%;
background: #fcfcfc;
color: # 000;
padding: 5rem calc((100vw - 1300rpx) / 2);
height: 100%;
}
.topLine {
color: #077bf1;
font-size: 2rem;
padding-left: 6rem;
margin-bottom: 0.75 rem;
}
.description {
text-align: start;
padding-left: 6rem;
margin-bottom: 4rem;
font-size: clamp(1.5 rem.5vw.2rem);
font-weight: bold;
}
.contentWrapper {
display: grid;
grid-template-columns: 1fr 1fr;
padding: 0 6rem;
}
@media screen and (max-width: 1200px) {
.contentWrapper {
grid-template-columns: 1fr; }}.columnOne {
display: grid;
grid-template-rows: 1fr 1fr;
}
.testimonial {
padding-top: 1rem;
padding-right: 2rem;
}
h3 {
margin-bottom: 1rem;
font-size: 2rem;
font-style: italic;
}
p {
color: #3b3b3b;
font-size: 1.2 rem;
}
.columnTwo {
display: grid;
grid-template-columns: 1fr 1fr;
margin-top: 2rem;
grid-gap: 10rpx;
}
@media screen and (max-width: 1200px) {
.columnTwo {
grid-template-columns: 1fr; }}.Images {
border-radius: 10px;
height: 100%;
width: 100%;
}
.icon {
font-size: 2rem;
margin-bottom: 1rem;
}
.color1 {
color: #3fffa8;
}
.color2 {
color: #f9b19b;
}
Copy the code
src/assets/images/
Email page
src/pages/Email/
index.tsx
import { createElement } from 'rax';
import View from 'rax-view';
import styles from './index.module.css';
function Email() {
return (
/ / email
<View>{/* container + image */}<div className={styles.emailContainer}>
<div className={styles.emailContent}>Description * /} {/ *<h1 className={styles.emailH1}>Get Access to Exclusive Offers</h1>
<p className={styles.emailP}>Sign up for your newsletter below to get $100 off your first trip!</p>{/* form */}<div className={styles.formWrap}>
<label htmlFor="email">
<input type="email" placeholder="Please enter your email address." id="email" />
</label>
<span className="button buttonPrimary buttonBig buttonRound">registered</span>
</div>
</div>
</div>
</View>
);
}
export default Email;
Copy the code
index.module.css
.emailContainer {
background: linear-gradient(
180deg.rgba(0.0.0.0.5) 0%.rgba(0.0.0.0.5) 35%.rgba(0.0.0.0.1) 100%
),
url('.. /.. /assets/images/21063001.jpeg') no-repeat center;
background-size: cover;
height: 650px;
width: 100%;
padding: 5rem calc((100vw - 1300px) / 2);
color: #fff;
display: flex;
justify-content: center;
align-items: center;
}
.emailContent {
display: flex;
flex-direction: column;
align-items: center;
}
.emailH1 {
text-align: center;
margin-bottom: 1rem;
font-size: clamp(1rem.5vw.3rem);
padding: 0 1rem;
}
.emailP {
text-align: center;
font-size: clamp(1rem.2.5 vw.1.5 rem);
padding: 0 1rem;
margin-bottom: 2rem;
color: #fff;
}
form {
z-index: 10;
}
input {
padding: 1rem 1.5 rem;
outline: none;
width: 450px;
height: 60px;
border-radius: 50px;
border: none;
margin-right: 1rem;
}
@media screen and (max-width: 768px) {
.formWrap {
display: flex;
flex-direction: column;
padding: 0 1rem;
}
input {
margin-bottom: 1rem;
width: 100%;
margin-right: 0; }}@media screen and (max-width: 768px) {
.button {
width: 100%;
min-width: 450px; }}Copy the code
src/assets/images/
Email pictures
Footer
Item bottom bar
src/components/Footer/
index.tsx
import { createElement } from 'rax';
import View from 'rax-view';
import styles from './index.module.css';
function Footer() {
return (
/ / at the bottom of the column
<View id="contact">
<div className={styles.footerContainer}>{/* First column */}<div className={styles.footerLinkWrapper}>{labels / * * /}<div className={styles.footerDesc}>
<h1>Expel</h1>
<p>We strive to create the best experiences for our customers</p>
</div>
<div className={styles.footerLinkItems}>
<h2 className={styles.footerLinkTitle}>Contact us</h2>
<div className={styles.footerLink}>
Contact
</div>
<div className={styles.footerLink}>
Support
</div>
<div className={styles.footerLink}>
Destinations
</div>
<div className={styles.footerLink}>
Sponsorships
</div>
</div>
</div>{/* Second column */}<div className={styles.footerLinkWrapper}>
<div className={styles.footerLinkItems}>
<h2 className={styles.footerLinkTitle}>audio</h2>
<div className={styles.footerLink}>
Submit Video
</div>
<div className={styles.footerLink}>
Ambassadors
</div>
<div className={styles.footerLink}>
Agency
</div>
<div className={styles.footerLink}>
Influencer
</div>
</div>
<div className={styles.footerLinkItems}>
<h2 className={styles.footerLinkTitle}>Content of the community</h2>
<div className={styles.footerLink}>blog</div>
<div className={styles.footerLink}>The Denver nuggets</div>
<div className={styles.footerLink}>zhihu</div>
<div className={styles.footerLink}>
WeChat
</div>
</div>
</div>
</div>
</View>
);
}
export default Footer;
Copy the code
index.module.css
.footerContainer {
padding: 5rem calc((100vw - 1100px) / 2);
display: grid;
grid-template-columns: repeat(2.1fr);
color: # 000;
background: #fafafb;
font-size: 14px;
}
.footerDesc {
padding: 0 2rem;
}
.footerDesc h1 {
margin-bottom: 3rem;
color: #f26a2e;
}
@media screen and (max-width: 400px) {
.footerDesc {
padding: 1rem; }}.footerLinkWrapper {
display: grid;
grid-template-columns: repeat(2.1fr);
}
@media screen and (max-width: 820px) {
.footerLinkWrapper {
grid-template-columns: 1fr; }}.footerLinkItems {
display: flex;
flex-direction: column;
align-items: flex-start;
padding: 1rem 2rem;
}
@media screen and (max-width: 400px) {
.footerLinkItems {
padding: 1rem; }}.footerLinkTitle {
font-size: 18px;
margin-bottom: 16px;
}
.footerLink {
text-decoration: none;
margin-bottom: 0.5 rem;
font-size: 16px;
color: #3d3d4e;
}
.footerLink:hover {
color: #f26a2e;
transition: 0.3 s ease-out;
}
Copy the code
After the speech
The final project
When the above content is completed, the final display effect of the project will be carried out again:
PC
mobile
The video tutorial technology stack is React, Gatsby and GraphQL. During this period, I used some skills to refactor Rax for this project, and some React peripheral plug-ins were also replaced with the Rax official website document examples.
During this period, I was familiar with JSX syntax, partial Hooks use, TS syntax and the basic content of Rax. But the weaknesses lie in several areas:
- Communication of components, data flow, etc
- Back-end network communication of Rax
- Testing (which I am very poor at)
- Build the deployment
In my opinion, the following areas can be optimized:
- The CSS to sass
- The transition of anchor points should be made using tranforms, etc., which have been tried but not well implemented
- Home should be turned into a real layout
- Further modular components
- Package builds (weak)
In the end, I feel that to learn Rax well, I need to lay a good foundation of React. Although there are many things I can understand by analogy, I still need to study it carefully. After learning it, I need to be able to use it in appropriate scenarios.
If you want the source code below is the warehouse address ~ save rolling to the beginning of github Gitee if there are improvements please guide one or two oh! Thank~