【Tencent Cloud Studio Practical Training Camp】Immersive experience writing a blog system

foreword

Welcome to the Tencent Cloud Cloud Studio practical training camp! In this training camp, we will take you through an immersive experience to write a static blog system based on Nuxt.js step by step. Whether you are a beginner or a developer with some programming experience, this training camp will provide you with an opportunity to deeply understand and master Nuxt.js technology and static website development.
Using Nuxt.js as the front-end framework, we will be able to make full use of its powerful functions and advantages to quickly build an efficient and scalable static blog system. Nuxt.js is a server-side rendering framework based on Vue.js. It combines single-page application (SPA) and static generation mode (SSG), so that we can easily build a blog system with good user experience.

In the process, you will learn

  1. How to use Cloud Studio for project development
  2. How does the Cloud Studio project link to coding as the management warehouse of the project
  3. Such as using python to crawl your csdn blog information
  4. Nuxt.js Installation and Basic Configuration: Learn how to create a new Nuxt.js project and tweak its basic configuration.
  5. Page and Route Design: Learn how to use Nuxt.js to create different pages, and how to configure routes to navigate between pages.
  6. How to use the layout module, clearly plan the layout
  7. The animation effect of the login module, etc.

Technology stack in the project

  • Vue.js: JavaScript framework
  • Nuxt.js: A Universal Application Framework for Vue.js
  • Element UI: UI component library based on Vue.js

new workspace

Follow the steps below to create your own workspace

Log in (register) to your Cloud Studio account:

