为了账号安全,请及时绑定邮箱和手机立即绑定

前端全栈入门:一步一步学起来

概述

本文详细介绍了前端全栈入门所需的基础知识,包括HTML、CSS、JavaScript、Vue.js或React.js以及Node.js等关键技术。通过多个示例,帮助读者理解和掌握这些技术的具体应用。此外,文章还涵盖了项目实战和部署上线的全过程,旨在为前端全栈入门提供全面的指导。

HTML与CSS基础
HTML标签入门

HTML是超文本标记语言(HyperText Markup Language)的缩写,它是用来设计网页的标准标记语言。HTML文档由一系列的标签组成,这些标签定义了文档的结构和内容。HTML标签通常由一对尖括号包围的标签名组成。例如:

<!DOCTYPE html>
<html>
<head>
    <title>示例页面</title>
</head>
<body>
    <h1>欢迎来到我的网站</h1>
    <p>这是我的第一个网页。</p>
</body>
</html>

基本标签

  • <html>: 定义整个HTML文档的根元素。
  • <head>: 包含文档的元数据(如标题、字符集定义等)。
  • <title>: 定义文档的标题,显示在浏览器的标题栏或标签页上。
  • <body>: 包含文档的所有内容(如文本、图片、表格、列表等)。
  • <h1> - <h6>: 定义标题,从大到小,<h1>是最主要的标题。
  • <p>: 定义段落。
  • <a>: 定义超链接,用于链接到其他页面或文件。
  • <img>: 插入图片,需要指定src属性来指定图片的URL。
  • <ul> - <ol>: 分别定义无序列表和有序列表。
  • <li>: 定义列表中的列表项。

示例:

<!DOCTYPE html>
<html>
<head>
    <title>HTML示例</title>
</head>
<body>
    <h1>欢迎来到我的网站</h1>
    <p>这是我的第一个网页。</p>
    <a href="https://www.imooc.com/">慕课网</a>
    <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="https://example.com/logo.png" alt="网站标志">
    <ul>
        <li>列表项1</li>
        <li>列表项2</li>
    </ul>
    <ol>
        <li>有序列表项1</li>
        <li>有序列表项2</li>
    </ol>
</body>
</html>
CSS样式基础

CSS(层叠样式表)用于描述HTML元素的样式。它使网页具有更丰富的样式和动态效果。CSS可以以内联方式、内部方式或外部方式使用。内部CSS样式表通常放在<head>标签内,外部CSS样式表则通过<link>标签引入。

内联样式

在HTML元素中直接定义样式,使用style属性。

<!DOCTYPE html>
<html>
<head>
    <title>内联样式示例</title>
</head>
<body>
    <h1 style="color: blue;">欢迎来到我的网站</h1>
    <p style="font-size: 20px;">这是我的第一个网页。</p>
</body>
</html>

内部样式表

<head>标签内定义<style>标签,将CSS代码写在<style>标签内。

<!DOCTYPE html>
<html>
<head>
    <title>内部样式表示例</title>
    <style>
        h1 {
            color: blue;
        }
        p {
            font-size: 20px;
        }
    </style>
</head>
<body>
    <h1>欢迎来到我的网站</h1>
    <p>这是我的第一个网页。</p>
</body>
</html>

外部样式表

使用<link>标签引用外部CSS文件。

<!DOCTYPE html>
<html>
<head>
    <title>外部样式表示例</title>
    <link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
    <h1>欢迎来到我的网站</h1>
    <p>这是我的第一个网页。</p>
</body>
</html>

styles.css文件中:

h1 {
    color: blue;
}
p {
    font-size: 20px;
}
布局与样式实战

基本布局

使用CSS的display属性和flex布局,可以实现更为灵活的页面布局。

