Vue3项目框架搭建封装,一次学习,终身受益【万字长文,满满干货】(二)

简介: Vue3项目框架搭建封装,一次学习,终身受益【万字长文,满满干货】

自动化生成项目基本模版

当我们在新建项目时,一般是手动新建文件夹,然后定义项目名字,新建入口文件,index.html,.vue文件,新建router store文件等等,这个是每次新建时必不可少的步骤。

其实,初始化项目的时候,新建的内容都差不多,如果我们能用一行指令,帮助我们生成这些模版文件,我们只需要定义个文件名字,可以显著提升开发体验。

新建项目指令

我在package.json里新增了一个指令 init

"init": "node ./src/common/initTemplate/index.js"

当执行这个命令时,会自动去执行,在本地common 目录下新建的js脚本,在module目录下自动生成一个新的文件。

演示

  • 输入npm run init

会提示用户“正在创建项目”

  • 要求输入项目名称

1686891339180.jpg

  • 确认之后

返回用户“该项目已经创建”,我们在src项目下能看到刚刚新建的目录hehehe,有内置的index.vue,App.vue,main.js,router.js

因为考虑到并不是所有开发者都会用到状态管理库,所以基础模版没有引入。

1686891352659.jpg

  • 执行npm run dev 之后

就可以在浏览器里看到我们刚刚生成的hehehe 项目了!

1686891370617.jpg

  • 重复名检测

当新建的项目已有时,会提示用户,“目录已经存在”,要求用户继续输入

1686891382899.jpg

代码实现

下图是initTempate 文件结构

实现比较简单

核心代码在 src/common/initTemplate/index.js

template文件夹是我们要生成的项目模版

initTemplate
├── index.js
└── template
    ├── App.vue
    ├── main.js
    ├── router.js
    └── view
        └── index.vue
// 2 directories, 5 files

inquirer

这个库用来询问用户输入项目名称,这是一个比较在处理命令行交互比较常见的库,详情可以查阅文档

前端Node命令行交互工具 —— inquirer

用vue-cli脚手架新建项目的应该都进行过命令交互,vue创建的时候会让你选择vue2还是vue3,也有多选要什么配置,也有输入y或者n选择是否用history路由等,这其实用inquire这个包都能实现。

fs.access

fs.access()方法可以用于测试文件是否存在

流程图

1686891420802.jpg

代码

#!/usr/bin/env node
console.log('您正在创建项目')
const path = require('path')
const fs = require('fs')
const inquirer = require('inquirer')
const stat = fs.stat
const targetDir = path.resolve(__dirname, './template')
//copy文件目录常用函数,都是常见api,
const copyFile = (targetDir, resultDir) => {
  // 读取文件、目录
  fs.readdir(targetDir, function(err, paths) {
    if (err) {
      throw err
    }
    paths.forEach(function(p) {
      const target = path.join(targetDir, '/', p)
      const res = path.join(resultDir, '/', p)
      let read
      let write
      stat(target, function (err, statsDta) {
        if (err) {
          throw err
        }
        if (statsDta.isFile()) {
          read = fs.createReadStream(target)
          write = fs.createWriteStream(res)
          read.pipe(write)
        } else if (statsDta.isDirectory()) {
          fs.mkdir(res, function() {
            copyFile(target, res)
          })
        }
      })
    })
  })
}
const question = [
  {
    type: 'input',
    name: 'name',
    message: '请输入项目名称:'
  }
]
const createProject = () => {
  // 询问用户问题
  inquirer.prompt(question).then(({ name }) => {
    // name 为输入的项目名称
    name = name.trim()
    if (!name) {
      console.log('项目目录不能为空')
      // 如果输入空,继续询问
      createProject()
      return false
    }
    // 目标路径,要放在module目录下
    const resultDir = path.resolve(__dirname, '../../module/', name)
    // fs.access()方法用于测试文件是否存在
    fs.access(resultDir, function(err, data) {
      if (err) {
        // 创建文件
        fs.mkdir(resultDir, function(err, data) {
          if (err) {
            throw err
          }
          // 复制模版文件
          copyFile(targetDir, resultDir)
        })
        console.log(`${name} 项目已创建成功`)
      } else {
        console.log(`${name} 项目目录已存在,请输入其他名称`)
        // 不存在,继续询问
        createProject()
      }
    })
  }).catch(err => {
    console.log(err)
  })
}
createProject()

Pinia状态管理

1686891466597.jpg

文档地址:pinia.web3doc.top/

Pinia /piːnjʌ/ 中文名:皮你啊

Pinia 优势

1.Pinia是一个全新的Vue状态管理库,是Vuex的代替者,尤雨溪强势推荐

翻译翻译 => 官方背书

2.Vue2 和 Vue3 都能支持

翻译翻译 => 既支持options api 又支持compostions api,维护成本低

3.抛弃传统的 Mutation ,只有 state, getter 和 action ,简化状态管理库

翻译翻译 => 少写代码,降低心智负担,再也不用写 mutation

4.不需要嵌套模块,符合 Vue3 的 Composition api,让代码扁平化

翻译翻译 => 多个state,不需要再使用module,现在可以定义多个store,相互之间调用

5.TypeScript支持

翻译翻译 => 没有使用ts,不好解释

6.代码简单,很好的代码自动分割

翻译翻译 => 可以构建多个store,打包管理会自动拆分模块化的设计,便于拆分状态,能很好支持代码分割;

7.极轻, 仅有 1 KB

翻译翻译 => 体积小,不会成为项目的负担

