Vue3+vite个人博客网站从0-1(element-plus组件库引入+首页样式布局)

简介: Vue3+vite个人博客网站从0-1(element-plus组件库引入+首页样式布局)

接着上一节,这一章主要是将element-plus组件库引入到项目中,然后将咱们之前漏掉的css预处理器给安装上来,然后讲首页基本显示出来,如果没有从第一章开始的


安装element-plus

NPM

npm install element-plus --save

Yarn

yarn add element-plus


安装完成之后我们这边使用的是一个全局引入 在main.js中引入

ec4e59fefb53435d87bc9e87528609e6.png


import { createApp } from 'vue'
import App from './App.vue'
import './index.css'
// 引入 router
import router from './router/index'
// 引入 store
import store from './store/index'
// 引入element-plus
import ElementPlus from 'element-plus'
import '../node_modules/element-plus/theme-chalk/index.css'
createApp(App).use(router).use(store).use(ElementPlus).mount('#app')


安装之后尝试在咱们的项目中运行看是否可以运行在home.js中运行

<template>
  <div class="block">
    <span class="demonstration"
      >Child options expand when clicked (default)</span
    >
    <el-cascader
      v-model="value"
      :options="options"
      @change="handleChange"
    ></el-cascader>
  </div>
  <div class="block">
    <span class="demonstration">Child options expand when hovered</span>
    <el-cascader
      v-model="value"
      :options="options"
      :props="props"
      @change="handleChange"
    ></el-cascader>
  </div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const value = ref([])
const props = {
  expandTrigger: 'hover',
}
const handleChange = (value) => {
  console.log(value)
}
const options = [
  {
    value: 'guide',
    label: 'Guide',
    children: [
      {
        value: 'disciplines',
        label: 'Disciplines',
        children: [
          {
            value: 'consistency',
            label: 'Consistency',
          },
          {
            value: 'controllability',
            label: 'Controllability',
          },
        ],
      },
      {
        value: 'navigation',
        label: 'Navigation',
        children: [
          {
            value: 'side nav',
            label: 'Side Navigation',
          },
          {
            value: 'top nav',
            label: 'Top Navigation',
          },
        ],
      },
    ],
  },
  {
    value: 'component',
    label: 'Component',
    children: [
      {
        value: 'basic',
        label: 'Basic',
        children: [
          {
            value: 'layout',
            label: 'Layout',
          },
          {
            value: 'button',
            label: 'Button',
          },
        ],
      },
      {
        value: 'form',
        label: 'Form',
        children: [
          {
            value: 'radio',
            label: 'Radio',
          },
          {
            value: 'select',
            label: 'Select',
          },
          {
            value: 'cascader',
            label: 'Cascader',
          },
          {
            value: 'switch',
            label: 'Switch',
          },
          {
            value: 'slider',
            label: 'Slider',
          },
          {
            value: 'time-picker',
            label: 'TimePicker',
          },
          {
            value: 'date-picker',
            label: 'DatePicker',
          },
          {
            value: 'form',
            label: 'Form',
          },
        ],
      },
      {
        value: 'data',
        label: 'Data',
        children: [
          {
            value: 'table',
            label: 'Table',
          },
          {
            value: 'badge',
            label: 'Badge',
          },
        ],
      },
      {
        value: 'notice',
        label: 'Notice',
        children: [
          {
            value: 'alert',
            label: 'Alert',
          },
          {
            value: 'notification',
            label: 'Notification',
          },
        ],
      },
      {
        value: 'navigation',
        label: 'Navigation',
        children: [
          {
            value: 'menu',
            label: 'Menu',
          }
          },
        ],
      },
      {
        value: 'others',
        label: 'Others',
        children: [
          {
            value: 'dialog',
            label: 'Dialog',
          }
        ],
      },
    ],
  },
  {
    value: 'resource',
    label: 'Resource',
    children: [
      {
        value: 'axure',
        label: 'Axure Components',
      },
      {
        value: 'sketch',
        label: 'Sketch Templates',
      },
      {
        value: 'docs',
        label: 'Design Documentation',
      },
    ],
  },
]
</script>
<style lang="scss" scoped>
.block {
  margin: 1rem;
}
.demonstration {
  margin: 1rem;
}
</style>


会发现报错

aac6286b9af24cb6a9cf1131e5378242.png


没有安装css预处理器


咱们这边项目使用less


在安装less之前如果没有安装淘宝镜像的记得先安装淘宝镜像


