提升你的前端技术栈----vite+vue3+vuex+ts+less实现一个超简单的记账本。

简介: 今天我带大家简单学习一下vite+vue3+ts实现一个超简单的记账本,旨在初步入门vite,vue3,vuex和ts。
开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天, 点击查看活动详情

引言

前端是一个发展的非常迅速的领域,如今的前端已经越来越卷,难度也随之上升,从很久之前的有手就行的“切图仔”,到如今的前端工程化。

越来越多的技术涌出。

html5,css3,css4,Less,Sass,stylus,ES6~ES12,babel,webpack,vite,vue2,vue3,React,TypeScript,jq,ajax,axios,VueX,Router......很多很多的技术栈,随着nodejs的推出,成功让js脱离浏览器的桎梏,让前端可以去做后端的事情,去操作数据库,去实现一些请求。

今天我带大家简单学习一下vite+vue3+ts实现一个超简单的记账本,旨在初步入门
vite,vue3,vuex和ts。

因为我们这个项目没做后端,所以数据无法持久性的存储,之后会搭一个后端。

vite与webpack

前端是一个日新月异,发展的非常非常快的领域,他的技术栈更迭速度非常快,需要前端工程师不断地去学习新技术,不能懈怠。

时过境迁,从 webpackRollup 到 Parcel 

工具不断变迁,今天我们来介绍一下当下非常非常非常流行的打包工具----vite。

传统的webpack的不足之处

在讲解vite的优势之前我们先看一下传统的技术栈:webpack的构建的过程。

webpack在build的时候,遇到一些所需的依赖,会跳转到依赖处去分析理解依赖的内容,再回来继续往后构建,而如今前端工程化后,组件间的依赖往往非常复杂,繁琐,webpack在不断的跳转的去构建所额外需要的依赖的时候就会花费大量的时间,导致打包时间也会成倍的增加。

而现在很多项目往往都有复杂的依赖关系,这也导致其越来越慢。

vite的优势

原因一

webpack出现的比较早,那时候浏览器并不支持模块化开发,并不支持ES Modules的标准,那时候的浏览器采用的加载顺序就是从上往下的同步加载。

所以webpack需要把所有的文件都遍历完成,理清依赖关系,定义每个模块的局部变量和全局变量的覆盖顺序,打包成完整的文件后才能交给浏览器去进行加载。

而ES Modules是一种将JavaScript程序拆分为可按需导入的单独模块的机制。

这是vite之所以这么快的第一个原因。

原因二

vite在启动的时候分为 冷启动 和 热更新。

冷启动的快

我们先来说他在冷启动下的快。

Vite在冷启动的时候,将代码分为依赖和源码两部分,源码部分使用ESModules或者CommonJS拆分到很多个小的模块中,

对于依赖部分,Vite使用Esbuild对依赖进行预构建。

Esbuild使用Go语言开发,相对于JavaScript,Go语言是一种编译型语言,在编译阶段就已经将源码转译为机器码。所以比js要快很多很多。

既然底层是大名鼎鼎的Go语言,所以ES Build相比单线程异步的js,他的运行速度和运行效率是要比js快很多的。

Rollup和webpack都没有使用多线程的能力,而ES Build不同,它使用了多线程的优势。

所以也导致了Esbuild构建模块的速度比webpack快到10-100倍。

对于源码部分

Vite省略了webpack遍历打包的时间,这部分工作交给浏览器,基本没有打包的时间,Vite只是在浏览器发送对模块的请求时,拦截请求,对源码进行转换后提供给浏览器,实现了源码的动态导入。

热更新的快

vite在热更新上,不需要对所有的改动都完全重构打包,vite只会对失活的模块进行热重载,而不影响页面的其他部分。

无论项目的规模多大,Vite的热更新也是在原生的ESM上进行的,只会加载当前使用到的模块。

vite的缺陷

Vite的生态与webpack相差甚远,在plugin等方面无法媲美诞生时间久远的webpack。

Vite的开发环境很惊艳,但是因为一些原因,生产环境还是使用Rollup进行构建的,还是需要打包的。

