手机版
扫描查看手机站
首页 > 文章 > 站长收藏 > 正文

第三课,以博客为例配置strapi后端与next.js对接

时间:2025-03-14 22:33:36来源:525游



Strapi 后端:
已安装并运行 Strapi(http://localhost:1337)。

已创建 articles 内容类型,包含字段:title(Text)、content(Rich Text)、slug(Text,唯一,选填,用于 SEO 优化)。

已配置好权限:Articles 的 find 和 findOne 权限设置为公开,create 权限需要认证。

示例数据:id: 4, documentId: "nbedxv11g6sdbxvnsdjxs48n", title: "hello world,test2", content: [...]。

Next.js 前端:
已创建 Next.js 项目(位于 C:\Node\test-example\packages\website)。

已安装必要的依赖:axios。


下面我们来操作具体的执行步骤

1. 安装 axios

cd C:\Node\test-example\packages\website

安装 axios  npm install axios  

安装后,检查 node_modules/axios 是否存在。

确认 package.json 中的 dependencies 包含:


"dependencies": {
  "axios": "^1.8.3",
  "next": "15.2.1",
  "react": "^19.0.0",
  "react-dom": "^19.0.0"
}


2、在website 目录下创建以下文件夹和文件:


win10创建文件夹命令符:



# 创建目录
mkdir app\articles app\articles\[id] app\login app\register app\create-article components context utils

# 创建文件
echo. > app\articles\[id]\page.js
echo. > app\login\page.js
echo. > app\register\page.js
echo. > app\create-article\page.js
echo. > components\AuthWrapper.js
echo. > components\Navbar.js
echo. > context\AuthContext.js
echo. > utils\api.js
echo. > next.config.mjs

运行上述命令后,目录结构应与第 1 步描述一致。app/layout.js 和 app/page.js 由 Next.js 自动生成,其他文件已手动创建。

现在整个目录,应该是下面这样的


test-example/packages/website/
├── app/
│   ├── articles/
│   │   ├── [id]/
│   │   │   └── page.js        # 文章详情页面,动态路由,显示具体文章内容
│   ├── login/
│   │   └── page.js            # 登录页面,处理用户登录
│   ├── register/
│   │   └── page.js            # 注册页面,处理用户注册
│   ├── create-article/
│   │   └── page.js            # 创建文章页面,处理文章发布
│   ├── layout.js              # 根布局文件,包含全局导航
│   └── page.js                # 首页,显示文章列表
├── components/                # 组件目录
│   ├── AuthWrapper.js         # 认证包装组件,提供 AuthContext
│   └── Navbar.js              # 导航组件,动态显示导航链接
├── context/                   # 上下文目录(新建)
│   └── AuthContext.js         # 认证上下文,管理用户状态
├── utils/                     # 工具函数目录
│   └── api.js                 # API 请求工具,封装与 Strapi 的交互
├── public/                    # 静态资源目录(Next.js 默认生成)
│   ├── favicon.ico
│   └── ...
├── styles/                    # 样式目录(Next.js 默认生成)
│   ├── globals.css            # 全局样式
│   └── Home.module.css        # 模块化样式(可选)
├── package.json               # 项目依赖和脚本
├── next.config.mjs            # Next.js 配置文件(新建)
└── README.md                  # 项目说明

文件说明


app/page.js:首页,显示文章列表,调用 getArticles 获取数据。

app/articles/[id]/page.js:文章详情页,动态路由,根据 documentId 获取具体文章。

app/login/page.js:登录页面,处理用户登录。

app/register/page.js:注册页面,处理用户注册。

app/create-article/page.js:创建文章页面,允许登录用户发布文章。

app/layout.js:根布局文件,包含全局导航,使用 AuthWrapper 和 Navbar 组件。

components/AuthWrapper.js:认证包装组件,提供 AuthContext。

components/Navbar.js(新建):导航组件,动态渲染导航链接。

context/AuthContext.js(新建):认证上下文,管理用户登录状态和 token。

utils/api.js:封装 API 请求,与 Strapi 后端交互。

styles/globals.css:全局样式,简单美化页面。

next.config.mjs(新建):Next.js 配置文件,调整配置以支持项目运行。






3. 具体新建文件内容、作用和功能说明

3.1 app/layout.js

作用:根布局文件,定义全局布局,包含导航。


import AuthWrapper from '../components/AuthWrapper';
import Navbar from '../components/Navbar';
import '../styles/globals.css';

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <AuthWrapper>
          <Navbar />
          {children}
        </AuthWrapper>
      </body>
    </html>
  );
}