<!DOCTYPE html>
<html>
<head>
    <title>基本布局示例</title>
    <style>
        .container {
            display: flex;
            justify-content: space-between;
            padding: 20px;
            border: 1px solid #ccc;
        }
        .box {
            width: 30%;
            height: 100px;
            background-color: #eee;
            margin: 10px;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
    </div>
</body>
</html>

响应式布局

使用媒体查询,可以让网页在不同设备上自适应布局。

<!DOCTYPE html>
<html>
<head>
    <title>响应式布局示例</title>
    <style>
        @media (max-width: 600px) {
            .container {
                flex-direction: column;
            }
            .box {
                width: 100%;
            }
        }
        .container {
            display: flex;
            justify-content: space-between;
            padding: 20px;
            border: 1px solid #ccc;
        }
        .box {
            width: 30%;
            height: 100px;
            background-color: #eee;
            margin: 10px;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
    </div>
</body>
</html>

通过上述示例,可以学习并实践基本的HTML和CSS布局。掌握这些基础技能后,就可以开始构建更加复杂的网页了。

JavaScript入门
JavaScript基础语法

JavaScript是一种用于添加动态性和交互性的客户端编程语言。它直接在Web浏览器中执行,使得网页具有交互性和响应性。

变量与类型

在JavaScript中,可以使用varletconst来声明变量,还可以使用typeof来检查变量类型。

var number = 42; // number类型
let string = "Hello, World!"; // string类型
const boolean = true; // boolean类型
const nullValue = null; // null类型
const undefinedValue = undefined; // undefined类型
const object = {}; // object类型
const array = [1, 2, 3]; // array类型
const functionType = function() {}; // function类型
const symbol = Symbol("name"); // symbol类型

函数

JavaScript函数是可执行的一段代码。函数可以有参数和返回值。

function add(a, b) {
    return a + b;
}

const result = add(10, 20);
console.log(result); // 输出30

条件语句

JavaScript中的条件语句包括ifelse ifelse

const age = 20;

if (age < 18) {
    console.log("未成年");
} else if (age >= 18 && age < 60) {
    console.log("成年");
} else {
    console.log("老年");
}

循环

JavaScript中的循环语句有forwhiledo...while

for (let i = 0; i < 5; i++) {
    console.log(i);
}

let x = 0;
while (x < 5) {
    console.log(x);
    x++;
}

let y = 0;
do {
    console.log(y);
    y++;
} while (y < 5);

数组操作

数组是JavaScript中一种常用的数据结构。

const fruits = ["apple", "banana", "cherry"];
console.log(fruits.length); // 输出3

fruits.push("orange"); // 添加元素
console.log(fruits); // ["apple", "banana", "cherry", "orange"]

fruits.pop(); // 删除最后一个元素
console.log(fruits); // ["apple", "banana", "cherry"]

console.log(fruits[1]); // 输出"banana"

对象操作

对象用于存储键值对。

const person = {
    name: "John",
    age: 30,
    sayHello: function() {
        return "Hello, " + this.name;
    }
};

console.log(person.name); // 输出"John"
console.log(person.sayHello()); // 输出"Hello, John"

通过这些基本语法的示例,可以了解JavaScript的基本构成和使用方法。

DOM操作与事件监听

DOM操作

Document Object Model(DOM)是HTML和XML文档的结构化表示。DOM提供了一种方法来访问和操作文档内容。通过JavaScript可以动态地更新网页内容。

<!DOCTYPE html>
<html>
<head>
    <title>DOM操作示例</title>
</head>
<body>
    <h1 id="title">欢迎来到我的网站</h1>
    <button id="changeText">更改文本</button>
    <script>
        const title = document.getElementById("title");
        const button = document.getElementById("changeText");

        button.addEventListener("click", function() {
            title.textContent = "新的标题";
        });
    </script>
</body>
</html>

事件监听

事件监听是JavaScript中非常重要的功能,它使网页可以对用户的动作做出响应。

<!DOCTYPE html>
<html>
<head>
    <title>事件监听示例</title>
</head>
<body>
    <button id="myButton">点击我</button>
    <script>
        const button = document.getElementById("myButton");

        button.addEventListener("click", function() {
            alert("按钮被点击了");
        });
    </script>
</body>
</html>

通过这些示例,可以学习如何使用JavaScript操作DOM和监听事件。

常见算法与数据结构简介

常见算法

算法是解决问题的一系列步骤。常见的算法包括排序算法和搜索算法。

排序算法:冒泡排序

冒泡排序是通过比较相邻元素,将较大的元素逐渐“沉底”。

function bubbleSort(arr) {
    let n = arr.length;
    for (let i = 0; i < n - 1; i++) {
        for (let j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
            }
        }
    }
    return arr;
}

const numbers = [64, 34, 25, 12, 22, 11, 90];
console.log(bubbleSort(numbers)); // 输出[11, 12, 22, 25, 34, 64, 90]

搜索算法:二分查找

二分查找是一种在有序数组中查找特定元素的技术。

function binarySearch(arr, target) {
    let start = 0;
    let end = arr.length - 1;

    while (start <= end) {
        let mid = Math.floor((start + end) / 2);
        if (arr[mid] === target) {
            return mid;
        } else if (arr[mid] < target) {
            start = mid + 1;
        } else {
            end = mid - 1;
        }
    }
    return -1;
}

const sortedNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log(binarySearch(sortedNumbers, 7)); // 输出6

常见数据结构

数组

数组是一种存储多个元素的数据结构。

const numbers = [1, 2, 3, 4, 5];
console.log(numbers.length); // 输出5
console.log(numbers[1]); // 输出2

链表

链表是一种链式存储的数据结构,每个元素(节点)包含数据和指向下一个节点的指针。

class Node {
    constructor(data, next = null) {
        this.data = data;
        this.next = next;
    }
}

class LinkedList {
    constructor() {
        this.head = null;
    }
    add(data) {
        if (!this.head) {
            this.head = new Node(data);
        } else {
            let current = this.head;
            while (current.next) {
                current = current.next;
            }
            current.next = new Node(data);
        }
    }
    print() {
        let current = this.head;
        while (current) {
            console.log(current.data);
            current = current.next;
        }
    }
}

const list = new LinkedList();
list.add(1);
list.add(2);
list.add(3);
list.print(); // 输出1, 2, 3

通过上述示例,可以学习并理解常见的算法和数据结构。

前端框架初探
Vue.js或React.js基础介绍

Vue.js简介

Vue.js 是一个渐进式 JavaScript 框架,用于构建用户界面。它非常适合构建单页面应用(SPA)。

Vue.js基础

Vue.js的核心概念是组件,通过组件化的方式构建界面。

<!DOCTYPE html>
<html>
<head>
    <title>Vue.js基础示例</title>
    <script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<body>
    <div id="app">
        <h1>{{ message }}</h1>
        <button v-on:click="changeMessage">更改文本</button>
    </div>
    <script>
        new Vue({
            el: '#app',
            data: {
                message: 'Hello Vue'
            },
            methods: {
                changeMessage() {
                    this.message = '文本已更改';
                }
            }
        });
    </script>
</body>
</html>

React.js简介

React.js 是由Facebook开发和维护的一个用于构建用户界面的JavaScript库。它也擅长构建单页面应用(SPA)。

React.js基础

React.js的核心概念也是组件,通过组件化的方式构建界面。

<!DOCTYPE html>
<html>
<head>
    <title>React.js基础示例</title>
    <script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
</head>
<body>
    <div id="root"></div>
    <script>
        const root = ReactDOM.createRoot(document.getElementById('root'));
        root.render(
            <button onClick={() => alert("按钮被点击了")}>点击我</button>
        );
    </script>
</body>
</html>

通过这些示例,可以了解Vue.js和React.js的基本使用方式,为后续项目实践打下基础。

框架项目实践

项目结构

一个典型的Vue.js或React.js项目结构如下:

my-project/
├── public/
│   ├── index.html
├── src/
│   ├── main.js
│   ├── App.vue (for Vue.js) or App.js (for React.js)
├── package.json
└── .gitignore

创建Vue.js项目

使用Vue CLI创建Vue.js项目。

npm install -g @vue/cli
vue create my-vue-app
cd my-vue-app
npm run serve

创建React.js项目

使用Create React App创建React.js项目。

npx create-react-app my-react-app
cd my-react-app
npm start

组件化开发

组件化是Vue.js和React.js的核心,通过组件化的方式构建复杂的界面。

Vue.js组件示例

<template>
    <div>
        <h1>{{ message }}</h1>
        <button @click="changeMessage">更改文本</button>
    </div>
</template>
<script>
export default {
    data() {
        return {
            message: 'Hello Vue'
        };
    },
    methods: {
        changeMessage() {
            this.message = '文本已更改';
        }
    }
};
</script>

React.js组件示例

import React from 'react';
import './App.css';

function App() {
    const [message, setMessage] = React.useState('Hello React');

    const changeMessage = () => {
        setMessage('文本已更改');
    };

    return (
        <div>
            <h1>{message}</h1>
            <button onClick={changeMessage}>更改文本</button>
        </div>
    );
}

export default App;

通过这些示例,可以实践Vue.js和React.js的组件化开发。

基本后端技术简介
Node.js基础

Node.js 是一个基于Chrome V8引擎的JavaScript运行环境。它允许使用JavaScript来编写服务器端代码,并且可以通过npm管理依赖包。

安装Node.js

可以在Node.js官网下载并安装Node.js,安装完成后可以通过node -vnpm -v来检查是否安装成功。

创建一个简单的Node.js应用

创建一个简单的HTTP服务器。

mkdir my-node-app
cd my-node-app
npm init -y
npm install express

index.js中创建一个简单的服务器:

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
    res.send('Hello World!');
});