Open the Cloud Studio URL (https://cloudstudio.net/), there are three ways to register and log in, just choose one

insert image description here

Go to the Cloud Studio console:

Click New Workspace in the lower left corner

insert image description here

Configure workspace parameters:

In the pop-up Create Workspace window, you need to configure the following:

  • space name
  • space description
  • job category
  • code source
  • Choose a Warehouse Service Provider
  • development environment
  • Specification configuration
    attention Here I choose coding as the warehouse service provider, so I need to register a coding account by myself, and I will not explain it in detail here. Just enter the
    domain name prefix of coding as shown in the figure.

insert image description here
full configuration

insert image description here

Confirm and create the workspace:

After completing the above configuration, click the "Create" button to confirm the creation of a new workspace, you will be pleasantly surprised to find that this is surprisingly similar to vscode

insert image description here

Project build

Next, start the project construction phase

Notes
When building a Nuxt project, you need to pay attention to the following aspects:

  1. Install Node.js and npm: Nuxt is developed based on Node.js, so first make sure you have Node.js and npm installed locally. You can download and install the latest version of Node.js from the official website, which comes with npm installed.

For example, this project uses node 19.0.0 version, it is recommended to use nvm for version management

  1. Create a new project: Create a new Nuxt project using the command line tools provided by Nuxt. Open a terminal window, change into the project's directory, and execute npx create-nuxt-app <project-name>the command. Follow the prompts to select the template and configuration items to be used.

  2. Configure the project: After creating the project, you can configure it according to your needs. This includes choosing a UI framework, routing configuration, style preprocessors, and more. The file can be modified nuxt.config.jsfor configuration.

    The places that need to be configured in this project

    It needs to nuxt.config.jsbe configured serveras follows

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

}
```

Add meta:code { name: 'referrer', content: 'no-referrer' },to load the image
insert image description here

Expand content

  1. Development and construction: When using Nuxt for development, you can pagescreate page components under the directory, and Nuxt will automatically generate routes based on the file name. Layout components can be layoutscreated under the directory to define the overall layout of the page. Use the commands provided by Nuxt npm run devto start the local development server for live preview. Use npm run buildthe command to build the project and generate static files.

  2. SEO optimization: Nuxt uses server-side rendering (SSR) by default, which can optimize SEO (search engine optimization). In each page component, headmethods can be used to set the page title, meta tags and other information, which will be rendered on the server side.

  3. Deploying the project: When deploying a Nuxt project, you can choose to deploy the project to a server or use a static file hosting service. If you choose to deploy to the server, you need to ensure that Node.js and npm have been installed on the server, and run npm installand npm run buildcommand according to the instructions.

Configure nuxt scaffolding

Use the command npx create-nuxt-app <项目名>to create a nuxt scaffolding

Fall out of the terminal, output the command and press Enter to run, waiting for the project to download

insert image description here

Rendering after successful construction, and scaffolding configuration

insert image description here

run project

Commands to run the project

 cd blog
 npm run dev

error message

I found an error when running it as below

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)

fix bug

According to the error message, the module 'node:util' could not be found, which caused an error.

You can try the following solutions

According to the error message, the module 'node:util' is still not found, causing an error. This could be due to dependency issues or missing modules.

You can try the following steps to resolve this issue:

  1. Clear the npm cache: Execute the following command in the terminal to clear the npm cache:
npm cache clean --force
  1. Delete package-lock.jsonfiles and node_modulesdirectories: Execute the following commands in the project root directory to delete package-lock.jsonfiles and node_modulesdirectories:
rm package-lock.json
rm -rf node_modules
  1. Update node version to 19.0.0

    The operation steps are as follows:

    • nvm ls
    • nvm install 19.0.0
    • nvm use 19.0.0
  2. Reinstall dependencies

    • npm install
  3. run project

    • npm run dev
      insert image description here

Scaffolding run preview

insert image description here

question

Direct access here http://172.16.21.246:3000/ is not acceptable. Click on the information in the pop-up window to access, as shown in the figure
insert image description here

Open blog code

configure 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>

summary

Template section:

  • <el-card>Components are used to wrap the entire navigation bar.
  • <h1>The tag displays the title of the blog and has a click event binding that will fire a method when clicked handleJump().
  • <div class="left">and <div class="right">represent the areas on the left and right of the navigation bar respectively, using Element UI's <el-row>and <el-col>components to implement the grid layout.
  • In the left area, v-forinstructions are used to traverse navthe objects in the array, generate corresponding navigation items, and bind the click event.
  • In the right area, <el-col>the component is also used to generate two navigation items, namely "login" and "register", and the click event is bound.
  • At the end, components are used <nuxt />to display other page content.

Script section:

  • dataAn array is defined in nav, which contains the items of the navigation bar, and each item includes a labellabel and a routeroute name.
  • methodsTwo methods are defined in : It is used to realize the page jump handleJump(url)through the method, and it is also used to realize the jump to the login page through the method.$router.push()handleGoLogin(idx)$router.push()

Style section:

  • .navClass defines the overall style of the navigation bar.
  • h1The label sets the style of the heading, including height, cursor type, and line height.
  • ::v-deep .el-card__bodyThe selector uses ::v-deepkeywords so that the internal style can affect the subcomponents under the component, which is used to set the style of the internal elements of the navigation bar.
  • .leftand .rightclasses set the width and cursor type of the left and right regions, respectively.

layoutPart of the code mainly implements a simple navigation bar component, and uses Nuxt to display other page content. Clicking on a navigation item will trigger the corresponding jump event.

Home configuration

<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>

summary

Template section:

  • The component is used <el-container>to create a container that contains a sidebar on the left ( <el-aside>) and a main content area on the right ( <el-main>).
  • There are two components in the sidebar <el-card>, which are used to display about me and clock respectively.
  • The about me section uses a wrapperwrapper that contains an avatar ( <el-avatar>) and a text area that displays about me.
  • In the main content area, the instruction is used v-forto traverse blogJsonthe objects in the array, and <el-card>display the title, description and picture of the blog in each object.

Script section:

  • importSome resource files and components are introduced using the statement.
  • dataThe function returns an object containing some data, including avatar, blog data, and about me.
  • componentA component named .properties is registered clock.
  • methodsA method is defined in handleLink(item), when the title in the blog list is clicked, the corresponding blog link will be opened in a new window.

Style section:

  • SCSS preprocessor syntax is used.
  • wrapperclass for styling the About Me section of the text area.
  • imageThe class is used to set the style of the avatar area, including width, height, border, etc.
  • .mycolClass that sets the style of the blog list title, including the cursor type as a pointer.
  • ::v-deep .el-cardThe selector uses ::v-deepkeywords so that the internal style can affect the subcomponents under this component. Here it is used to set the spacing between blog list items.

The code on the home page mainly implements the pages about me and the blog list, which are displayed using the components and styles of Element UI. The About Me section displays an avatar and a piece of text information, and the blog list displays multiple blog items, and each blog item includes a title, description, and picture. Clicking on a blog title will open the corresponding blog link in a new window.

other pages

Since each page has different uses, I won’t explain too much here. Friends who are interested in this blog can find the project address at the bottom of the article!

Effect preview

insert image description here

Project video preview

July 27th

Project directory structure

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        // 状态管理的说明文档

Upload code to coding

Set coding mailbox and account

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

git commit

1. Initialize the project in our command editor git init
2.git add .
3.git commit -m 'remarks'
4.git remote add origin [email protected]:shiqingqing/test.git
5.git pull origin master
6. Start uploading and input git push -u origin master Here may report an error, so it is recommended not to use this sentence directly to use git push -u origin master -f to force the upload

summary

So far, the project has basically been built, but there are some problems in the process of using Cloud Studio, which are summarized as follows:

link image not showing

As shown in the picture, mine imgLinkis a valid httpsaddress, but it is not displayed after actually running. Then I changed several methods and found that it is not displayed, which is very uncomfortable.

insert image description here

terminal startup project

This is my nuxtproject. There will be a default request address when the terminal is started, but this address does not take effect. Instead, you need to open the button of the terminal pop-up window to access it. The accessed address is different from the address I listen to. It is completely different. In line with the custom, as shown in the figure
insert image description here

Close the port pop-up window problem

After starting the project and closing the terminal pop-up window, I can’t find the pop-up window. I don’t know where to find it, unless I restart the project

file sync problem

When editing a file, it is automatically saved, causing the terminal to be hot updated, which looks very messy, and the error report is also very serious. For example, I haven’t typed a close yet, but the terminal is already running. At this time, an error will be reported, which is very uncomfortable.

Install scaffolding

It took a lot of time to install the scaffolding. I waited for a long time and I hope it can be improved.

advantage

When installing the project, I found that the version of node used was wrong. However, I don’t know if Cloud Studio has a nvmversion management tool. I tried to knock it out and nvm lsfound that the nvm version control was installed intimately. This is very detailed.
Of Cloud Studiocourse There are many other advantages, and we look forward to experiencing them together!

resource

Project coding address

blog project address

Cloud Studio address

Cloud Studio

Use py script to get blog resources

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 文件中')

Guess you like

Origin blog.csdn.net/qq_33681891/article/details/131889556