初始化一个项目

既然vite这么香的,那么我们就开始我们的vite+vue3+vuex+ts实现一个超简单的记账本之旅啦。

image.png

打开我们的cmd

输入npm init vite@latest

接下来为我们的项目起名

image.png

然后选择我们要使用的框架,这里我们选择Vue作为开发的框架。

image.png

然后选择语言,这里我选择Ts,当然不熟悉ts的小伙伴也可以选择js作为开发语言。

然后回车。

咦?

瞬间完成了????

vite快也不能这么快吧。

好吧

原来是我们没有下载依赖。

接下来我们cd到项目中去。

然后npm install

下载相关依赖。

静待一会,还是相比webpack肉眼可见的快的完成了项目的创建。

接下来我们使用

npm run dev

来启动项目。

image.png

挖趣

这么快????

接下来我们进入http://localhost:5173/

image.png

看到如下内容,完成了demo的创建。

项目的编写

接下来我们正是进入项目的编写。

image.png

项目结构如上。

我们先删除自动生成的组件HelloWorld.vue,再清空App.vue中的全部内容。

小准备

我们准备一下要用到的依赖

npm i vue-router
npm install element-plus --save
npm install echarts --save

npm install less less-loader --save-dev

main.ts

我们首先修改一下main.ts文件

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from '../router';
import store from '../store'
import menu from './components/menu.vue';
import 'element-plus/dist/index.css'
import * as ECharts from 'echarts'

import ElementPlus from 'element-plus'

const app = createApp(App);
app.use(router);
app.use(store);
app.use(ElementPlus);
app.config.globalProperties.$ECharts = ECharts;
app.component('Menu',menu);
app.mount('#app');

我们抛弃了Vue2的写法,采取了Composition Api的组合式语法。

content1.vue

我们来编写第一个组件。

router.ts

我们创建一个router.js文件。

内容如下:

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

    import demo1 from './src/components/demo1.vue'
    import demo2 from './src/components/demo2.vue'

    interface Routers {
        path:string;
        component:object
    }

    const routes:Array<Routers> = [{
        path:"/demo1",
        component:demo1
    },{
        path:"/demo2",
        component:demo2
    }
    ]

    const router = createRouter({
        history:createWebHashHistory(),
        routes
    })

    export default router;

Menu.vue

接下来我们来编写Menu.vue的内容

<template>
    <div class="Menu">
      <router-link to="/demo1" class="Menu_child">demo1</router-link>
      <router-link to="/demo2" class="Menu_child">demo2</router-link>
    </div>
    <router-view></router-view>
  </template>
  
  <style scoped lang="less">
    @width : 100%;
    @height:10%;
    .Menu {
      width: @width;
      height: @height;
      position: absolute;
      bottom: 0%;
      right: 0;
      left: 0;
      display: flex;
      font-size: 24px;
      justify-content: center;
    }
    .Menu .Menu_child {
      margin-right: 0;
      flex-grow: 1;
    }
  </style>

demo2.vue

<template>
    <header>
        <h1 @click="initCharts">简单展示一下</h1>
    </header>
    <main id="main" class="dark">
        <!-- <div id="content">
            {{fishMoney}},{{VegetablesMoney}},{{meatMoney}}
        </div> -->
    </main>
  </template>
  
  <style scoped>
    #main {
        display: flex;
        justify-content: center;
        width: 600px;
        height: 540px;
    }
    #content {
        width: 360px;
        height: 360px;
    }
  </style>
  
  <script setup lang="ts">
    import echarts from "echarts";
    import { onMounted } from "vue";
    import { ref ,Ref , computed } from "vue";
    import { useStore } from 'vuex';
  
    const store = useStore();
    let fishMoney:Ref<number> = computed(()=>store.state.fishMoney);
    let VegetablesMoney:Ref<number> = computed(()=>store.state.VegetablesMoney);
    let meatMoney:Ref<number> = computed(()=>store.state.meatMoney);
  
    interface Data {
        value:number;
        name:string;
    }
        
    interface Series {
        type:string;
        data:Array<Data>;
        roseType:string
    }    
    interface Option {
        series:Series;
    }
  
    function initCharts(){
        let myChart = echarts.init(document.getElementById('main') as HTMLElement);
        let data:Array<Data> = [
                    {
                        value:fishMoney.value,
                        name:"卖鱼的钱"
                    },
                    {
                        value:VegetablesMoney.value,
                        name:"卖菜的钱"
                    },
                    {
                        value:meatMoney.value,
                        name:"卖肉的钱"
                    }
                ]
        let series:Array<Series> = [
                {
                type: 'pie',
                data,
                roseType: 'area'
                }
            ]
  
        let option = {
            series
        };
        myChart.setOption(option);
    }      
  </script>
  
  