app.listen(port, () => {
    console.log(`App running on http://localhost:${port}`);
});

运行服务器:

node index.js

使用Express框架

Express是一个基于Node.js的Web应用框架。它可以快速搭建Web应用,支持中间件、路由、模板引擎等功能。

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
    res.send('Hello World!');
});

app.listen(port, () => {
    console.log(`App running on http://localhost:${port}`);
});

通过上述示例,可以学习并实践Node.js的基础应用。

Express框架入门

创建一个Express应用

使用Express创建一个简单的应用。

mkdir my-express-app
cd my-express-app
npm init -y
npm install express

index.js中创建一个简单的Express应用:

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
    res.send('Hello World!');
});

app.listen(port, () => {
    console.log(`App running on http://localhost:${port}`);
});

运行应用:

node index.js

路由

路由用于定义应用的URL结构和处理相应的HTTP请求。

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
    res.send('Hello World!');
});

app.get('/users', (req, res) => {
    res.send('User List');
});

app.listen(port, () => {
    console.log(`App running on http://localhost:${port}`);
});

中间件

中间件用于处理应用中的HTTP请求。例如,可以使用中间件来处理请求头、请求体等。

const express = require('express');
const app = express();
const port = 3000;

app.use((req, res, next) => {
    res.setHeader('Access-Control-Allow-Origin', '*');
    next();
});