功能说明:
使用 AuthWrapper 组件提供认证上下文。使用 Navbar 组件渲染导航栏。引入全局样式 globals.css。




3.2 app/page.js
作用:首页,显示文章列表


'use client';
import { useEffect, useState } from 'react';
import Link from 'next/link';
import { getArticles } from '../utils/api';

export default function Home() {
  const [articles, setArticles] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchArticles = async () => {
      try {
        const response = await getArticles();
        console.log('Full API Response:', response);
        console.log('Response Data:', response.data);
        const articlesData = response.data?.data || response.data; // 处理嵌套
        if (Array.isArray(articlesData)) {
          setArticles(articlesData);
        } else {
          setArticles([]);
          setError('No articles data found in API response');
        }
      } catch (err) {
        console.error('Fetch Articles Error:', err);
        setError('Failed to fetch articles');
        setArticles([]);
      } finally {
        setIsLoading(false);
      }
    };
    fetchArticles();
  }, []);

  if (isLoading) {
    return <div className="container">Loading...</div>;
  }

  if (error) {
    return <div className="container">Error: {error}</div>;
  }

  return (
    <div className="container">
      <h1>Articles</h1>
      <div className="article-list">
        {articles.length === 0 ? (
          <p>No articles found.</p>
        ) : (
          articles.map((article) => {
            console.log('Article Object:', article);
            return (
              <div key={article.id} className="article-card">
                <Link href={`/articles/${article.documentId}`}>
                  <h2>{article.title || 'Untitled'}</h2>
                </Link>
                <p>
                  {article.content && article.content[0]?.children && article.content[0].children[0]?.text
                    ? article.content[0].children[0].text.slice(0, 100) + '...'
                    : 'No content available'}
                </p>
              </div>
            );
          })
        )}
      </div>
    </div>
  );
}


功能说明:
调用 getArticles 获取文章列表。使用 useEffect 和 useState 管理数据加载状态。
渲染文章列表,支持点击跳转到文章详情页(使用 documentId 作为参数)。




3.3 app/articles/[id]/page.js
作用:文章详情页,动态路由,显示具体文章内容。
'use client';
import { useEffect, useState } from 'react';
import { useParams } from 'next/navigation';
import { getArticle } from '../../../utils/api';

export default function ArticleDetail() {
  const params = useParams();
  const documentId = params?.id;
  const [article, setArticle] = useState(null);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    const fetchArticle = async () => {
      try {
        const response = await getArticle(documentId);
        console.log('Full Article Response:', response);
        console.log('Response Data:', response.data);
        const articleData = response.data?.data || response.data; // 处理嵌套
        if (articleData) {
          setArticle(articleData);
        } else {
          setArticle(null);
        }
      } catch (err) {
        console.error('Fetch Article Error:', err);
      } finally {
        setIsLoading(false);
      }
    };
    if (documentId) fetchArticle();
  }, [documentId]);

  if (isLoading) {
    return <div className="container">Loading...</div>;
  }

  if (!article) {
    return <div className="container">Article not found.</div>;
  }

  return (
    <div className="container">
      <h1>{article.title || 'Untitled'}</h1>
      <div className="article-content">
        {article.content && Array.isArray(article.content) ? (
          article.content.map((block, index) => (
            <p key={index}>
              {block.children.map((child, childIndex) => (
                <span key={childIndex}>{child.text}</span>
              ))}
            </p>
          ))
        ) : (
          <p>No content available.</p>
        )}
      </div>
    </div>
  );
}


功能说明:
使用 useParams 获取动态路由参数 id(documentId)。调用 getArticle 获取文章详情。渲染文章标题和内容。


3.4 app/login/page.js(新建)
作用:登录页面,处理用户登录。


'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';
import { login } from '../../utils/api';
import { useAuth } from '../../context/AuthContext';

