【腾讯云 Cloud Studio 实战训练营】沉浸式体验编写一个博客系统

前言

欢迎参加腾讯云 Cloud Studio 实战训练营!在本次训练营中,我们将通过沉浸式体验,带您一步步编写一个基于 Nuxt.js 的静态博客系统。无论您是初学者还是有一定编程经验的开发者,本训练营都将为您提供一个深入了解和掌握 Nuxt.js 技术以及静态网站开发的机会。
使用 Nuxt.js 作为前端框架,我们将能够充分利用其强大的功能和优势,快速搭建一个高效、可扩展的静态博客系统。Nuxt.js 是基于 Vue.js 的服务端渲染框架,结合了单页应用程序(SPA)和静态生成模式(SSG),使得我们可以轻松构建出具有良好用户体验的博客系统。

在这个过程中,您将学习到

  1. 如何使用Cloud Studio 进行项目开发
  2. Cloud Studio 项目如何链接到coding 作为项目的管理仓库
  3. 如和使用python 来爬取你的csdn 博客信息
  4. Nuxt.js 的安装和基本配置:了解如何创建一个新的 Nuxt.js 项目,以及对其基本配置进行调整。
  5. 页面和路由设计:学习如何使用 Nuxt.js 创建不同的页面,以及如何配置路由,实现页面之间的导航。
  6. layout 模块如何使用,清晰规划layout
  7. 登录模块的动画效果等

项目中技术栈

  • Vue.js:JavaScript 框架
  • Nuxt.js:Vue.js 的通用应用框架
  • Element UI:基于 Vue.js 的 UI 组件库

新建工作空间

参考以下步骤来创建一个属于你自己的工作空间

登录(注册)Cloud Studio 账号:

