5、搭建前端项目

5.1 使用vite + vue搭建

win + r 打开终端

切换到你想要搭建的盘

在这里插入图片描述

npm init vite@latest

跟着以下步骤取名即可

在这里插入图片描述

cd fullStackBlog

npm install

npm run dev

默认在 http://localhost:5173/ 下启动了

在这里插入图片描述

5.2 用vscode打开项目并安装需要的插件

在这里插入图片描述

1、删除多余的 HelloWorld.vue 文件

2、安装需要的插件

网络请求我直接用fetch了,你需要用axios的话就执行以下命令安装,使用也很简单

npm i axios -S

安装Element-Plus并引入到入口文件 main.js (这里使用了全局引入,按需引入的参考官网,很简单)

安装element-plus/icons-vue图标

npm install @element-plus/icons-vue

全局引入

npm install element-plus --save

在main.js中引入:

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'

const app = createApp(App)

app.use(ElementPlus)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
    app.component(key, component)
}
app.mount('#app')

**按需引入需要装两个插件,然后在vite.config.js中配置(打开注释部分即可):

npm install -D unplugin-vue-components unplugin-auto-import unplugin-icons
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// import AutoImport from 'unplugin-auto-import/vite'
// import Components from 'unplugin-vue-components/vite'
// import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
// import Icons from 'unplugin-icons/vite'
// import IconsResolver from 'unplugin-icons/resolver'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    // AutoImport({
    //   resolvers: [
    //     ElementPlusResolver(),
    //     IconsResolver({
    //       prefix: 'Icon',
    //     })
    //   ],
    // }),
    // Components({
    //   resolvers: [
    //     ElementPlusResolver(),
    //     IconsResolver({
    //       enabledCollections: ['ep'],
    //     }),
    //   ],
    // }),
    // Icons({
    //   autoInstall: true,
    // }),
  ],
})

在这里插入图片描述

安装tailwindcss并配置

执行以下命令安装tailwindcss和相应的插件

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

会生成 tailwind.config.js 和 postcss.config.js 文件即可

然后在assets文件夹下创建一个 tailwind.css 文件(名称可以自定义) 写上以下代码,并引入到入口文件main.js

// tailwind.config.js