export default function Login() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');
  const router = useRouter();
  const { login: authLogin } = useAuth();

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      const { data } = await login(email, password);
      authLogin(data.user, data.jwt);
      router.push('/');
    } catch (err) {
      setError('Login failed');
    }
  };

  return (
    <div className="container">
      <h1>Login</h1>
      <form onSubmit={handleSubmit} className="form">
        <div className="form-group">
          <label>Email</label>
          <input
            type="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            required
          />
        </div>
        <div className="form-group">
          <label>Password</label>
          <input
            type="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            required
          />
        </div>
        <button type="submit" className="btn">Login</button>
      </form>
      {error && <p className="error">{error}</p>}
    </div>
  );
}


功能说明:
提供登录表单,输入邮箱和密码。调用 login API,向 Strapi 发送登录请求。
成功后将 JWT 和用户信息存储到 localStorage,并跳转到首页。



3.5 app/register/page.js(新建)
作用:注册页面,处理用户注册。


'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';
import { register } from '../../utils/api';

export default function Register() {
  const [username, setUsername] = useState('');
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');
  const router = useRouter();

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      const { data } = await register(username, email, password);
      router.push('/login');
    } catch (err) {
      setError('Registration failed');
    }
  };

  return (
    <div className="container">
      <h1>Register</h1>
      <form onSubmit={handleSubmit} className="form">
        <div className="form-group">
          <label>Username</label>
          <input
            type="text"
            value={username}
            onChange={(e) => setUsername(e.target.value)}
            required
          />
        </div>
        <div className="form-group">
          <label>Email</label>
          <input
            type="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            required
          />
        </div>
        <div className="form-group">
          <label>Password</label>
          <input
            type="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            required
          />
        </div>
        <button type="submit" className="btn">Register</button>
      </form>
      {error && <p className="error">{error}</p>}
    </div>
  );
}

功能说明:
提供注册表单,输入用户名、邮箱和密码。调用 register API,向 Strapi 发送注册请求。
成功后存储 JWT 和用户信息,跳转到首页。


3.6 app/create-article/page.js(新建)
作用:创建文章页面,允许登录用户发布文章。


'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';
import { createArticle } from '../../utils/api';
import { useAuth } from '../../context/AuthContext';

export default function CreateArticle() {
  const [title, setTitle] = useState('');
  const [content, setContent] = useState('');
  const [error, setError] = useState('');
  const { token } = useAuth();
  const router = useRouter();

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (!token) {
      setError('Please login to create an article');
      return;
    }
    try {
      const articleData = {
        title,
        content: [
          {
            type: 'paragraph',
            children: [
              {
                type: 'text',
                text: content || 'Default content',
              },
            ],
          },
        ],
        publishedAt: new Date().toISOString(),
      };
      await createArticle(token, articleData);
      router.push('/');
    } catch (err) {
      setError('Failed to create article');
    }
  };

  return (
    <div className="container">
      <h1>Create Article</h1>
      <form onSubmit={handleSubmit} className="form">
        <div className="form-group">
          <label>Title</label>
          <input
            type="text"
            value={title}
            onChange={(e) => setTitle(e.target.value)}
            required
          />
        </div>
        <div className="form-group">
          <label>Content</label>
          <textarea
            value={content}
            onChange={(e) => setContent(e.target.value)}
            required
            rows="5"
          />
        </div>
        <button type="submit" className="btn">Publish</button>
      </form>
      {error && <p className="error">{error}</p>}
    </div>
  );
}


功能说明:
提供文章发布表单,输入标题和内容。检查用户是否登录(通过 token)。
调用 createArticle API,向 Strapi 发送文章创建请求。成功后跳转到首页。




3.7 components/AuthWrapper.js(新建)
作用:认证包装组件,提供 AuthContext。

'use client';
import { AuthProvider } from '../context/AuthContext';

export default function AuthWrapper({ children }) {
  return <AuthProvider>{children}</AuthProvider>;
}

功能说明:
使用 AuthProvider 提供认证上下文,包装所有页面内容。
确保子组件可以通过 useAuth 访问用户状态和 token。


3.8 components/Navbar.js(新建)
作用:导航组件,动态渲染导航链接。




'use client';
import Link from 'next/link';
import { useAuth } from '../context/AuthContext';

export default function Navbar() {
  const { user, logout } = useAuth();

  return (
    <nav className="navbar">
      <Link href="/">Home</Link>
      {user ? (
        <>
          <Link href="/create-article">Create Article</Link>
          <button onClick={logout} className="btn">Logout</button>
          <span>Welcome, {user.username}</span>
        </>
      ) : (
        <>
          <Link href="/login">Login</Link>
          <Link href="/register">Register</Link>
        </>
      )}
    </nav>
  );
}


