在认识vue3全家桶之前,先简单回顾一下vue2的全家桶

一.在vue2中,全家桶技术栈

技术栈: vue2 +vue-cli + vuex@3+vue-router@3+webpack + elementUI + vue-resource

1.vue-cli 脚手架构建vue项目,CLI 服务是构建于 webpack 和 webpack-dev-server构建快速生成一个vue2的开发项目。

// 安装 vue/cl
npm install -g @vue/cli
// 快速构建 my-project 项目
vue create my-project

node环境要求

 Vue CLI 4.x 需要 Node.js v8.9 或更高版本 (推荐 v10 以上)

2.vue-router 页面路由,主要版本是4之前的版本

vue2项目直接安装: npm i vue-router默认安装最新版本,不兼容vue2,推荐指定特定版本安装

npm i vue-router@3.5.2

3.vuex: 状态管理,vue2兼容版本目前是vuex@3

npm i vuex@3

4.UI组件库

pc组件库

element-ui 
iView 
Ant Design 
Boostrap
...

移动端组件库

 Vantui 
 Mintui  
 NuTUI  
 ...

5.vue-resource vue自带的http请求插件

仓库源码:https://github.com/pagekit/vue-resource
使用文档: https://github.com/pagekit/vue-resource/blob/develop/docs/http.md

安装

npm install vue-resource 或者 yarn add vue-resource

基本使用

main.js入口文件配置
Import VueResource form ‘vue-resource’
Vue.use(VueResource)
vue组件中使用

// GET /someUrl?foo=bar

  this.$http.get('/someUrl', {params: {foo: 'bar'}, headers: {'X-Custom': '...'}}).then(response => {
    // success callback
  }, response => {
    // error callback
  });

// POST /someUrl

  this.$http.post('/someUrl', {foo: 'bar'}).then(response => {

    // get status
    response.status;

    // get status text
    response.statusText;

    // get 'Expires' header
    response.headers.get('Expires');

    // get body data
    this.someData = response.body;

  }, response => {
    // error callback
  });

更多的使用方式请参考文档

二.在vue3中,全家桶技术栈

技术栈:vue3 +vite + pinia(或者vuex@4)+vue-router@4 + axios + elementPlus

1.项目脚手架

(1) 使用 Vite 来创建一个 Vue 项目,npm init vue@latest这个命令会安装和执行 create-vue,它是 Vue 提供的官方推荐脚手架工具

npm init vue@latest
npm init vue@3
npm init vue@2

或者
npm create vue@3
npm create vue@2

(2) Vue CLI方式:和vue2构建方式一样,这样是依赖webpack构建,注意版本兼容

2.vue-router@4

(1) 安装方式

npm install vue-router@4
或者
yarn add vue-router@4

(2). 常用的API

createRouter 建一个可以被 Vue 应用程序使用的路由实例。查看 RouterOptions 中的所有可以传递的属性列表
createWebHistory 创建一个 HTML5 历史,即单页面应用程序中最常见的历史记录。应用程序必须通过 http 协议被提供服务
createWebHashHistory 创建一个 hash 历史记录。对于没有主机的 web 应用程序 (例如 file://),或当配置服务器不能处理任意 URL 时这非常有用。

注意:如果 SEO 对你很重要,你应该使用 createWebHistory

import { createRouter, createWebHistory,createWebHashHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(),
  // history: createWebHashHistory(),
  routes: [
    {
      path: '/',
      name: 'home',
      component: () => import('../views/HomeView.vue')
    },
    {
      path: '/about',
      name: 'about',
      component: () => import('../views/AboutView.vue')
    }
  ]
})

export default router
useRoute 返回当前路由地址。相当于在模板中使用 $route。必须在 setup() 中调用
useRouter 返回 router 实例。相当于在模板中使用 $router。必须在 setup() 中调用。
路由跳转示例
<script lang="ts" setup>
import { useRouter } from "vue-router";

const router = useRouter()

// 字符串路径
router.push('/users/eduardo')

// 带有路径的对象
router.push({ path: '/users/eduardo' })

// 命名的路由,并加上参数,让路由建立 url
router.push({ name: 'user', params: { username: 'eduardo' } })

// 带查询参数,结果是 /register?plan=private
router.push({ path: '/register', query: { plan: 'private' } })

// 带 hash,结果是 /about#team
router.push({ path: '/about', hash: '#team' })


</script >
路由接受参数示例
<script lang="ts" setup>
import { useRoute } from "vue-router";

// 接收参数
const username  = route.params.username

// 带查询参数
const plan  = route.query.plan

// 带查询参数
const plan  = route.query.plan

// 带 hash
const hash =  route.hash
</script >

3.状态管理

(1) vuex@4 - 目前兼容vue3

vuex的基本5大核心概念

State
Getter
Mutation
Action
Module

vuex@4的安装

npm install vuex@next --save 或者 yarn add vuex@next --save
基本用法示例
modules/moduleTest.js 模块
export default { 
   state () {
       return {
            count: 0
       }
    },
    mutations: {
        // 负责修改state中的count值
        countMutations (state, newVal) {
            state.count = newVal
        }
    },
    actions: {
        countActions ({ commit }, params) {
            // 触发mutations中的countMutations函数并传递参数
            commit("countMutations", params)
        }
    }
}
store/index.js
import { createStore } from 'vuex'
import moduleTest from './modules/moduleTest'