我们可运行先下面这条命令来查看,yarn的下载依赖包的仓库地址是否已经安装淘宝镜像


yarn config get registry


如果已经安装了可以忽略下面几个步骤


如果没有安装就需要安装一下淘宝镜像


yarn config set registry https://registry.npm.taobao.org -g

npm config set registry https://registry.npm.taobao.org


然后安装好之后就可以直接安装less


安装一下less


在vite中不再需要安装less-loader,只需要安装less就好了(血的教训)


npm i less -D


到这里安装less之后不要忙着运行项目 先把sass改成我们的less在运行项目

<template>
  <div class="block">
    <span class="demonstration"
      >Child options expand when clicked (default)</span
    >
    <el-cascader
      v-model="value"
      :options="options"
      @change="handleChange"
    ></el-cascader>
  </div>
  <div class="block">
    <span class="demonstration">Child options expand when hovered</span>
    <el-cascader
      v-model="value"
      :options="options"
      :props="props"
      @change="handleChange"
    ></el-cascader>
  </div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const value = ref([])
const props = {
  expandTrigger: 'hover',
}
const handleChange = (value) => {
  console.log(value)
}
const options = [
  {
    value: 'guide',
    label: 'Guide',
    children: [
      {
        value: 'disciplines',
        label: 'Disciplines',
        children: [
          {
            value: 'consistency',
            label: 'Consistency',
          },
          {
            value: 'controllability',
            label: 'Controllability',
          },
        ],
      },
      {
        value: 'navigation',
        label: 'Navigation',
        children: [
          {
            value: 'side nav',
            label: 'Side Navigation',
          },
          {
            value: 'top nav',
            label: 'Top Navigation',
          },
        ],
      },
    ],
  },
  {
    value: 'component',
    label: 'Component',
    children: [
      {
        value: 'basic',
        label: 'Basic',
        children: [
          {
            value: 'layout',
            label: 'Layout',
          },
          {
            value: 'button',
            label: 'Button',
          },
        ],
      },
      {
        value: 'form',
        label: 'Form',
        children: [
          {
            value: 'radio',
            label: 'Radio',
          },
          {
            value: 'select',
            label: 'Select',
          },
          {
            value: 'cascader',
            label: 'Cascader',
          },
          {
            value: 'switch',
            label: 'Switch',
          },
          {
            value: 'slider',
            label: 'Slider',
          },
          {
            value: 'time-picker',
            label: 'TimePicker',
          },
          {
            value: 'date-picker',
            label: 'DatePicker',
          },
          {
            value: 'form',
            label: 'Form',
          },
        ],
      },
      {
        value: 'data',
        label: 'Data',
        children: [
          {
            value: 'table',
            label: 'Table',
          },
          {
            value: 'badge',
            label: 'Badge',
          },
        ],
      },
      {
        value: 'notice',
        label: 'Notice',
        children: [
          {
            value: 'alert',
            label: 'Alert',
          },
          {
            value: 'notification',
            label: 'Notification',
          },
        ],
      },
      {
        value: 'navigation',
        label: 'Navigation',
        children: [
          {
            value: 'menu',
            label: 'Menu',
          }
          },
        ],
      },
      {
        value: 'others',
        label: 'Others',
        children: [
          {
            value: 'dialog',
            label: 'Dialog',
          }
        ],
      },
    ],
  },
  {
    value: 'resource',
    label: 'Resource',
    children: [
      {
        value: 'axure',
        label: 'Axure Components',
      },
      {
        value: 'sketch',
        label: 'Sketch Templates',
      },
      {
        value: 'docs',
        label: 'Design Documentation',
      },
    ],
  },
]
</script>
<style lang="less" scoped>
.block {
  margin: 1rem;
}
.demonstration {
  margin: 1rem;
}
</style>


如果到这里页面上显示出来就说明引入成功了


到这里咱们的element-puls和咱们的css预处理器就已经安装完成了


接下里就可以吧咱们的首页的静态页面完成。


创建公共头部

src/components/layout/nav-bar.vue

<template>
      <!--导航-->
  <div>
    <div class="animate__animated animate__fadeIn title"  :style="{'background-image': bgUrl}"></div>
    <el-header  class="animate__animated animate__fadeIn">
      <h2 class="animate__animated animate__swing logo" >haihai</h2>
      <div class="menu-expend">
        <i class="el-icon-menu"></i>
      </div>
      <div class="search_input">
        <el-input
                class="search"
                placeholder="请输入内容"
                prefix-icon="el-icon-search">
        </el-input>
      </div>
    </el-header>
  </div>