/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{vue,js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

在这里插入图片描述

// postcss.config.js

export default {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}

在这里插入图片描述

// tailwind.css文件

@tailwind base;
@tailwind components;
@tailwind utilities;

在这里插入图片描述

// main.js

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import './assets/css/tailwind.css'
import './style.css'
import App from './App.vue'

const app = createApp(App)

app.use(ElementPlus)
app.mount('#app')

在这里插入图片描述

3、在App.vue中验证element 与 tailwind 是否生效

// App.vue

<template>
  <div>
    <h4 class="text-3xl font-blod underline">demo</h4>
    <el-button class="mt-24" type="primary">button</el-button>
  </div>
</template>

<script setup>
</script>

<style scoped>
</style>

在这里插入图片描述

在这里插入图片描述

验证没问题!

5.3 页面布局

安装vue-router路由

npm install vue-router@4

在src目录下新建router文件夹,新建index.js路由文件

// router/index.js

import { createRouter, createWebHistory } from "vue-router";

const route = [
    {
        path: '/',
        component: () => import('../views/blog/List.vue')
    },
    {
        path: '/add',
        component: () => import('../views/blog/Add.vue')
    }
]

const router = createRouter({
  history: createWebHistory(),
  routes: [...route]
});

export default router;

在这里插入图片描述

在src下新建views文件夹,在views下新建blog文件夹,在blog下新建List.vue 和 Add.vue 文件

// List.vue

<template>
    <div>list</div>
</template>

<script setup>

</script>

<style scoped>

</style>

// Add.vue

<template>
    <div>add</div>
</template>

<script setup>

</script>

<style scoped>

</style>

在这里插入图片描述

在main.js中引入路由并挂载

// main.js

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import './assets/css/tailwind.css'
import './style.css'
import App from './App.vue'
import router from './router'

const app = createApp(App)

app.use(router)
app.use(ElementPlus)
app.mount('#app')

在这里插入图片描述

在components下新建Header.vue Main.vue Footer.vue Nav.vue 并添加如下代码:
在这里插入图片描述

// Header.vue

<template>
    <div>
        <el-header class="h-16 p-4 header-wrapper">
            <el-row>
                <el-col :span="12">
                    <button class="button" data-text="Awesome" @click="goToHome">
                        <span class="actual-text">&nbsp;blog&nbsp;</span>
                        <span aria-hidden="true" class="hover-text">&nbsp;blog&nbsp;</span>
                    </button>
                </el-col>
                <el-col :span="12" class="flex justify-end">
                    <Nav />
                </el-col>
            </el-row>
        </el-header>
    </div>
</template>

<script setup>
import Nav from './Nav.vue'

</script>

<style scoped>
.header-wrapper{
    line-height: 64px;
}
</style>

<style scoped>
.button {
    margin: 0;
    height: auto;
    background: transparent;
    padding: 0;
    border: none;
    cursor: pointer;
}

.button {
    --border-right: 6px;
    --text-stroke-color: #1da1f2;
    --animation-color: #1da1f2;
    --fs-size: 2em;
    letter-spacing: 3px;
    text-decoration: none;
    font-size: var(--fs-size);
    font-family: "Arial";
    position: relative;
    text-transform: uppercase;
    color: transparent;
    -webkit-text-stroke: 1px var(--text-stroke-color);
}

.hover-text {
    position: absolute;
    box-sizing: border-box;
    content: attr(data-text);
    color: var(--animation-color);
    width: 0%;
    inset: 0;
    border-right: var(--border-right) solid var(--animation-color);
    overflow: hidden;
    transition: 0.5s;
    -webkit-text-stroke: 1px var(--animation-color);
}

.button:hover .hover-text {
    width: 100%;
    filter: drop-shadow(0 0 23px var(--animation-color))
}
</style>

// Main.vue

<template>
    <div>
        <el-main class="flex justify-center items-center container">
            <RouterView />
        </el-main>
    </div>
</template>

<script setup>

</script>

<style scoped>
.container {
    min-width: 100%;
    height: calc(100vh - 128px);
}
</style>

// Footer.vue

<template>
    <div>
        <el-footer class="h-16 flex justify-center items-center bg-black text-white">Footer</el-footer>
    </div>
</template>

<script setup>

</script>

<style scoped></style>

// Nav.vue

<template>

<div class="button-container">
  <button class="button" @click="goHome">
    List
  </button>
  <button class="button" @click="goAdd">
    Add
  </button>
</div>

</template>

<script setup>
import { useRouter } from 'vue-router'

const router = useRouter()

const goHome = () => {
    router.push({ path: '/' })
}

const goAdd = () => {
    router.push({ path: '/add' })
}
</script>


<style scoped>
.button-container {
  display: flex;
  background-color: rgba(0, 73, 144);
  width: 250px;
  height: 40px;
  align-items: center;
  justify-content: space-around;
  border-radius: 10px;
  box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px,
    rgba(0, 73, 144, 0.5) 5px 10px 15px;
  transition: all 0.5s;
}
.button-container:hover {
  width: 300px;
  transition: all 0.5s;
}

.button {
  outline: 0 !important;
  border: 0 !important;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background-color: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  transition: all ease-in-out 0.3s;
  cursor: pointer;
}

.button:hover {
  transform: translateY(-3px);
}

.icon {
  font-size: 20px;
}

</style>

// App.vue改造为以下结构

<template>
  <div>
    <Header></Header>
    <Main></Main>
    <Footer></Footer>
  </div>
</template>

<script setup>
import Header from './components/Header.vue'
import Main from './components/Main.vue'
import Footer from './components/Footer.vue'

</script>

<style scoped>
</style>

在这里插入图片描述

初步布局完成,页面如图:
在这里插入图片描述

5.4 新增博客页面 (前端部分)

页面使用了markdown语法,安装以下插件:

编写markdowm:mavon-editor

展示markdown:markdown-it、highlight.js

vue2下安装mavon-editor,vue3下安装mavon-editor@next

npm install mavon-editor@next markdown-it highlight.js  --save

// Add.vue

四个字段:

​ 标题:title

​ 作者: auth

​ 文档:mdoc

​ 创建时间:createtime

// markdowm 暂时对图片没做处理

<template>
    <div class="add-wrapper">
        <div class="top-anonymous">
            <el-input v-model="title" placeholder="标题(选填)"></el-input>
            <el-input class="mt-4" v-model="auth" placeholder="作者(选填)"></el-input>
        </div>

        <div class="bottom-anonymous">
            <mavon-editor class="h-full" :toolbars="markdownOption" v-model="mdoc" />
        </div>

        <button class="mt-8 button_submit" @click="save">
            <div class="button_submit__int">
                <span class="button_submit__span">Submit</span>
            </div>
        </button>
    </div>
</template>

<script setup>
import { ref } from 'vue'
import { ElNotification } from 'element-plus'
import { useRouter } from 'vue-router'
import { dayjs } from 'element-plus'
import { mavonEditor } from 'mavon-editor'
import 'mavon-editor/dist/css/index.css'

const router = useRouter()

let mdoc = ref('')

let markdownOption = ref({
    bold: true, // 粗体
    italic: true, // 斜体
    header: true, // 标题
    underline: true, // 下划线
    strikethrough: true, // 中划线
    mark: true, // 标记
    superscript: true, // 上角标
    subscript: true, // 下角标
    quote: true, // 引用
    ol: true, // 有序列表
    ul: true, // 无序列表
    link: true, // 链接
    imagelink: true, // 图片链接
    code: true, // code
    table: true, // 表格
    fullscreen: false, // 全屏编辑
    readmodel: false, // 沉浸式阅读
    htmlcode: true, // 展示html源码
    help: true, // 帮助
    undo: true, // 上一步
    redo: true, // 下一步
    trash: true, // 清空
    save: true, // 保存(触发events中的save事件)
    navigation: true, // 导航目录
    alignleft: true, // 左对齐
    aligncenter: true, // 居中
    alignright: true, // 右对齐
    subfield: true, // 单双栏模式
    preview: true, // 预览
})

let title = ref('')
let auth = ref('')

const save = async () => {
    if (!mdoc.value) {
        ElNotification({
            message: '请录入内容~~',
            type: 'error'
        }) 
        return
    }
    const params = {
        title: title.value || `标题--${dayjs().format('YYYY-MM-DD HH:mm:ss')}`,
        auth: auth.value || '恋爱单排选手',
        mdoc: mdoc.value,
        createtime: dayjs().format('YYYY-MM-DD HH:mm:ss')
    }
    const response = await request(params)
    console.log(response)
    if (!response.ok) {
        ElNotification({
            message: response.message,
            type: 'error'
        }) 
        return
    }
    ElNotification({
        message: '写入成功~~',
        type: 'success'
    })
    router.push({ path: '/' })

}

const request = async (params) => {
    const url = `${import.meta.env.VITE_API_BASE_URL}/api/add`

    const response = await fetch(url, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(params)
    })
    return response
}