// 创建一个新的 store 实例
export default createStore({
    state () {
        return {
            sum: 0
        }
    },
    mutations: {
        // 负责修改state中的count值
        sumMutations (state, newVal) {
            state.sum += newVal
        }
    },
    actions: {
        sumActions ({ commit }, params) {
            // 触发mutations中的countMutations函数并传递参数
            setTimeout(()=>{
                commit("sumMutations", params)
            },300)
        }
    },
    getters: {
        getSum: state => state.sum
    },
    modules: {
        moduleTest
    }
})
src/main.js入口文件
import { createApp } from "vue";
import App from "./App.vue";
import store from "./store";
 
createApp(App)
  .use(store)
  .mount("#app");
vue3混合API使用vuex方式
<script setup lang="ts">
   import { computed,ref } from 'vue'
    import { mapState,useStore} from 'vuex'

    const {commit,dispatch,state,getters,actions} = useStore();
    const count = ref(0)
    const inp1 = ref(0)
    const inp2 = ref(0)

   // 映射 this.count 为 store.state.count
   const getStateCount = computed(()=> state.moduleTest.count)
   const getStateSum = computed(()=> state.sum)

   // 点击按钮操作数据修改
   const addCountMutations = () => {
      commit('countMutations',count.value++)
   }

   const addCountActions = () => {
      dispatch('countActions', count.value++)
   }

   const addSumMutations = () => {
     commit('sumMutations',Number(inp1.value) + Number(inp2.value))
   }

   const addSumActions = () => {
    dispatch('sumActions', Number(inp1.value) + Number(inp2.value))
 }
  
</script>

<template>
  <main>
       <div style="margin-bottom:20px">
          <span>state: 展示count的值: {{getStateCount}}</span>
          <span>getters: 展示count的值: {{getters.count}}</span><br>

          <button @click="addCountMutations">点击Mutations++</button>
          <button @click="addCountActions">点击Actions++</button><br>
        
       </div>
       <input v-model="inp1"/>
       <input v-model="inp2"/><br>
       <button @click="addSumMutations">求和mutations同步方式</button>
       <button @click="addSumActions">求和actions异步方式</button><br>
       <span>获取两个input框求和结果:state=>{{ getStateSum }} getters=>{{getters.getSum}}</span>
  </main>
</template>

(2) pinia状态管理

为什么要使用 Pinia?使用pinia的有什么优势?

dev-tools 支持
跟踪动作、突变的时间线
Store 出现在使用它们的组件中
time travel 和 更容易的调试
热模块更换
在不重新加载页面的情况下修改您的 Store
在开发时保持任何现有状态
插件:使用插件扩展 Pinia 功能
为 JS 用户提供适当的 TypeScript 支持或 autocompletion
服务器端渲染支持

与 Vuex 的比较

与 Vuex 相比,Pinia 提供了一个更简单的 API,具有更少的规范,提供了 Composition-API 风格的 API,最重要的是,在与 TypeScript 一起使用时具有可靠的类型推断支持。此外,pinia已经实现vuex@5大部分功能,因此pinia可以被称为vuex@5。

pinia在vuex上基础上不同:

一是去掉 mutations,它的存在显得流程过于复杂和冗余
二是不再需要注入、导入函数、调用函数、享受自动完成功能!
三是无需动态添加 Store,默认情况下它们都是动态的
四是不再有 modules 的嵌套结构
五是 没有 命名空间模块。鉴于 Store 的扁平架构,“命名空间” Store 是其定义方式所固有的,您可以说所有 Store 都是命名空间的。

在vue3项目如何安装和注册pinia
安装
yarn add pinia
# 或者使用 npm
npm install pinia
引入main.ts入口文件
import { createApp } from 'vue'
import { createPinia } from 'pinia'

import App from './App.vue'
import router from './router'

const app = createApp(App)

app.use(createPinia())
app.use(router)

app.mount('#app')
在store仓库中使用
stores/counter.ts 文件中定义

函数方式一

import { ref, computed } from 'vue';
import { defineStore } from 'pinia';

 const useCounterStore = defineStore('counter', () => {
  // state定义状态变量count/sum
  const count = ref(0);
  const sum = ref(0);

  // getters中获取计算结果 doubleCount
  const doubleCount = computed(() => count.value * 2);

  // actions直接操作state状态变量修改
  function increment() {
    count.value++;
  }

  return { count, doubleCount, increment };
});

对象方式二

import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter',{
  // state定义状态变量count
  state: () => ({ count: 0,sum: 0 }),

  // getters中获取计算结果 doubleCount
  getters: {
    doubleCount: state => state.count * 2
  },

  // actions直接操作state状态变量修改
  actions: {
    increment() {
      this.count++;
    }
  }
});

在vue组件中引入并使用
<template>
    <p>展示count: {{counterStore.count}}</p>
    <p>展示getters计算结果: {{counterStore.doubleCount}}</p>
    <el-button @click="changeCountHanlder">修改count</el-button>
</template>

<script setup lang="ts">
import { useCounterStore } from "@/stores/counter";

// 获取useCounterStore仓库
const counterStore = useCounterStore()

// 触发actions修改state中的count值
const changeCountHanlder = () => {
   // 直接修改单个属性值
  // counterStore.count++

  // 创建对象批量修改多个属性值 
  // 使用这种语法应用某些突变非常困难或代价高昂:任何集合修改(例如,从数组中推送、删除、拼接元素)都需要您创建一个新集合
  // let counts = counterStore.count
  // counterStore.$patch({count: counts + 1, sum: counts + 10})

  // 函数回调函数修改state => 推荐使用
     counterStore.$patch((state: any) => {
        state.count += 1
        state.sum = state.count + 10
     })
}

</script>
Logo

前往低代码交流专区

更多推荐