</template>
<script>
export default {
  data () {
    return {
      bgUrl:'url(http://img.haihaina.cn/Shinichi6.jpeg)'
    }
  }
}
</script>
<style>
  .search input.el-input__inner {
    background-color: rgba(0, 0, 0, 0.1);
    /*border-radius: 20px;*/
    color: #cccccc;
  }
</style>
<style scoped lang="less">
  .title {
    position: fixed;
    top: 0;
    width: 100%;
    height: 120vh;
    background-repeat: no-repeat;
    background-size: cover;
    border-bottom: 3px solid #fff;
  }
  .el-header {
    transition: .2s;
  }
  .el-header:hover {
    opacity: 1 !important;
  }
  .el-menu {
    background-color: rgba(0, 0, 0, 0) !important;
  }
  .el-menu /deep/ .el-menu-item{
    background-color: rgba(0, 0, 0, 0) !important;
  }
  .el-menu /deep/ .el-menu-item i {
    color: rgba(255, 255, 255);
  }
  .el-menu /deep/ .el-menu-item:hover i {
    color: white;
  }
  .el-menu /deep/ .el-menu-item:hover {
    background-color: rgba(0, 0, 0, 0.5) !important;
  }
  .search_input {
    position: relative;
    box-sizing: border-box;
  }
  .search_input ul {
    position: absolute;
    top: 30px;
    width: 100%;
    border: 1px solid #e5e9ef;
    margin-top: 1px;
    background: #fff;
    z-index: 10000;
    border-radius: 2px;
    box-shadow: 0 2px 4px rgba(58, 118, 142, 0.16);
    padding: 10px 0;
    font-size: 14px;
    box-sizing: border-box;
  }
  .search_input ul li {
    padding: 0 16px;
    height: 32px;
    line-height: 32px;
    cursor: pointer;
    word-wrap: break-word;
    word-break: break-all;
    display: block;
    color: #222;
    position: relative;
    /*transition: .2 ease;*/
  }
  .search_input ul li:hover {
    background-color: #e8f3ff;
  }
  .search-blog {
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
    padding-left: 20px;
    padding-right: 20px;
  }
  .el-header {
    width: 100%;
    position: sticky;
    top: 0;
    z-index: 9999;
    background-color: rgba(0, 0, 0, 0.2);
    color: #fff;
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 20px;
    > div {
      display: flex;
      align-items: center;
    }
    img {
      height: 40px;
    }
    span {
      margin-left: 15px;
    }
    button {
      opacity: 0.8;
    }
    .el-menu {
      flex-shrink: 0;
    }
    .logo {
      color: #ffd04b;
    }
    .logo:hover {
      cursor: pointer;
    }
  }
  .loginInfo {
    flex-shrink: 0;
    /*background-color: #545c64;*/
    color: white;
    height: 60px;
    border: none;
    width: 160px;
    position: relative;
    .el-avatar {
      width: 36px;
      height: 36px;
      margin: 0 auto;
      z-index: 200;
    }
    .user-option {
      position: absolute;
      top: 60px;
      width: 150px;
      left: 50%;
      transform: translate(-50%, 0);
      font-size: 14px;
      text-align: center;
      line-height: 30px;
      background-color: #fff;
      visibility: hidden;
      opacity: 0;
      color: #333;
      box-shadow: 0 2px 6px 0 rgb(0 0 0 / 10%);
      border: 1px solid #eee;
      border-radius: 5px;
    }
    .logout {
      margin: 10px auto;
      padding: 0;
      width: 100%;
    }
    .logout:hover {
      background-color: #eee;
    }
  }
  .loginInfo:hover {
    cursor: pointer;
    .el-avatar {
      transform: translate(0, 50%) scale(1.5);
      transition: .3s;
    }
    .user-option {
      visibility: visible;
      opacity: 1;
      transition: opacity .4s;
    }
  }
  .zZindex {
    margin-top: 300px;
    padding-top: 100px;
  }
  .menu-expend {
    display: none !important;
  }
  .el-menu-hidden {
    /*display: none;*/
    position: absolute;
    top: 60px;
    left: 0;
    border-top: 1px solid #ccc;
    border-right: none;
    width: 100%;
    .el-menu-item {
      border-bottom: 1px solid #ccc;
    }
  }
  @media screen and (max-width: 1000px) {
    .search_input {
      visibility: hidden;
    }
  }
  @media screen and (max-width: 768px) {
    .el-menu /deep/ .el-menu-item{
      background-color: rgba(0, 0, 0, 0.3) !important;
    }
    .el-menu-demo {
      display: none;
    }
    .title {
      width: 100%;
      background-position-x: center;
    }
    .menu-expend {
      display: block !important;
      position: fixed;
      top: 18px;
      left: 150px;
    }
    .menu-expend:hover {
      color: #ffd04b;
      cursor: pointer;
    }
    .title {
      background-position-y: 0;
    }
  }