app.get('/', (req, res) => {
    res.send('Hello World!');
});

app.listen(port, () => {
    console.log(`App running on http://localhost:${port}`);
});

通过这些示例,可以学习并实践Express框架的基本使用方法。

项目实战
小型项目案例分析

功能需求

假设要创建一个简单的待办事项(To-Do List)应用程序,该应用程序具有添加、删除、编辑和完成待办事项的功能。

功能实现

创建前端页面

使用HTML、CSS和JavaScript创建待办事项列表的界面。

<!DOCTYPE html>
<html>
<head>
    <title>To-Do List</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #f0f0f0;
        }
        .container {
            max-width: 600px;
            margin: 40px auto;
            background-color: white;
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }
        h1 {
            text-align: center;
            margin-bottom: 20px;
        }
        .input-group {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
        }
        .input-group input {
            flex: 1;
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            margin-right: 10px;
        }
        .input-group button {
            padding: 10px;
            border: none;
            background-color: #007bff;
            color: white;
            border-radius: 5px;
            cursor: pointer;
        }
        .input-group button:hover {
            background-color: #0056b3;
        }
        .list-item {
            background-color: #f9f9f9;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 5px;
            margin-bottom: 10px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .list-item.completed {
            text-decoration: line-through;
            background-color: #e5e5e5;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>待办事项列表</h1>
        <div class="input-group">
            <input type="text" id="new-task" placeholder="新待办事项...">
            <button onclick="addTask()">添加</button>
        </div>
        <ul id="task-list"></ul>
    </div>
    <script>
        const taskList = document.getElementById('task-list');
        let nextId = 1;

        function addTask() {
            const taskInput = document.getElementById('new-task');
            const taskText = taskInput.value.trim();
            if (taskText === '') return;

            const li = document.createElement('li');
            li.className = 'list-item';
            li.id = `task-${nextId}`;
            li.textContent = taskText;
            li.completed = false;

            li.addEventListener('click', () => {
                li.classList.toggle('completed');
                li.completed = !li.completed;
            });

            li.addEventListener('contextmenu', (event) => {
                event.preventDefault();
                taskList.removeChild(li);
            });

            taskList.appendChild(li);
            taskInput.value = '';
            nextId++;
        }
    </script>
</body>
</html>

创建后端API

使用Express创建一个简单的RESTful API来处理待办事项的增删改查操作。

mkdir my-todo-app
cd my-todo-app
npm init -y
npm install express

index.js中创建API:

const express = require('express');
const app = express();
const port = 3001;

const todos = [];

app.use(express.json());

app.get('/todos', (req, res) => {
    res.json(todos);
});

app.post('/todos', (req, res) => {
    const newTodo = {
        id: Date.now(),
        text: req.body.text,
        completed: false
    };
    todos.push(newTodo);
    res.status(201).json(newTodo);
});

app.put('/todos/:id', (req, res) => {
    const todoId = parseInt(req.params.id);
    const todoIndex = todos.findIndex(todo => todo.id === todoId);
    if (todoIndex === -1) return res.status(404).json({ message: '待办事项未找到' });

    const updatedTodo = {
        ...todos[todoIndex],
        completed: req.body.completed
    };
    todos[todoIndex] = updatedTodo;
    res.json(updatedTodo);
});

app.delete('/todos/:id', (req, res) => {
    const todoId = parseInt(req.params.id);
    const todoIndex = todos.findIndex(todo => todo.id === todoId);
    if (todoIndex === -1) return res.status(404).json({ message: '待办事项未找到' });

    const deletedTodo = todos.splice(todoIndex, 1)[0];
    res.json(deletedTodo);
});

app.listen(port, () => {
    console.log(`App running on http://localhost:${port}`);
});

运行API:

node index.js

前端与后端集成

在前端页面中通过JavaScript调用后端API来实现待办事项的增删改查操作。

const taskList = document.getElementById('task-list');
const nextId = 1;

function addTask() {
    const taskInput = document.getElementById('new-task');
    const taskText = taskInput.value.trim();
    if (taskText === '') return;

    fetch('/todos', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ text: taskText })
    })
    .then(response => response.json())
    .then(data => {
        const li = document.createElement('li');
        li.className = 'list-item';
        li.textContent = data.text;
        li.completed = data.completed;
        li.id = `task-${data.id}`;

        li.addEventListener('click', () => {
            li.classList.toggle('completed');
            fetch(`/todos/${data.id}`, {
                method: 'PUT',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ completed: li.completed })
            });
        });

        li.addEventListener('contextmenu', (event) => {
            event.preventDefault();
            fetch(`/todos/${data.id}`, { method: 'DELETE' });
            li.remove();
        });

        taskList.appendChild(li);
        taskInput.value = '';
    });
}