demo1.vue



<template>
  <header>
      <h1>记账</h1>
  </header>
  <main class="dark">
      <div class="content">
          卖鱼的收入:<el-input-number v-model="f" @input="fishMoneyStatus"/>
          卖菜的收入:<el-input-number v-model="v" @input="VegetablesMoneyStatus"/>
          卖肉的收入:<el-input-number v-model="m" @input="meatMoneystatus"></el-input-number>
      </div>
      <el-button type="primary">帮助</el-button>
  </main>
</template>

<style scoped>
  .content {
      display: flex;
      justify-content: center;
  }
</style>

<script setup lang="ts">
  import { ref ,Ref , computed } from "vue";
  import { useStore } from 'vuex';

  const store = useStore();
  let f:Ref<number> = ref(0);
  let v:Ref<number> = ref(0);
  let m:Ref<number> = ref(0);
  let fishMoney:Ref<number> = computed(()=>store.state.fishMoney);
  let VegetablesMoney:Ref<number> = computed(()=>store.state.VegetablesMoney);
  let meatMoney:Ref<number> = computed(()=>store.state.meatMoney);

  // f = fishMoney;
  // v = VegetablesMoney;
  // m = meatMoney;

  function fishMoneyStatus() {
    store.commit('fishMoneyStatus',f);
    console.log(f);
    console.log(computed(()=>store.state.fishMoney).value);
  }

  function VegetablesMoneyStatus() {
    store.commit('VegetablesMoneyStatus',v);
  }

  function meatMoneystatus() {
    store.commit('meatMoneystatus',m);
  }

</script>

最后看一下Menu.vue文件,这里引入了路由的使用的菜单

<template>
    <div class="Menu">
      <router-link to="/demo1" class="Menu_child">demo1</router-link>
      <router-link to="/demo2" class="Menu_child">demo2</router-link>
    </div>
    <router-view></router-view>
  </template>
  
  <style scoped lang="less">
    @width : 100%;
    @height:10%;
    .Menu {
      width: @width;
      height: @height;
      position: absolute;
      bottom: 0%;
      right: 0;
      left: 0;
      display: flex;
      font-size: 24px;
      justify-content: center;
    }
    .Menu .Menu_child {
      margin-right: 0;
      flex-grow: 1;
    }
  </style>

最后新建一个文件夹store 建立一个index.ts文件

内容如下:

import { createStore } from 'vuex';

const store = createStore({
    state(){
        return {
            fishMoney:0,
            VegetablesMoney:0,
            meatMoney:0
        }
    },
    mutations:{
        fishMoneyStatus (state,f):void {
            state.fishMoney = f;
        },
        VegetablesMoneyStatus(state,v):void {
            state.VegetablesMoney = v;
        },
        meatMoneystatus(state,m):void {
            state.meatMoney = m;
        }
    }
})