</style>


首页

/src/view/home.vue

<template>
  <div>
      <navbar></navbar>
    <el-row style="height: 95vh">
      <el-col :span="24" style="height: 100%">
        <el-card shadow="none" class="welcome">
          <h1 class="tit">
            欢迎来到海海的小窝
            <div class="border"></div>
          </h1>
          <h2 class="intro">{{intro}}</h2>
      <!-- 进入主页 -->
          <div class="bounce down" @click="startRead">
            <i class="el-icon-arrow-down" style="color: white"></i>
          </div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>
<script>
import navbar from '../components/layout/nav-bar.vue'
export default {
  components: {
    navbar
  },
  setup(){
  let intro = '欢迎来到海海的小窝、这里会分享关于编程,开发以及其他方面的一些内容,希望可以对您有所帮助...';
  // 开始进入主页
   const  startRead = ()=>{
     console.log('进入主页')
    }
  return {startRead,intro}
  },
}
</script>
<style scoped lang="less">
  body {
    width: 100%;
  }
  .welcome {
    background-color: rgba(0, 0, 0, 0.1);
    border: none;
    height: 90%;
    position: relative;
    .border {
      width: 812px;
      height: 112px;
      position: absolute;
      top: -6px;
      left: -6px;
      border: 3px solid white;
      box-sizing: border-box;
      animation: clipMe 5s linear infinite;
    }
    .tit {
      box-sizing: border-box;
      position: relative;
      width: 800px;
      height: 100px;
      line-height: 100px;
      box-shadow: inset 0 0 0 1px white;
      margin: 40px auto;
      margin-top: 80px;
      color: white;
      text-align: center;
      font-size: 50px;
      font-weight: normal;
      letter-spacing: 10px;
    }
    .intro {
      letter-spacing: 5px;
      line-height: 50px;
      width: 80%;
      margin: 0 auto;
      text-align: center;
      font-weight: normal;
      color: white;
    }
    .down {
      animation: bounce 2s infinite;
      animation-duration: 3s;
      font-size: 25px;
      position: absolute;
      bottom: 5px;
      left: 50%;
      transform: translateX(-50%);
      display: flex;
      justify-content: center;
      align-items: center;
      width: 50px;
      height: 50px;
      border-radius: 50%;
      border: 2px solid #fff;
    }
    .down:hover {
      animation: none;
      cursor: pointer;
      box-shadow: 0 0 20px 0 white;
      transition: all .2s;
    }
  }
  @keyframes clipMe {
    0%,
    100% {
      clip: rect(0px, 806px, 6px, 0px);
    }
    25% {
      clip: rect(0px, 6px, 112px, 0px);
    }
    50% {
      clip: rect(112px, 812px, 112px, 0px);
    }
    75% {
      clip: rect(0px, 812px, 112px, 806px);
    }
  }
  @keyframes bounce {
    0%, 20%, 50%, 80%, 100% {
      transform: translate(-50%, 0);
    }
    40% {
      transform: translate(-50%, -30px);
    }
    60% {
      transform: translate(-50%, -15px);
    }
  }
  ul {
    padding-left: 10px;
    padding-right: 10px;
    margin-bottom: 0;
    border-radius: 5px;
  }
  .el-pagination {
    padding-bottom: 20px;
  }
  .el-card /deep/ .el-card__body {
    padding: 0;
  }
  .right-item {
    margin-bottom: 20px;
    li:first-child {
      border-top: 1px solid rgba(179, 216, 255, 0.5);
    }
    li {
      border-bottom: 1px solid rgba(179, 216, 255, 0.5);
    }
    .more {
      text-align: center;
      color: #3a8ee6;
      padding: 8px;
    }
    .more:hover {
      cursor: pointer;
      color: #3a8ee6;
    }
    .blog-type:hover, .activeType {
      background-color: rgba(58, 142, 230, 0.3);
      cursor: pointer;
    }
    .tags {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      margin: 15px 13px 0;
      border-bottom: 1px solid rgba(179, 216, 255, 0.5);
    }
    .tag-item {
      display: flex;
      justify-content: space-around;
      align-items: center;
      margin-left: 5px;
      margin-right: 5px;
      margin-bottom: 10px;
      box-sizing: border-box;
      .tag {
        background-color: #ecf5ff;
        box-sizing: border-box;
        display: inline-block;
        height: 22px;
        padding: 0 10px;
        line-height: 22px;
        font-size: 10px;
        color: #409eff;
        border-radius: 4px;
        white-space: nowrap;
        border: 1px solid #409eff;
        transition: .2s;
      }
      .sjx-outer {
        width: 0;
        height: 0;
        border-top: 6px solid transparent;
        border-bottom: 6px solid transparent;
        border-right: 6px solid #409eff;
        position: relative;
        transition: .2s;
      }
      .sjx-inner {
        border-top: 6px solid transparent;
        border-bottom: 6px solid transparent;
        border-right: 6px solid #ecf5ff;
        top: -6px;
        left: 1px;
        position: absolute;
        transition: .2s;
      }
    }
    .tag-item:hover, .activeTag {
      box-sizing: border-box;
      .tag {
        color: white;
        background-color: #409eff;
        cursor: pointer;
      }
      .sjx-inner {
        border-right: 6px solid #409eff;
      }
    }
  }
  .blog-type {
    display: flex;
    justify-content: space-between;
    align-items: center;
    line-height: 40px;
  }
  .recommend-blog {
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
    padding-left: 20px;
    padding-right: 20px;
    a {
      border-bottom: 1px solid rgba(34, 36, 38, .15);
      line-height: 40px;
      display: block;
      text-decoration: none;
      color: black;
    }
    a:hover {
      color: #3a8ee6;
    }
  }
  .total {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: larger;
    font-weight: bold;
    .title {
      display: flex;
      align-items: center;
      .el-icon-back {
        font-weight: bolder;
        color: #3a8ee6;
        margin-right: 10px;
      }
      .el-icon-back:hover {
        cursor: pointer;
      }
    }
  }
  .blog-content:hover {
    /*border-left: 5px solid #3a8ee6;*/
    /*border-right: 5px solid #3a8ee6;*/
    background-color: rgba(58, 142, 230, 0.3);
    cursor: pointer;
    .el-tag {
      color: white;
      background-color: #3a8ee6;
    }
  }
  .blog-content {
    padding: 10px;
    height: auto;
    border-bottom: 1px solid rgb(199, 163, 92);
    /*border-bottom: 1px solid rgba(34, 36, 38, .15);*/
    transition: .3s;
    .el-image {
      border-radius: 5px;
      box-sizing: border-box;
      flex-shrink: 0;
    }
    .blog-info {
      display: flex;
      align-items: center;
      color: rgba(0, 0, 0, .4);
      font-size: 10px;
      .user-info {
        display: flex;
        justify-content: space-around;
        align-items: center;
        margin-right: 15px;
        .el-avatar {
          margin-right: 5px;
          width: 22px;
          height: 22px;
        }
        .header {
          text-decoration: none;
          color: #3a8ee6;
          font-weight: bold;
        }
      }
      .blog-date {
        margin-right: 15px;
      }
      .blog-type {
        margin-left: auto;
      }
    }
  }
  .description {
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    font: 300 1em/1.8 PingFang SC, Lantinghei SC, Microsoft Yahei, Hiragino Sans GB, Microsoft Sans Serif, WenQuanYi Micro Hei, sans-serif;
  }
  @media screen and (max-width: 768px) {
    .blog-date {
      display: none;
    }
    .welcome {
      width: 100%;
      .border {
        display: none;
      }
      .tit {
        font-size: 2rem;
        width: 100%;
        line-height: 50px;
        letter-spacing: 2px;
        height: auto;
      }
      .intro {
        font-size: 1rem;
        line-height: 30px;
      }
    }
    .el-pagination {
      width: 100%;
    }
  }