通过这个示例,可以学习并实践从需求分析到实现的完整过程。

项目部署与上线

前端部署

使用静态文件服务器

可以使用静态文件服务器如http-server来部署前端静态文件。

npm install -g http-server
http-server ./dist -p 8080

使用CDN

将前端静态文件上传到CDN,如阿里云CDN,通过域名访问。

后端部署

使用Docker

使用Docker构建和部署后端应用。

docker build -t my-todo-app .
docker run -p 3001:3001 my-todo-app

使用云服务

将后端应用部署到云服务,如阿里云ECS。

上线

完成部署后,通过域名访问前端和后端应用,实现上线。

通过这些步骤,可以学习并实践项目部署与上线的完整过程。

常用开发工具与调试技巧
开发环境搭建

安装Node.js和npm

在Mac、Windows或Linux上安装Node.js和npm。

# macOS
brew install node

# Windows
https://nodejs.org/download/release/latest-v14.x/node-v14.x.x-win-x64.zip

# Linux
sudo apt-get install nodejs npm

安装Vue.js或React.js开发环境

Vue.js

使用Vue CLI创建Vue.js项目。

npm install -g @vue/cli
vue create my-vue-app

React.js

使用Create React App创建React.js项目。

npx create-react-app my-react-app
常用调试工具使用

Chrome DevTools

Chrome DevTools是一个强大的浏览器调试工具,可以帮助开发者调试前端代码。

使用步骤

  1. 打开Chrome浏览器,右键点击页面,选择“检查”。
  2. 在Elements面板中查看和修改HTML、CSS和JavaScript。
  3. 在Console面板中查看和调试JavaScript代码。

示例

在Console面板中输入以下代码调试:

console.log(document.title);
document.title = "调试页面";
console.log(document.title);

Node.js调试

使用Node.js内置的--inspect选项进行调试。

node --inspect app.js

在Chrome浏览器中打开chrome://inspect页面,点击“打开专用调试器窗口”。

使用WebStorm或其他IDE

WebStorm或其他IDE提供了丰富的调试功能,可以方便地调试JavaScript代码。

使用步骤

  1. 在项目中设置断点。
  2. 启动调试模式,运行应用。
  3. 在调试面板中查看和修改变量值。

通过这些示例,可以学习并实践常用开发工具的使用方法。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消