export default store;
相关文章
|
5天前
|
人工智能 移动开发 前端开发
WeaveFox:蚂蚁集团推出 AI 前端智能研发平台,能够根据设计图直接生成源代码,支持多种客户端和技术栈
蚂蚁团队推出的AI前端研发平台WeaveFox,能够根据设计图直接生成前端源代码,支持多种应用类型和技术栈,提升开发效率和质量。本文将详细介绍WeaveFox的功能、技术原理及应用场景。
295 66
WeaveFox:蚂蚁集团推出 AI 前端智能研发平台,能够根据设计图直接生成源代码,支持多种客户端和技术栈
|
23天前
|
存储 前端开发 JavaScript
前端状态管理:Vuex 核心概念与实战
Vuex 是 Vue.js 应用程序的状态管理模式和库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。本教程将深入讲解 Vuex 的核心概念,如 State、Getter、Mutation 和 Action,并通过实战案例帮助开发者掌握在项目中有效使用 Vuex 的技巧。
|
1月前
|
资源调度 前端开发 JavaScript
vite3+vue3 实现前端部署加密混淆 javascript-obfuscator
【11月更文挑战第10天】本文介绍了在 Vite 3 + Vue 3 项目中使用 `javascript-obfuscator` 实现前端代码加密混淆的详细步骤,包括安装依赖、创建混淆脚本、修改 `package.json` 脚本命令、构建项目并执行混淆,以及在 HTML 文件中引用混淆后的文件。通过这些步骤,可以有效提高代码的安全性。
|
1月前
|
前端开发 JavaScript 开发者
React与Vue:前端框架的巅峰对决与选择策略
【10月更文挑战第23天】React与Vue:前端框架的巅峰对决与选择策略
|
1月前
|
前端开发 JavaScript 数据管理
React与Vue:两大前端框架的较量与选择策略
【10月更文挑战第23天】React与Vue:两大前端框架的较量与选择策略
|
1月前
|
前端开发 JavaScript 开发工具
Vite 4.0 发布,下一代的前端工具链
【10月更文挑战第21天】Vite 4.0 的发布标志着前端开发领域的又一次重要进步。它为开发者带来了更高效、更智能、更具创新性的开发体验,正逐渐成为下一代前端工具链的引领者。
|
1月前
|
JavaScript 前端开发 搜索推荐
Vue的数据驱动视图与其他前端框架的数据驱动方式有何不同?
总的来说,Vue 的数据驱动视图在诸多方面展现出独特的优势,其与其他前端框架的数据驱动方式的不同之处主要体现在绑定方式、性能表现、触发机制、组件化结合、灵活性、语法表达以及与后端数据交互等方面。这些差异使得 Vue 在前端开发领域具有独特的地位和价值。
|
2月前
|
JavaScript 前端开发 算法
前端优化之超大数组更新:深入分析Vue/React/Svelte的更新渲染策略
本文对比了 Vue、React 和 Svelte 在数组渲染方面的实现方式和优缺点,探讨了它们与直接操作 DOM 的差异及 Web Components 的实现方式。Vue 通过响应式系统自动管理数据变化,React 利用虚拟 DOM 和 `diffing` 算法优化更新,Svelte 通过编译时优化提升性能。文章还介绍了数组更新的优化策略,如使用 `key`、分片渲染、虚拟滚动等,帮助开发者在处理大型数组时提升性能。总结指出,选择合适的框架应根据项目复杂度和性能需求来决定。
|
2月前
|
监控 JavaScript 前端开发
前端的混合之路Meteor篇(六):发布订阅示例代码及如何将Meteor的响应数据映射到vue3的reactive系统
本文介绍了 Meteor 3.0 中的发布-订阅模型,详细讲解了如何在服务器端通过 `Meteor.publish` 发布数据,包括简单发布和自定义发布。客户端则通过 `Meteor.subscribe` 订阅数据,并使用 MiniMongo 实现实时数据同步。此外,还展示了如何在 Vue 3 中将 MiniMongo 的 `cursor` 转化为响应式数组,实现数据的自动更新。
|
1月前
|
前端开发 JavaScript 安全
vite3+vue3 实现前端部署加密混淆 javascript-obfuscator
【11月更文挑战第7天】本文介绍了在 Vite 3 + Vue 3 项目中使用 `javascript-obfuscator` 实现前端代码加密混淆的详细步骤。包括项目准备、安装 `javascript-obfuscator`、配置 Vite 构建以应用混淆,以及最终构建项目进行混淆。通过这些步骤,可以有效提升前端代码的安全性,防止被他人轻易分析和盗用。
241 0