</style>


运行打开之后大概是这样image.png


本期的内容大概就是这样了,后续会接着更新。

目录
打赏
0
0
0
0
3
分享
相关文章
斩获开发者口碑!SnowAdmin:基于 Vue3 的高颜值后台管理系统,3 步极速上手!
SnowAdmin 是一款基于 Vue3/TypeScript/Arco Design 的开源后台管理框架,以“清新优雅、开箱即用”为核心设计理念。提供角色权限精细化管理、多主题与暗黑模式切换、动态路由与页面缓存等功能,支持代码规范自动化校验及丰富组件库。通过模块化设计与前沿技术栈(Vite5/Pinia),显著提升开发效率,适合团队协作与长期维护。项目地址:[GitHub](https://github.com/WANG-Fan0912/SnowAdmin)。
364 5
Vue 表情包输入组件的实现代码:支持自定义表情库、快捷键发送和输入框联动的聊天表情解决方案
本文详细介绍了在 Vue 项目中实现一个功能完善、交互友好的表情包输入组件的方法,并提供了具体的应用实例。组件设计包含表情分类展示、响应式布局、与输入框的交互及样式定制等功能。通过核心技术实现,如将表情插入输入框光标位置和点击外部关闭选择器,确保用户体验流畅。同时探讨了性能优化策略,如懒加载和虚拟滚动,以及扩展性方案,如自定义主题和国际化支持。最终,展示了如何在聊天界面中集成该组件,为用户提供丰富的表情输入体验。
100 8
Vue 3 中的 nextTick 使用详解与实战案例
Vue 3 中的 nextTick 使用详解与实战案例 在 Vue 3 的日常开发中,我们经常需要在数据变化后等待 DOM 更新完成再执行某些操作。此时,nextTick 就成了一个不可或缺的工具。本文将介绍 nextTick 的基本用法,并通过三个实战案例,展示它在表单验证、弹窗动画、自动聚焦等场景中的实际应用。
165 17
基于 ant-design-vue 和 Vue 3 封装的功能强大的表格组件
VTable 是一个基于 ant-design-vue 和 Vue 3 的多功能表格组件,支持列自定义、排序、本地化存储、行选择等功能。它继承了 Ant-Design-Vue Table 的所有特性并加以扩展,提供开箱即用的高性能体验。示例包括基础表格、可选择表格和自定义列渲染等。
183 6
Vue 2 与 Vue 3 的区别:深度对比与迁移指南
Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架,在过去的几年里,Vue 2 一直是前端开发中的重要工具。而 Vue 3 作为其升级版本,带来了许多显著的改进和新特性。在本文中,我们将深入比较 Vue 2 和 Vue 3 的主要区别,帮助开发者更好地理解这两个版本之间的变化,并提供迁移建议。 1. Vue 3 的新特性概述 Vue 3 引入了许多新特性,使得开发体验更加流畅、灵活。以下是 Vue 3 的一些关键改进: 1.1 Composition API Composition API 是 Vue 3 的核心新特性之一。它改变了 Vue 组件的代码结构,使得逻辑组
403 0
vue2和vue3的响应式原理有何不同?
大家好,我是V哥。本文详细对比了Vue 2与Vue 3的响应式原理:Vue 2基于`Object.defineProperty()`,适合小型项目但存在性能瓶颈;Vue 3采用`Proxy`,大幅优化初始化、更新性能及内存占用,更高效稳定。此外,我建议前端开发者关注鸿蒙趋势,2025年将是国产化替代关键期,推荐《鸿蒙 HarmonyOS 开发之路》卷1助你入行。老项目用Vue 2?不妨升级到Vue 3,提升用户体验!关注V哥爱编程,全栈开发轻松上手。
225 2
高效工作流:用Mermaid绘制你的专属流程图;如何在Vue3中导入mermaid绘制流程图
mermaid是一款非常优秀的基于 JavaScript 的图表绘制工具,可渲染 Markdown 启发的文本定义以动态创建和修改图表。非常适合新手学习或者做一些弱交互且自定义要求不高的图表 除了流程图以外,mermaid还支持序列图、类图、状态图、实体关系图等图表可供探索。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
你真的会使用Vue3的onMounted钩子函数吗?Vue3中onMounted的用法详解
onMounted作为vue3中最常用的钩子函数之一,能够灵活、随心应手的使用是每个Vue开发者的必修课,同时根据其不同写法的特性,来选择最合适最有利于维护的写法。博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
Pinia 如何在 Vue 3 项目中进行安装和配置?
Pinia 如何在 Vue 3 项目中进行安装和配置?
300 4
登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问