打开Cloud Studio网址(https://cloudstudio.net/),有三种注册登录方式 , 选择一种即可

在这里插入图片描述

进入 Cloud Studio 控制台:

点击左下角的 新建工作空间

在这里插入图片描述

配置工作空间参数:

在弹出的创建工作空间窗口中,您需要进行以下配置:

  • 空间名称
  • 空间描述
  • 工作类别
  • 代码来源
  • 选择仓库服务商
  • 开发环境
  • 规格配置
    注意 这里我选择的是coding 作为仓库服务商, 因此需要自己注册一个coding 账户, 这里不做详细讲解
    如图 输入coding的域名前缀就可以了

在这里插入图片描述
完整配置

在这里插入图片描述

确认并创建工作空间:

完成上述配置后,点击 “创建” 按钮确认创建新的工作空间, 你会惊喜的发现 这个与vscode 惊人的相似

在这里插入图片描述

项目搭建

接下来就开始进行项目搭建环节

注意事项
在搭建Nuxt项目时,你需要注意以下几个方面:

  1. 安装Node.js和npm: Nuxt是基于Node.js开发的,因此首先要确保在本地安装了Node.js和npm。可以从官方网站上下载并安装最新版本的Node.js,它会附带安装npm。

比如本项目 用的是 node 19.0.0 这版本, 建议 采用nvm 进行版本管理

  1. 创建新项目: 使用Nuxt提供的命令行工具创建新的Nuxt项目。打开终端窗口,切换到项目的目录中,然后执行npx create-nuxt-app <project-name>命令。根据提示选择要使用的模板和配置项。

  2. 配置项目: 在创建项目后,你可以根据自己的需求进行一些配置。这包括选择UI框架、路由配置、样式预处理器等。可以修改nuxt.config.js文件来进行配置。

    本项目中所需要配置的地方

    需要再nuxt.config.js中配置server 如下

     server: {
          
          
    port: 3000, // default: 3000
    host: '0.0.0.0' // default: localhost
    

}
```

meta:中加上代码 { name: 'referrer', content: 'no-referrer' }, 来进行图片的加载
在这里插入图片描述

拓展内容

  1. 开发和构建: 使用Nuxt进行开发时,可以在pages目录下创建页面组件,Nuxt会自动根据文件名生成路由。可以在layouts目录下创建布局组件,用于定义页面的整体布局。使用Nuxt提供的命令npm run dev启动本地开发服务器,进行实时预览。使用npm run build命令构建项目,生成静态文件。

  2. SEO优化: Nuxt默认使用服务端渲染(SSR),可以优化SEO(搜索引擎优化)。在每个页面组件中,可以使用head方法来设置页面的标题、meta标签等信息,这些信息将在服务端被渲染。

  3. 部署项目: 在部署Nuxt项目时,你可以选择将项目部署到服务器上或者使用静态文件托管服务。如果选择部署到服务器上,需要确保服务器上已经安装了Node.js和npm,并按照说明运行npm installnpm run build命令。

配置nuxt 脚手架

使用命令 npx create-nuxt-app <项目名> 创建一个nuxt 的脚手架

掉出终端 , 输出 指令 回车运行, 等待项目下载

在这里插入图片描述

成功搭建后效果图, 以及脚手架配置

在这里插入图片描述

运行项目

运行项目的指令

 cd blog
 npm run dev

报错信息

运行时我发现了一个错误,如下所示

blog git:(master)npm run dev 

> [email protected] dev
> nuxt

internal/modules/cjs/loader.js:892
  throw err;
  ^

Error: Cannot find module 'node:util'
Require stack:
- /workspace/myblog/blog/node_modules/consola/dist/shared/consola.deac7d5a.cjs
- /workspace/myblog/blog/node_modules/consola/dist/shared/consola.4bbae468.cjs
- /workspace/myblog/blog/node_modules/consola/dist/index.cjs
- /workspace/myblog/blog/node_modules/consola/lib/index.cjs
- /workspace/myblog/blog/node_modules/@nuxt/utils/dist/utils.js
- /workspace/myblog/blog/node_modules/@nuxt/cli/dist/cli-index.js
- /workspace/myblog/blog/node_modules/@nuxt/cli/dist/cli.js
- /workspace/myblog/blog/node_modules/nuxt/bin/nuxt.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:889:15)
    at Function.Module._load (internal/modules/cjs/loader.js:745:27)
    at Module.require (internal/modules/cjs/loader.js:961:19)
    at require (internal/modules/cjs/helpers.js:92:18)
    at Object.<anonymous> (/workspace/myblog/blog/node_modules/consola/dist/shared/consola.deac7d5a.cjs:3:19)
    at Module._compile (internal/modules/cjs/loader.js:1072:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10)
    at Module.load (internal/modules/cjs/loader.js:937:32)
    at Function.Module._load (internal/modules/cjs/loader.js:778:12)
    at Module.require (internal/modules/cjs/loader.js:961:19) {
    
    
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/workspace/myblog/blog/node_modules/consola/dist/shared/consola.deac7d5a.cjs',
    '/workspace/myblog/blog/node_modules/consola/dist/shared/consola.4bbae468.cjs',
    '/workspace/myblog/blog/node_modules/consola/dist/index.cjs',
    '/workspace/myblog/blog/node_modules/consola/lib/index.cjs',
    '/workspace/myblog/blog/node_modules/@nuxt/utils/dist/utils.js',
    '/workspace/myblog/blog/node_modules/@nuxt/cli/dist/cli-index.js',
    '/workspace/myblog/blog/node_modules/@nuxt/cli/dist/cli.js',
    '/workspace/myblog/blog/node_modules/nuxt/bin/nuxt.js'
  ]
}
➜  blog git:(master)

解决错误

根据错误信息显示,是找不到模块 ‘node:util’,导致引发了错误。

可以尝试以下办法解决

根据错误信息显示,依然是找不到模块 ‘node:util’,导致引发了错误。这可能是由于依赖关系问题或缺失的模块引起的。

您可以尝试以下步骤来解决这个问题:

  1. 清除 npm 缓存:在终端中执行以下命令清除 npm 缓存:
npm cache clean --force
  1. 删除 package-lock.json 文件和 node_modules 目录:在项目根目录下执行以下命令删除 package-lock.json 文件和 node_modules 目录:
rm package-lock.json
rm -rf node_modules
  1. 更新node 版本到19.0.0

    操作步骤如下:

    • nvm ls
    • nvm install 19.0.0
    • nvm use 19.0.0
  2. 重新安装依赖

    • npm install
  3. 运行项目

    • npm run dev
      在这里插入图片描述

脚手架运行预览

在这里插入图片描述

问题

这里直接访问 http://172.16.21.246:3000/ 是不行的 有点击弹窗的信息进行访问, 如图
在这里插入图片描述

开启博客代码

配置layout

<template>
  <div>
    <el-card class="nav">
              <h1>若城的博客</h1>

     <div class="left">
       <el-row :gutter="20">
        <el-col :span="8" v-for="item in nav" :key="item.label">

          <span class="mynav" @click="handleJump(item.route)">{
   
   {item.label}}</span>
        </el-col>
       
      </el-row>
     </div>

     <div class="right">
       <el-row :gutter="20">
        <el-col :span="12"><span  @click="handleGoLogin(1)" class="mynav">登录</span></el-col>
        <el-col :span="12" ><span @click="handleGoLogin(2)" class="mynav">注册</span></el-col>
      </el-row>
     </div>
    </el-card>
    <nuxt />
     
  </div>
</template>
<script>
export default {
  data() {
    return {
      nav:[
         {
          label:'首页',
          route:'index'
         },
         {
          label:'博客画廊',
          route:'photo'
         },
         {
          label:'我的画廊',
          route:'about'
         },
      ]
    }
  },
  methods: {
    handleJump(url){
        this.$router.push({name:url})
    },
    handleGoLogin(idx){
         this.$router.push({name:'login'})

    }
  },
}
</script>
<style lang="scss" scoped>
  .nav{
    
  }
  h1{
     height: 30px;
          cursor: pointer;

     line-height: 30px;
  }
  ::v-deep .el-card__body{
 display: flex;
     justify-content: space-between;
  }
  .left{
     width: 30%;
     cursor: pointer;
  }
  .right{
    width: 10%;
         cursor: pointer;

  }
</style>

总结说明

模板部分:

  • 使用了<el-card>组件包裹整个导航栏。
  • <h1>标签显示了博客的标题,具有点击事件绑定,当被点击时会触发handleJump()方法。
  • <div class="left"><div class="right">分别表示导航栏左侧和右侧的区域,使用了Element UI的<el-row><el-col>组件来实现栅格布局。
  • 在左侧区域中,使用了v-for指令遍历nav数组中的对象,生成对应的导航项,并绑定了点击事件。
  • 在右侧区域中,同样使用了<el-col>组件生成两个导航项,分别是"登录"和"注册",并绑定了点击事件。
  • 在最后,使用了<nuxt />组件来展示其他页面内容。

脚本部分:

  • data中定义了一个nav数组,其中包含了导航栏的各个项,每个项包括一个label标签和一个route路由名称。
  • methods中定义了两个方法:handleJump(url)用于通过$router.push()方法实现页面跳转,handleGoLogin(idx)也是通过$router.push()方法实现跳转到登录页面。

样式部分:

  • .nav类定义导航栏整体的样式。
  • h1标签设置了标题的样式,包括高度、光标类型以及行高等。
  • ::v-deep .el-card__body选择器通过::v-deep关键词,使得内部样式可以影响该组件下的子组件,这里用来设置导航栏内部元素的样式。
  • .left.right类分别设置了左侧和右侧区域的宽度和光标类型。

layout 部分的代码主要实现的是一个简单的导航栏组件,并使用Nuxt来展示其他页面内容。点击导航项会触发相应的跳转事件。

首页配置

<template>
  <div class="container">
    <el-container>
      <el-aside width="500px">
        <el-card class="box-card">
          <div slot="header">
            <span>关于我</span>
          </div>
          <div class="wrapper">
            <div class="image">
              <el-avatar shape="square" :size="200" :src="pho"></el-avatar>
            </div>
            <div class="text">
               {
   
   {aboutMe}}
            </div>
          </div>
        </el-card>

        <el-card class="box-card">
          <clock />
        </el-card>
      </el-aside>
      <el-main>
        <el-card v-for="(item, index) in blogJson" :key="index">
          <el-row :gutter="20">
            <el-col :span="20" class="mycol">
              <h3 @click="handleLink(item.blogLink)">{
   
   { item.title }}</h3>
              <p>{
   
   { item.desc }}</p>
            </el-col>

            <el-col :span="4">
              <el-image
                style="width: 100px; height: 100px"
                :src="item.imgLink"
                fit="fill"
              ></el-image>
            </el-col>
          </el-row>
        </el-card>
      </el-main>
    </el-container>
  </div>
</template>

<script>
import pho from "../assets/img/1.jpg";
import blogJson from "../assets/result.json";
import clock from "../components/Clock.vue"

export default {
      
      
  layout: "Myblog",
  data() {
      
      
    return {
      
      
      pho,
      blogJson,
      aboutMe: `大家好,我是一名专注于 Python 和前端技术的技术讲解者。
       我擅长将复杂的技术概念转化为简单易懂的语言,帮助初学者快速入门,
       并满足高级开发者对更深入理解的需求。 作为一位资深的 Python 开发者,我具备广泛的编程经验和深厚的技术功底。我熟练掌握 Python 语言的各种特性和库,能够灵活运用它们解决实际问题。
       不论是爬虫、数据分析、后端开发还是机器学习,我都能够提供高效、可靠的解决方案。
        如果你对 Python 或前端技术有任何疑问或需要帮助,欢迎与我联系。无论是入门指导、项目建议还是技术咨询,
        我都会竭诚为您提供帮助。让我们一起探索技术的魅力,共同成长和进步!`,
    };
  },
  component(){
      
      
    clock
  },
  methods: {
      
      
    handleLink(item){
      
      
      //  window.location.href = 
      window.open(item, "_blank")
    }
  },
};
</script>
<style lang="scss" scoped>
// .box-card{
      
      
//    padding: 30px 0px 30px 0;
// }
.wrapper {
      
      
  overflow: hidden; /* 确保容器可以包含浮动元素 */
  width: 500px; /* 文字区域宽度 */
}

.text {
      
      
}

.image {
      
      
  width: 200px;
  height: 200px;
  border-radius: 50%;
  overflow: hidden;
  border: 2px solid #f0f0f0;
  float: left;
  shape-outside: circle();
}
.mycol{
      
      
   cursor: pointer;
}

::v-deep .el-card {
      
      
   margin-bottom: 20px;
}
</style>

总结说明

模板部分:

  • 使用了<el-container>组件来创建一个容器,包含了左侧的侧边栏(<el-aside>)和右侧的主要内容区域(<el-main>)。
  • 侧边栏中包含了两个<el-card>组件,分别用于展示关于我和时钟。
  • 关于我的部分使用了一个wrapper包裹,包含了一个头像(<el-avatar>)和一个文本区域,文本区域中显示了关于我的内容。
  • 主要内容区域中使用了v-for指令遍历blogJson数组中的对象,在每个对象对应的<el-card>中展示博客的标题、描述和图片。

脚本部分:

  • 使用了import语句引入了一些资源文件和组件。
  • data函数返回了一个包含了一些数据的对象,包括头像、博客数据和关于我的内容。
  • component属性中注册了一个名为clock的组件。
  • methods中定义了一个handleLink(item)方法,当博客列表中的标题被点击时,会在新窗口中打开对应的博客链接。

样式部分:

  • 使用了SCSS预处理器语法。
  • wrapper类用于设置关于我部分文字区域的样式。
  • image类用于设置头像区域的样式,包括宽度、高度、边框等。
  • .mycol类设置了博客列表标题的样式,包括光标类型为指针。
  • ::v-deep .el-card选择器通过::v-deep关键词,使得内部样式可以影响该组件下的子组件,这里用来设置博客列表项之间的间距。

首页部分的代码主要实现的是关于我和博客列表的页面,使用Element UI的组件和样式进行展示。关于我部分展示了一张头像和一段文字信息,博客列表展示了多个博客项,每个博客项包括标题、描述和图片。点击博客标题会在新窗口中打开对应的博客链接。

其他页面

由于每个页面都有不同的用处, 这里就不做过多讲解说明, 对于这个博客感兴趣的朋友可以在文章最下面找到项目地址哦!

效果预览

在这里插入图片描述

项目视频预览

7月27日

项目目录结构

blog
 |-- myblog
    |-- .editorconfig        // 代码编辑器的配置文件
    |-- .gitignore           // Git 版本控制忽略文件列表
    |-- README.md            // 项目的说明文档
    |-- nuxt.config.js       // Nuxt.js 的配置文件
    |-- package-lock.json    // npm 生成的锁定依赖版本的文件
    |-- package.json         // 包含项目的元数据和依赖的配置文件
    |-- tree.md              // 当前目录结构的文档
    |-- .nuxt                // Nuxt.js 自动生成的文件夹
    |   |-- App.js           // Nuxt.js 应用程序的入口文件
    |   |-- client.js        // Nuxt.js 客户端的入口文件
    |   |-- empty.js         // 空文件
    |   |-- index.js         // Nuxt.js 核心库的入口文件
    |   |-- jsonp.js         // JSONP 相关的功能代码
    |   |-- loading.html     // 页面加载中的 HTML 文件
    |   |-- middleware.js    // 中间件的代码
    |   |-- router.js        // 路由的配置文件
    |   |-- router.scrollBehavior.js  // 路由的滚动行为配置文件
    |   |-- routes.json      // 路由的配置文件(JSON 格式)
    |   |-- server.js        // Nuxt.js 服务器的入口文件
    |   |-- utils.js         // Nuxt.js 的工具函数
    |   |-- components       // Nuxt.js 自动生成的组件目录
    |   |-- layouts          // 页面布局文件目录
    |   |-- mixins           // Mixin 文件目录
    |   |-- vetur            // Vetur 插件的配置文件目录
    |   |-- views            // 视图文件目录
    |-- assets               // 静态资源文件目录
    |   |-- common.css       // 共享的 CSS 样式文件
    |   |-- login.css        // 登录页面的 CSS 样式文件
    |   |-- pat.svg          // PAT 图标文件(可能是用户名的缩写)
    |   |-- result.json      // 结果数据的 JSON 文件
    |   |-- img              // 图片目录
    |       |-- 1.jpg        // 图片文件
    |-- components           // 自定义组件目录
    |   |-- Clock.vue        // 时钟组件
    |   |-- NuxtLogo.vue     // Nuxt.js Logo 组件
    |   |-- Tutorial.vue     // 教程组件
    |-- layouts              // 页面布局文件目录
    |   |-- Myblog.vue       // "Myblog" 页面的布局文件
    |-- pages                // 页面文件目录
    |   |-- index.vue        // 主页
    |   |-- about            // 关于页面
    |   |   |-- index.vue    // 关于页面的主文件
    |   |-- login            // 登录页面
    |   |   |-- index.vue    // 登录页面的主文件
    |   |-- photo            // 照片页面
    |       |-- index.vue    // 照片页面的主文件
    |-- plugins              // 插件文件目录
    |   |-- element-ui.js    // Element UI 插件的配置文件
    |-- static               // 静态文件目录
    |   |-- favicon.ico      // 网站的图标文件
    |   |-- heng             // 文件夹
    |   |-- imgdata          // 图像数据文件夹
    |-- store                // Vuex 的状态管理目录
        |-- README.md        // 状态管理的说明文档

上传代码到coding

设置coding 邮箱和账号

git config --global user.email “[email protected]
git config --global user.name “Your Name”

git 提交

1.在我们的命令编辑器里初始化项目 git init
2.git add .
3.git commit -m ‘备注’
4.git remote add origin [email protected]:shiqingqing/test.git
5.git pull origin master
6.开始上传 输入git push -u origin master 这里可能会报错 所以建议不用这句 直接使用git push -u origin master -f 强制上传

总结说明

到目前位置 基本上已经将项目搭建完成了, 不过在使用Cloud Studio 的过程中确实存在一些问题,总结如下:

链接图片不显示

如图我的imgLink 是有效的https 地址 , 但是 实际上运行之后并没有显示出来, 随后我又换了几种方式,发现都不显示, 很难受

在这里插入图片描述

终端启动项目

我这个是nuxt项目, 终端启动的时候 会有默认的请求地址, 但是 这个地址并不生效, 相反需要打开终端弹窗的按钮才可以访问, 访问的地址与我自己监听的地址也不一样, 完全不符合习惯, 如图
在这里插入图片描述

关闭端口弹窗问题

启动项目之后关闭终端弹窗之后 , 就找不到这个弹窗了, 不知在哪里找到, 除非重启项目

文件同步运行问题

编辑文件的时候自动保存, 导致终端会热更新, 显得很乱, 而且出现的报错也很严重, 比如我一个闭合还没敲,但是终端已经运行了, 这时就会报错, 很难受啊

安装脚手架

在安装脚手架的时候,非常费时间,等了好久,希望可以改进下

优点

在安装项目的时候 , 我发现使用的node 版本不对但是, 我不清楚Cloud Studio 是否有nvm 版本管理工具, 尝试的敲了一下 nvm ls 发现, 竟然贴心的安装了nvm 版本控制, 这个很细节很好.
当然Cloud Studio 还有很多其他优点, 期待大家一起去体验感受一下哦!

资源

项目coding 地址

blog项目地址

Cloud Studio 地址

Cloud Studio

使用py脚本获取博客资源

import json
from selenium import webdriver

# 使用 Chrome 驱动程序创建一个 WebDriver 实例
driver = webdriver.Chrome()

# 访问指定的博客列表页面
url = 'https://blog.csdn.net/qq_33681891?type=blog'
driver.get(url)

# 定位博客列表中的每篇文章
articles = driver.find_elements('css selector', '.blog-list-box')

# 创建一个空列表用于存储结果
results = []

# 遍历每篇文章,获取图片、标题、简介和博客链接
for article in articles:
    # 获取图片链接
    img_elem = article.find_element('css selector', '.course-img')
    img_src = img_elem.get_attribute('src')

    # 获取标题
    title_elem = article.find_element('css selector', 'h4')
    title = title_elem.text

    # 获取简介
    desc_elem = article.find_element('css selector', '.blog-list-content')
    desc = desc_elem.text

    # 获取博客链接
    link_elem = article.find_element('css selector', 'a')
    link = link_elem.get_attribute('href')

    # 将结果添加到列表中
    result = {
    
    
        '图片链接': img_src,
        '标题': title,
        '简介': desc,
        '博客链接': link
    }
    results.append(result)

# 关闭浏览器
driver.quit()

# 将结果以 JSON 格式写入文件
with open('result.json', 'w', encoding='utf-8') as f:
    json.dump(results, f, ensure_ascii=False, indent=4)

print('结果已保存到 result.json 文件中')

猜你喜欢

转载自blog.csdn.net/qq_33681891/article/details/131889556