功能说明:
使用 useAuth 获取用户状态和 logout 方法。
动态渲染导航:未登录显示“登录”和“注册”,已登录显示“创建文章”、“登出”和欢迎信息。



3.9 context/AuthContext.js(新建)
作用:认证上下文,管理用户登录状态和 token。


'use client';
import { createContext, useContext, useState, useEffect } from 'react';

const AuthContext = createContext();

export function AuthProvider({ children }) {
  const [user, setUser] = useState(null);
  const [token, setToken] = useState(null);

  useEffect(() => {
    if (typeof window !== 'undefined') {
      const storedToken = localStorage.getItem('token');
      const storedUser = localStorage.getItem('user');
      if (storedToken && storedUser) {
        setToken(storedToken);
        setUser(JSON.parse(storedUser));
      }
    }
  }, []);

  const login = (userData, jwt) => {
    setUser(userData);
    setToken(jwt);
    if (typeof window !== 'undefined') {
      localStorage.setItem('token', jwt);
      localStorage.setItem('user', JSON.stringify(userData));
    }
  };

  const logout = () => {
    setUser(null);
    setToken(null);
    if (typeof window !== 'undefined') {
      localStorage.removeItem('token');
      localStorage.removeItem('user');
    }
  };

  return (
    <AuthContext.Provider value={{ user, token, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
}

export const useAuth = () => useContext(AuthContext);




功能说明:
创建 AuthContext,管理用户状态(user 和 token)。

useEffect:在客户端加载时检查 localStorage,恢复用户状态。

login:保存用户数据和 token 到状态和 localStorage。

logout:清除用户状态和 localStorage。

useAuth:提供钩子,供其他组件访问上下文。



3.10 utils/api.js
作用:封装 API 请求,与 Strapi 后端交互。


import axios from 'axios';

const API_URL = 'http://localhost:1337/api';

export const register = async (username, email, password) => {
  return axios.post(`${API_URL}/auth/local/register`, {
    username,
    email,
    password,
  });
};

export const login = async (email, password) => {
  return axios.post(`${API_URL}/auth/local`, {
    identifier: email,
    password,
  });
};

export const getArticles = async () => {
  return axios.get(`${API_URL}/articles?populate=*`);
};

export const getArticle = async (documentId) => {
  return axios.get(`${API_URL}/articles/${documentId}?populate=*`);
};

export const createArticle = async (token, articleData) => {
  return axios.post(
    `${API_URL}/articles`,
    { data: articleData },
    { headers: { Authorization: `Bearer ${token}` } }
  );
};


功能说明:
register:向 Strapi 发送注册请求。login:向 Strapi 发送登录请求。

getArticles:获取文章列表。getArticle:获取单篇文章(使用 documentId)。

createArticle:创建新文章(需要认证)。




3.11 styles/globals.css
作用:全局样式,简单美化页面。




body {
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 0;
  background-color: #f5f5f5;
}

.container {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
}

.navbar {
  display: flex;
  gap: 20px;
  padding: 10px 20px;
  background-color: #0070f3;
  color: white;
}

.navbar a {
  color: white;
  text-decoration: none;
}

.navbar button {
  background: none;
  border: none;
  color: white;
  cursor: pointer;
}

.form {
  display: flex;
  flex-direction: column;
  gap: 15px;
  max-width: 400px;
  margin: 0 auto;
}

.form-group {
  display: flex;
  flex-direction: column;
}

.form-group label {
  margin-bottom: 5px;
  font-weight: bold;
}

.form-group input,
.form-group textarea {
  padding: 8px;
  font-size: 16px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.btn {
  padding: 10px;
  background-color: #0070f3;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 16px;
}

.btn:hover {
  background-color: #005bb5;
}

.error {
  color: red;
  margin-top: 10px;
}

.article-list {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.article-card {
  padding: 15px;
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.article-card h2 {
  margin: 0 0 10px;
  color: #0070f3;
}

.article-content p {
  margin: 10px 0;
}


功能说明:
提供全局样式,美化页面布局、导航、表单和文章展示。






3.12 next.config.mjs(新建)
作用:Next.js 配置文件,调整项目配置。


/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
};

export default nextConfig;




功能说明:
启用 reactStrictMode,确保 React 严格模式运行,帮助发现潜在问题。

可根据需要添加其他配置(如图像优化、环境变量等)。




4.配置完毕以后,npm run dev 启动strapi 与next.js 然后测试下面的!


注册:访问 http://localhost:3000/register,输入用户名、邮箱和密码,注册用户。

登录:访问 http://localhost:3000/login,输入邮箱和密码,登录。

文章列表:访问 http://localhost:3000/,查看文章列表。

文章详情:点击文章标题,访问 http://localhost:3000/articles/nbedxv11g6sdbxvnsdjxs48n,查看文章详情。

发布文章:登录后访问 http://localhost:3000/create-article,创建新文章。


好的。下面已经打包备份了。strapi cms 和next.js website 文件中修改的资料;可以查找对比。

 

下地地址   https://www.525you.com/d/file/2025/202503/f588af66fa52f6c2e80446d0fdfbreb1.rar

 

 


Sunbit交易所合约交易新手操作教程 重装系统的教程,超简单的u盘一键重装电脑系统 创造与魔法植物纤维有什么用(创魔植物纤维哪里多) GHST是什么币种?GHST币前景怎么样? 万圣节第五人格活动有哪些(第五人格万圣节活动持续多久) 第五人格搏命是哪个天赋(第五人格里的搏命是什么天赋) 2023dnf神话装备转换npc在哪(snf神话装备) 今天的泰达币兑换人民币等于多少?泰达币如何兑换人民币? 适合解压玩的游戏有哪些(比较解压的游戏有哪些) 魔兽世界导灵器怎么升级(魔兽世界导灵器升级278) 期货交易平台哪个最可靠?正规期货交易平台APP排行榜 okex永续合约怎么玩?okex永续合约交易教程 永续合约对手价是什么意思? 莱比特矿池怎样挖矿?莱比特矿池挖矿教程 王者荣耀解说灵儿叫什么(王者荣耀的解说灵儿) 宝可梦阿尔宙斯传说怎么换小精灵(阿尔宙斯怎么弄) 梦幻西游强壮有什么效果(梦幻西游强壮太贵了啊) 冰原守卫者佣兵实力怎么升(冰原守卫者攻略) 求职必看!靠谱网站有哪些(招聘网站好用的) WING是什么币种?WING币未来前景如何? 区块链扫盲:炒币做空是什么意思?炒币做空要注意什么? 开机启动项怎么设置?Win7开机启动项设置图文详解 3个有特色的兼职网络平台(兼职赚钱的正规软件) 单币质押挖矿什么意思?单币质押挖矿的风险有哪些 BDI是什么币种?BDI币怎么样详细介绍 中国大陆可用的正规交易所有哪些?正规的数字货币交易平台排行 森林之子steam叫什么(森林之子到底出不出了) DORA发行总量多少?铜锣烧币发行总量介绍 使用.bat 随机生成url链接的解决方案 IPFS/FIL挖矿防爆指南,IPFS/FIL挖矿需要主要哪些坑 苹果手机小圆点怎么弄出来?苹果手机小圆点打不开怎么办 租房子app哪个好没有中介费?(租房平台比较) 如何在币安购买狗狗币?币安买狗狗币流程 关于Chia的一些常见问题的补充和整理 Web3.0时代,我们的生活将会产生怎样的变化? 梦幻西游千年蛇魅怎么样(梦幻西游千年蛇魅剧情怎么过) 宝可梦传说阿尔宙斯伊布哪个厉害(精灵宝可梦阿尔宙斯厉害吗) Bithumb交易所详细的注册图文教程 我的世界蜂巢没有蜜蜂怎么办(我的世界蜂巢为什么没有蜂蜜) Axie Infinity游戏还有人玩吗?Axie Infinity官网介绍官方地址 星露谷物语卡洛琳家在哪里(星露谷物语卡洛琳在哪卡洛琳行程一览) 有啥新出的放置手机网游(手游放置游戏) 蚂蚁庄园小鸡宝宝考考你今天的答案是什么2022最新 卖车怎么卖?卖车平台哪个好一点 三国杀袁绍怎么获得(三国杀袁绍适合什么身份) 蜀门手游红花洞怎么打(蜀门手游红手指怎么挂机) 创造与魔法混战服选什么宠物(创造与魔法混战服新手攻略2020) 看风景去哪里旅游最好?策划一次完美旅行 imToken钱包怎么添加USDT?imToken钱包添加币种教程 全球币圈三大数字货币交易所是哪三家?盘点三大数字货币交易所 cf手游跨系统角色转移卡怎么买(cf手游跨系统角色转移卡在哪里买) 冰原守卫者冰龙蛋如何获取(冰原守卫者怎么玩) imToken怎么提现人民币?imToken提现人民币教程 王者荣耀弈星2022怎么出装(王者弈星最强出装) 欧易充值为什么要看银行流水明细?欧易充值未到账怎么回事? 0氪仙侠手游推荐(0氪不花钱的仙侠手游排行榜) 黑色沙漠手游料理师的风采知识怎么获得(黑色沙漠料理从零到道人) dnf决战者是固伤还是百分比(dnf决战者装备搭配) 我的世界狐狸驯服后会跟随吗(我的世界狐狸被驯服会跟你走吗) 王者荣耀右侧发信号怎么变成问号了(王者荣耀右侧发信号图标不一样) 无法连接至steam网络(无法进入steam网络) 在币安交易所购买USDT泰达币操作步骤教程 腾讯微云怎么清理相似照片 腾讯微云清理相似照片教程 imToken钱包支持哪些币种?imToken钱包支持哪些数字货币? 和平精英皇冠和白银组队能加分吗(和平精英皇冠和白银排到的是什么段位) 创造与魔法什么样的坐骑速度快(创造与魔法什么坐骑速度快排名) 热血传奇:1.76与1.80的过渡相连是什么样的(热血传奇1.76和1.80区别) 梦幻西游手游魔王寨怎么加点(梦幻西游手游魔王寨怎么加点才厉害?) ios有什么免费大型游戏(iphone免费大型游戏) REN币未来前景怎么样?REN币历史最高价和最低价介绍 INJ是什么币?INJ币未来前景怎么样? 王者荣耀qq和微信哪个水平高(王者荣耀qq厉害还是微信厉害) 诛仙手游妖兽突袭怎么带队(诛仙手游妖兽突袭活动玩法详细攻略) 雷达币彻底崩盘不能提现了吗?中央电视台揭秘雷达币骗局 诛仙手游焚香灌注怎么弄(诛仙手游焚香用什么法宝好) csgo控制器已启用但是按不出来怎么办(csgo控制器已启用是什么意思) 百度网盘不用开会员(百度网盘不用开会员也能快速下载) 宝可梦传说阿尔宙斯花岩怪只有一只吗(神奇宝贝阿尔宙斯有几块石板) Pi主网后的价格是多少?派币主网上线最新消息以及价格预测 B2BX是什么交易所?B2BX交易所安全吗? IEO是什么意思?区块链IEO的优缺点解析 王者荣耀星传说限定一般上线多久(王者星传说限时) 英雄联盟手游隐藏分低如何补回来(联盟手游隐藏分查询) 有哪些福利多的卡牌游戏(福利游戏哪个好) 超好用的pdf编辑软件,打工人必备软件) 金铲铲之战中新手选择什么阵容玩(金铲铲之战新手上路) 区块链概念股是什么?区块链概念股有什么作用? 梦幻西游画魂在哪里抓(梦幻西游画魂任务) 第五人格宿伞之魂怎么玩 宿伞之魂玩法攻略 喂价是什么意思?一文读懂区块链喂价机制 CoinEx交易所怎么充值?CoinEx充值、提现、充币、提币图文教程 英雄联盟手游信誉4级怎么升5级(英雄联盟手游信誉等级4到5要多久) 魔兽世界中格罗姆地狱咆哮的墓碑在哪(魔兽世界格罗姆地狱咆哮结局) 什么是P盘?chia奇亚矿池搭建 10u币圈合约最稳的玩法?加密货币合约永不爆仓方法 ERC20协议是什么意思?一文读懂ERC20协议 超详细的金庸群侠传攻略全求成,轻松助你过关斩将 艾尔登法环太刀好用吗(艾尔登法环什么类型) BOND是什么币种?BOND币前景和价值全面介绍 魔兽世界工程学分支哪个好(魔兽世界里的工程学)

热门文章

推荐专题

更多>>

游戏推荐

更多>>