核心概念

  1. State: 用于存放数据,有点儿类似 data 的概念;
  2. Getters: 用于获取数据,有点儿类似 computed 的概念;
  3. Actions: 用于修改数据,有点儿类似 methods 的概念;
  4. Plugins: Pinia 插件。

Pinia与Vuex代码分割机制

举个例子:某项目有3个store「user、job、pay」,另外有2个路由页面「首页、个人中心页」首页用到job store,个人中心页用到了user store,分别用Pinia和Vuex对其状态管理。

1686891486436.jpg

Vuex的代码分割

打包时,vuex会把3个store合并打包,当首页用到Vuex时,这个包会引入到首页一起打包,最后输出1个js chunk。这样的问题是,其实首页只需要其中1个store,但其他2个无关的store也被打包进来,造成资源浪费。

解决方案:

经常在首页优化时,会考虑到这个场景,一般处理方案是去做vuex的按需加载,beforeCreate 的时候,可以去判断当前页面需要加载哪些store,利用这个api可以实现$store.registerModule

详情可参考文章

vuex按需加载,避免首页初始化所有数据

pinia的代码分割

打包时,Pinia会检查引用依赖,当首页用到job store,打包只会把用到的store和页面合并输出1个js chunk,其他2个store不耦合在其中。Pinia能做到这点,是因为它的设计就是store分离的,解决了项目的耦合问题。

1686891518716.jpg

基本使用

定义state,getters 和vuex基本一样,具体使用可以去官网学

这里仅仅对比修改数据时,两者的区别

明显pinia 的代码量更少,逻辑更清晰,心智负担更小

//store.js
import { defineStore } from 'pinia'
export const main = defineStore('main', {
  state: () => {
    return {
      configInfo: {}
    }
  },
  getters: {},
  actions: {}
})
import * as piniaStore from '../piniaStore'
piniaStore.main().$patch({
    configInfo: data
})
//store.js
import { createStore } from 'vuex'
export const store = createStore({
  state: {
    count: 0
  },
  getters: {},
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {},
  modules: {}
})
export default store
//index.vue
import { useStore } from 'vuex'
const storeVuex = useStore()
storeVuex.commit('increment')

总结

总得来说,Pinia 就是 Vuex 的替代版,可以更好的兼容 Vue2,Vue3以及TypeScript。在Vuex的基础上去掉了 Mutation,只保留了 state, getter和action。

Pinia拥有更简洁的语法, 扁平化的代码编排,符合Vue3 的 Composition api


相关文章
|
27天前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
128 64
|
27天前
|
JavaScript 前端开发 API
Vue 3 中 v-model 与 Vue 2 中 v-model 的区别是什么?
总的来说,Vue 3 中的 `v-model` 在灵活性、与组合式 API 的结合、对自定义组件的支持等方面都有了明显的提升和改进,使其更适应现代前端开发的需求和趋势。但需要注意的是,在迁移过程中可能需要对一些代码进行调整和适配。
108 60
|
2天前
|
JavaScript API 数据处理
vue3使用pinia中的actions,需要调用接口的话
通过上述步骤,您可以在Vue 3中使用Pinia和actions来管理状态并调用API接口。Pinia的简洁设计使得状态管理和异步操作更加直观和易于维护。无论是安装配置、创建Store还是在组件中使用Store,都能轻松实现高效的状态管理和数据处理。
12 3
|
1月前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱前端的大一学生,专注于JavaScript与Vue,正向全栈进发。博客分享Vue学习心得、命令式与声明式编程对比、列表展示及计数器案例等。关注我,持续更新中!🎉🎉🎉
39 1
vue学习第一章
|
27天前
|
前端开发 JavaScript 测试技术
Vue3中v-model在处理自定义组件双向数据绑定时,如何避免循环引用?
Web 组件化是一种有效的开发方法,可以提高项目的质量、效率和可维护性。在实际项目中,要结合项目的具体情况,合理应用 Web 组件化的理念和技术,实现项目的成功实施和交付。通过不断地探索和实践,将 Web 组件化的优势充分发挥出来,为前端开发领域的发展做出贡献。
31 8
|
26天前
|
存储 JavaScript 数据管理
除了provide/inject,Vue3中还有哪些方式可以避免v-model的循环引用?
需要注意的是,在实际开发中,应根据具体的项目需求和组件结构来选择合适的方式来避免`v-model`的循环引用。同时,要综合考虑代码的可读性、可维护性和性能等因素,以确保系统的稳定和高效运行。
30 1
|
26天前
|
JavaScript
Vue3中使用provide/inject来避免v-model的循环引用
`provide`和`inject`是 Vue 3 中非常有用的特性,在处理一些复杂的组件间通信问题时,可以提供一种灵活的解决方案。通过合理使用它们,可以帮助我们更好地避免`v-model`的循环引用问题,提高代码的质量和可维护性。
35 1
|
27天前
|
JavaScript
在 Vue 3 中,如何使用 v-model 来处理自定义组件的双向数据绑定?
需要注意的是,在实际开发中,根据具体的业务需求和组件设计,可能需要对上述步骤进行适当的调整和优化,以确保双向数据绑定的正确性和稳定性。同时,深入理解 Vue 3 的响应式机制和组件通信原理,将有助于更好地运用 `v-model` 实现自定义组件的双向数据绑定。
|
1月前
|
JavaScript 前端开发 API
从Vue 2到Vue 3的演进
从Vue 2到Vue 3的演进
40 0
|
1月前
|
JavaScript 前端开发 API
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
57 0