</script>

<style scoped>
.add-wrapper {
    width: 90%;
    height: 96%;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
}
.top-anonymous {
    width: 100%;
}
.bottom-anonymous {
    margin-top: 32px;
    width: 100%;
    height: 100%;
}

</style>

<style scoped>
.button_submit {
  background-image: linear-gradient(to right bottom, #e300ff, #ff00aa, #ff5956, #ffb900, #fffe00);
  border: none;
  font-size: 1.2em;
  border-radius: 1.5em;
  padding: 4px;
  transition: border-top-left-radius 0.2s ease-in, 
  border-top-right-radius 0.2s ease-in 0.15s, 
  border-bottom-right-radius 0.2s ease-in 0.3s,
  border-bottom-left-radius 0.2s ease-in 0.45s, 
  padding 0.2s ease-in;
  position: relative;
}

.button_submit__int {
  background-color: #212121;
  color: white;
  border-radius: 1.3em;
  padding: 10px 40px;
  transition: all 0.2s ease-in,
  border-top-left-radius 0.2s ease-in, 
  border-top-right-radius 0.2s ease-in 0.15s, 
  border-bottom-right-radius 0.2s ease-in 0.3s,
  border-bottom-left-radius 0.2s ease-in 0.45s,
  padding 0.2s ease-in;
  font-weight: 600;
  z-index: -1;
  box-shadow: -15px -10px 30px -5px rgba(225, 0, 255, 0.8),
    15px -10px 30px -5px rgba(255, 0, 212, 0.8),
    15px 10px 30px -5px rgba(255, 174, 0, 0.8),
    -15px 10px 30px -5px rgba(255, 230, 0.8);
}

.button_submit:active .button_submit__int {
  padding: 10px 30px;
}

.button_submit:hover {
  border-radius: 0;
}

.button_submit:hover .button_submit__int {
  border-radius: 0;
}

.button_submit:hover .button_submit__int {
  box-shadow: -25px -10px 30px -5px rgba(225, 0, 255, 0.7),
    25px -10px 30px -5px rgba(255, 0, 212, 0.7),
    25px 10px 30px -5px rgba(255, 174, 0, 0.7),
    -25px 10px 30px -5px rgba(255, 230, 0, 0.7);
}

</style>

在这里插入图片描述

5.4 列表页面展示(前端部分)

// List.vue 页面数据目前是伪造的,后面后端写完后直接调用

<template>
    <div class="w-full h-full pt-10 box-border flex justify-between list-wrapper">
        <div class="w-3/5 h-full mr-4 relative left-wrapper">
            <div>
                <input
                    class="w-full bg-[#004990] text-white font-mono ring-1 ring-zinc-400 focus:ring-2 focus:ring-blue-400 outline-none duration-300 placeholder:text-white placeholder:opacity-50 rounded-full px-4 py-1 shadow-md focus:shadow-lg focus:shadow-blue-400"
                    autocomplete="off"
                    placeholder="title..."
                    name="title"
                    type="text"
                    v-model="input"
                    @blur="search"
                />
            </div>
            <div class="mt-8 overflow-y-scroll blog-list">
                <div v-for="item in blogList" :key="item">
                    <div class="text-3xl cursor-pointer" >
                        <span class="hover:text-[#1da1f2]">{{ item.title }}</span>
                    </div>
                    <div class="flex flex-row my-4">
                        <el-text class="basis-2/4" type="info">
                            <el-icon>
                                <Position />
                            </el-icon>
                            {{ item.auth }}
                        </el-text>
                        <el-text class="basis-2/4" type="info">
                            <el-icon>
                                <Compass />
                            </el-icon>
                            {{ item.createtime }}
                        </el-text>
                    </div>
                    <div class="mt-2 border rounded-md p-4">
                        <div v-html="md.render(item.mdoc)"></div>
                    </div>
                    <el-divider />
                </div>
            </div>
            <el-pagination class="absolute bottom-0" :hide-on-single-page="isShowPage" background layout="prev, pager, next" :page-size="5"
                :default-page-size="5" :current-page="currentPage" :total="totalNum" @current-change="currentChange" />
        </div>
        <div class="w-2/5 h-full right-wrapper">
            <div class="h-24"></div>
            <div class=""></div>
        </div>
    </div>
    <div class="write-btn-wrapper" @click="goWrite">
        <WriteBtn />
    </div>
</template>

<script setup>
import { ref } from 'vue'
import WriteBtn from '../../components/WriteBtn.vue'
import markdownit from 'markdown-it'
import hljs from 'highlight.js/lib/core'
import 'highlight.js/styles/atom-one-dark.css'
import { useRouter } from 'vue-router'
const router = useRouter()

const goWrite = () => {
    router.push({ path: '/add' })
}
let input = ref('')
let blogList = ref([
    {
        title: 'title1',
        auth: 'auth1',
        createtime: '2024-06-04',
        mdoc: '## 132\n```language\nlet a = 1 + 1\n```\n'
    },
    {
        title: 'title2',
        auth: 'auth2',
        createtime: '2024-06-04',
        mdoc: '## 这是一个测试2'
    },
    {
        title: 'title1',
        auth: 'auth1',
        createtime: '2024-06-04',
        mdoc: '## 132\n```language\nlet a = 1 + 1\n```\n'
    },
    {
        title: 'title1',
        auth: 'auth1',
        createtime: '2024-06-04',
        mdoc: '## 132\n```language\nlet a = 1 + 1\n```\n'
    },
    {
        title: 'title1',
        auth: 'auth1',
        createtime: '2024-06-04',
        mdoc: '## 132\n```language\nlet a = 1 + 1\n```\n'
    },
    {
        title: 'title1',
        auth: 'auth1',
        createtime: '2024-06-04',
        mdoc: '## 132\n```language\nlet a = 1 + 1\n```\n'
    },
])
let totalNum = ref(100)
let currentPage = ref(1)
// let isShowPage = computed(() => blogList.value.length <= 5)
let isShowPage = false


const currentChange = async (page) => {
    currentPage.value = page
    console.log(page, '=================')
    requestData()
    
}

const md = markdownit({
    html: true,
    linkify: true,
    typographer: true,
    breaks: true,
    highlight: function (str, lang) {
        if (lang && hljs.getLanguage(lang)) {
            try {
                return `<pre><code class="language-${lang} hljs">` +
                    hljs.highlight(str, { language: lang, ignoreIllegals: true }).value +
                    '</code></pre>';
            } catch (__) { }
        }

        return '<pre><code class="language-none hljs">' + md.utils.escapeHtml(str) + '</code></pre>';
    }
})

const search = () => {
    requestData()
}


const requestData = async () => {
    console.log(import.meta.env.VITE_API_BASE_URL, '============')
    const url = `${import.meta.env.VITE_API_BASE_URL}/api/list`
    console.log(input.value, '======input.value======')
    const params = {
        currentPage: currentPage.value - 1,
        title: input.value.trim()
    }

    const queryString = new URLSearchParams(params).toString();

    const requestUrl = `${url}?${queryString}`;
    const response = await fetch(requestUrl, {
        method: 'GET',
        headers: {
            'Content-Type': 'application/json'
        }
    })
    if (!response.ok) {
        throw new Error('Failed to fetch data')
    }
    const data = await response.json()
    // console.log('Data from backend:', data)
    const { data: resData, total } = data
    blogList.value = resData
    totalNum.value = total
}

</script>

<style scoped>
.write-btn-wrapper {
    position: fixed;
    top: 120px;
    right: 40px;
}
.blog-list {
    height: 90%;
}

</style>

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/687295.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

linux驱动学习(七)之混杂设备

需要板子一起学习的可以这里购买&#xff08;含资料&#xff09;&#xff1a;点击跳转 一、混杂设备 混杂设备也叫杂项设备&#xff0c;是对普通的字符设备(struct cdev)的一种封装,设计目的就是为了简化字符设备驱动设计的流程。具有以下特点&#xff1a; 1) 主设备号为10&a…

你工作中最推荐的 C/C++ 程序库有哪些,为什么?

我主要做计算力学&#xff0c;说说平时用的一些c库1、前处理划网格用netgen&#xff0c;非结构网格功能强大&#xff0c;有可执行的软件和供调用的库&#xff0c;使用方便。 刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「C的资料从专业入门到高级教程」&…

1898java疫情防控管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java 疫情防控管理系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助采用了java设计&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统采用web模式&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发…

【JMeter接口测试工具】第一节.JMeter简介和安装【入门篇】

文章目录 前言一、JMeter简介 1.1 JMeter基本介绍 1.2 JMeter优缺点二、JMeter安装 2.1 JMeter安装步骤 2.2 JMeter环境配置三、项目介绍 3.1 项目简介 3.2 API接口清单总结 前言 一、JMeter简介 1.1 JMeter基本介绍 JMeter 是 Apache 组织使用…

【NoSQL】Redis练习

1、redis的编译安装 systemctl stop firewalld systemctl disable firewalld setenforce 0 yum install -y gcc gcc-c make wget cd /opt wget https://download.redis.io/releases/redis-5.0.7.tar.gz tar zxvf redis-5.0.7.tar.gz -C /opt/cd /opt/redis-5.0.7/ # 编译 make…

【性能测试】Jmeter —— jmeter计数器

jmeter计数器 如果需要引用的数据量较大&#xff0c;且要求不能重复或者需要递增&#xff0c;那么可以使用计数器来实现 如&#xff1a;新增功能&#xff0c;要求名称不能重复 1&#xff0c;新增计数器 计数器&#xff1a;允许用户创建一个在线程组之内都可以被引用的计数器…

QComboBox条目可选择状态

有时候下拉框需要根据情况&#xff0c;将某些条目设为不可点击状态&#xff0c;或者动态切换为可点击状态&#xff0c;可采用以下方法。 //item1可选ui->comboBox->setItemData(0, QVariant(-1), Qt::UserRole-1);//item2不可选ui->comboBox->setItemData(1, QVari…

2024年5大制作AI电子手册工具推荐

AI电子手册作为一种结合了人工智能技术和传统电子手册功能的新型工具&#xff0c;逐渐成为了企业进行知识管理和信息传递的重要工具&#xff0c;为企业提高效率、优化用户体验。在本文中&#xff0c;LookLook同学将简单介绍一下什么是AI电子手册、对企业有什么好处&#xff0c;…

官网万词霸屏推广 轻松实现百度万词霸屏源码系统 带完整的安装代码包以及搭建教程

系统概述 官网万词霸屏推广源码系统是一款基于先进技术研发的综合性 SEO 工具。它的设计理念是通过智能化的算法和策略&#xff0c;帮助用户快速提升网站在百度等搜索引擎中的排名&#xff0c;实现大量关键词的霸屏效果。该系统整合了多种优化技术&#xff0c;包括关键词研究、…

Kali linux学习入门

Kali linux学习入门 文章目录 Kali linux学习入门Kali Linux简介Kali Linux工具篇Kali Docker安装Docker 更换国内镜像源Kali 安装 docker compose Kali Linux文档篇Kali Linux 社区篇 Kali Linux简介 Kali Linux是专门用于渗透测试linux操作系统&#xff0c;它由BackTrack发展…

【List,ArrayList与顺序表】

目录 1&#xff0c;什么是List 2&#xff0c;List的使用 3&#xff0c;线性表 4&#xff0c;顺序表 4.1 接口的实现 5&#xff0c; ArrayList简介 6&#xff0c;ArrayList的使用 6.1 ArrayList的构造方法 6.2 ArrayList的常见操作 6.3 ArrayList的遍历 7&#xff0c;…

【数据分享】中国高技术产业统计年鉴(2023年)

大家好&#xff01;今天我要向大家介绍一份重要的高技术产业发展情况统计数据资源——《中国高技术产业统计年鉴》。这份年鉴涵盖了从2023年中国高技术产业发展情况的全面数据&#xff0c;并以多格式提供免费下载。&#xff08;无需分享朋友圈即可获取&#xff09; 数据介绍 …

混凝土结构中最小配筋率45ft/fy怎么来的?

文章目录 0. 背景1. 原理解析2. 总结 0. 背景 上学的时候就对混凝土结构规范中关于最小配筋率“ 45 f t / f y 45f_t/f_y 45ft​/fy​”的表述很好奇&#xff0c;今天终于看到解释了。原文来自这里&#xff0c;喜欢的可以关注原作者。 按照原作者的说法&#xff0c;本文的解释…

基于SpringBoot3+Vue3+原生小程序的设计与实现

大家好&#xff0c;我是程序员小孟。 最近开发了一个宠物的小程序&#xff0c;含有详细的文档、源码、项目非常的不错&#xff01; 一&#xff0c;系统的技术栈 二&#xff0c;项目的部署教程 前端部署包&#xff1a;npm i 启动程序&#xff1a;npm run dev 注意事项&…

Python中的@staticmethod和@classmethod装饰器

名词解释 本文主要介绍静态方法staticmethod和类方法classmethod在类中的应用&#xff0c;在介绍这两个函数装饰器之前&#xff0c;先介绍类中的几个名词&#xff0c;便于后面的理解&#xff1a; 类对象&#xff1a;定义的类就是类对象 类属性&#xff1a;定义在__init__ 外…

UML交互图-序列图

概述 序列图又称为时序图、活动序列图&#xff0c;它是一种详细表示对象之间及对象与参与者实例之间交互的图,它由一组协作的对象(或参与者实例)及它们之间可发送的消息组成&#xff0c;它强调消息之间的时间顺序。 序列图主要用于按照交互发生的一系列顺序&#xff0c;显示对…

【C语言】03.分支结构

本文用以介绍分支结构&#xff0c;主要的实现方式为if语句和switch语句。 一、if语句 1.1 if语句 if (表达式)语句表达式为真则执行语句&#xff0c;为假就不执行。在C语言中&#xff0c;0表示假&#xff0c;非0表示真.下图表示if的执行过程&#xff1a; 1.2 else语句 当…

六位一线AI工程师总结大模型应用摸爬滚打一年的心得,网友:全程高能!

六位一线AI工程师和创业者&#xff0c;把在大模型应用开发上摸爬滚打一整年的心得&#xff0c;全&#xff01;分&#xff01;享&#xff01;了&#xff01; &#xff08;奇怪的六一儿童节大礼包出现了&#xff09; 这篇干货长文&#xff0c;一时间成为开发者社区热议的话题。…

大数据之HDFS磁盘扩容(linux磁盘扩容)

之所以扩容,是因为当前大数据平台已经接入了不同来源的数据,当执行mapreduce任务时,会发生磁盘爆满,导致hdfs爆红 具体扩容方案如下: 1、查看云磁盘分区情况 fdisk -l . 可以从图看出&#xff1a; /dev/vda 数据盘磁盘容量为21.5GB&#xff0c;包含/dev/vda1分区 /dev/vdb 数…

外贸干货|如何提高商机转化率?

常常听到外贸业务员抱怨“询盘质量不高”、“有询盘没转化”、“有些客户只是来比价格的”……想必大家都不陌生&#xff01; 但难道只有询盘问题、客户问题吗&#xff1f;我们自身的处理真的没问题吗&#xff1f;我想只有更多的自省自查我们可以控制的问题&#xff0c;优化我们…