VUE3基础

一、vue-router v4.x

介绍 | Vue Router

1、安装

javascript 复制代码
yarn add vue-router@next

@next代表最新的版本

2、路由配置

在src目录下,新建router/index.ts,具体配置如下

javascript 复制代码
import {RouteRecordRaw,createRouter,createWebHashHistory} from 'vue-router'
const routes:Array<RouteRecordRaw> = [
    {
        path: '/login',
        component: () => import('../views/Login.vue')
    },
    {
        path: '/register',
        component: () => import('../views/Register.vue')
    },
    {
        path: '/',
        component: () => import('../views/Home.vue')
    }
]
const router=createRouter({
    routes,
    history:createWebHashHistory()
})
export default router

必须在main.ts引入后挂载

javascript 复制代码
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from './router'
​
const app=createApp(App)
app.use(router)
app.mount('#app')

3、路由跳转

路由跳转有两种方式

  • router-link,超链接的方式来跳转

  • 通过useRouter这个hook来进行跳转

javascript 复制代码
<template>
  <div>
    <h1>登录</h1>
    <a href="#" @click="goRegister">没有账号,请注册</a>
  </div>
</template>
​
<script lang='ts' setup>
import { reactive,ref} from 'vue'
import {useRouter} from 'vue-router'
const router=useRouter()
const goRegister=(e:MouseEvent)=>{
  e.preventDefault()
  router.push({
    path:'/register'
  })
}
</script>

4、路由传参

4.1、params参数
  • 配置
javascript 复制代码
const routes:Array<RouteRecordRaw>=[
    {
        path:'/newsDetail/:id',
        component:()=>import('../views/NewsDetail.vue')
    }
]
  • 传参
javascript 复制代码
<template>
  <div>
    <h3>新闻列表</h3>
    <router-link to="/newsDetail/12">乌四地全票通过入俄!梅德韦杰夫:欢迎回家</router-link><br>
    <router-link to="/newsDetail/13">美国副总统哈里斯遭遇车祸</router-link>
  </div>
</template>
  • 接收参数
javascript 复制代码
<script lang='ts' setup>
import { reactive,ref,onMounted} from 'vue'
import {useRoute} from 'vue-router'
const route=useRoute()
onMounted(()=>{
    console.log(route.params.id);
})
</script>
4.2、query参数
  • 配置
javascript 复制代码
const routes:Array<RouteRecordRaw>=[
    {
        path:'/newsDetail',
        component:()=>import('../views/NewsDetail.vue')
    }
]
  • 传参

    方式一:使用<router-link>标签形式进行跳转并且使用?的方式进行传递参数

javascript 复制代码
<router-link to="/newsDetail?id=23">首页</router-link>

方式二:使用router.push方式进行跳转并且使用query属性方式进行传参

javascript 复制代码
<template>
  <div>
    <h3>新闻列表</h3>
    <a href="#" @click="skip($event,12)">乌四地全票通过入俄!梅德韦杰夫:欢迎回家</a><br>
    <a href="#" @click="skip($event,13)">美国副总统哈里斯遭遇车祸</a>
  </div>
</template>

<script lang='ts' setup>
import { reactive,ref} from 'vue'
import {useRouter} from 'vue-router'
const router=useRouter()
const skip=(e:MouseEvent,id:number)=>{
    e.preventDefault()
    router.push({
        path:`/newsDetail`,
        query:{id}
        
    })
}
</script>
  • 接收参数
javascript 复制代码
<script lang='ts' setup>
import { reactive,ref,onMounted} from 'vue'
import {useRoute} from 'vue-router'
const route=useRoute()
onMounted(()=>{
    console.log(route.query.id);
})

</script>

二、vuex v4.x

官网地址:开始 | Vuex

1、安装

javascript 复制代码
yarn add vuex@next

2、配置

  • 在src/store/index.ts创建store实例
javascript 复制代码
import {createStore} from 'vuex'
const store=createStore({
    state(){
        return{
            count:0
        }
    }
})
export default store
  • 在main.js中挂载store
javascript 复制代码
import { createApp } from 'vue'
import App from './App.vue'
import store from './store'
const app=createApp(App)
app.use(store)
app.mount('#app')

3、State

javascript 复制代码
<template>
    <h1>计数器:{{store.state.count}}</h1>
</template>
<script>
import {useStore} from 'vuex'
export default {
    setup(){
      const store=useStore()
      return {store}
    }   
}
</script>

4、Mutation

Counter.vue组件

javascript 复制代码
<template>
    <h1>计数器:{{store.state.count}}</h1>
    <button @click="increment">+</button>
</template>

<script>
import {useStore} from 'vuex'
export default {
    setup(){
      const store=useStore()
      const increment=()=>{
         store.commit('increment')  //store.commit("方法名字")
      }
      return {store,increment}
    }
}
</script>

store/index.js

javascript 复制代码
import {createStore} from 'vuex'
interface State{
    count:number
}
const store=createStore({
    state(){
        return{
            count:0
        }
    },
    mutations:{
        increment(state:State){
            state.count++
        }
    }
})
export default store

5、actions

触发action异步任务时携带参数

javascript 复制代码
import {createStore} from 'vuex'
const store=createStore({
    state(){
        return{
            count:1
        }
    },
    mutations:{
        increment(state:State,n:number){
            state.count+=n
        }
    },
    actions:{
        incrementAsync(context:ActionContext<State,any>,n:number){
           setTimeout(() => {
            context.commit('increment',n)
           }, 2000);
        }
    }
})
export default store

组件中使用store.dispatch()派发异步任务

javascript 复制代码
import {useStore} from 'vuex'
export default {
    setup(){
      const store=useStore()
      const increment=()=>{
        store.dispatch('incrementAsync',3)
      }
      return {store,increment}
    }
}
</script>

6、vuex模块化

6.1、创建modules目录

可以根据项目中数据的分类,来将仓库拆分成多个模块。通常我们会在src/store目录中,创建一个modules目录,用来存放所有的模块文件。

6.2、配置模块

每一个仓库模块中,都需要暴露一个对象出去,同时,需要设置一个属性

javascript 复制代码
import {ActionContext} from 'vuex'
interface State{
    count:number
}
export default{
    namespaced:true,
    state(){
        return{
            count:1
        }
    },
    mutations:{
        increment(state:State,n:number){
            state.count+=n
        }
    },
    actions:{
        incrementAsync(context:ActionContext<State,any>,n:number){
           setTimeout(() => {
            context.commit('increment',n)
           }, 2000);
        }
    }
}
6.3、引入模块

模块配置完成之后,需要在主仓库src/store/index.js文件中引入模块

javascript 复制代码
import {createStore} from 'vuex'
import counter from './modules/counter'
const store=createStore({
   state(){
   },
   mutations:{
   },
   actions:{
   },
   modules:{
    counter
   }
})
export default store
6.4、组件操作模块
javascript 复制代码
<template>
    <h1>计数器:{{store.state.counter.count}}</h1>  <!--store.state.模块名.变量名-->
    <button @click="increment">+</button>
</template>

<script>
import {useStore} from 'vuex'
export default {
    setup(){
      const store=useStore()
      const increment=()=>{
        //store.dispatch("模块名/actions对应方法",参数)
        store.dispatch('counter/incrementAsync',3)  
      }
      return {store,increment}
    }
}
</script>
6.5、辅助函数方式
javascript 复制代码
<template>
  <div>
    <h1>计数器</h1>
    <div>{{count}}</div>
    <button @click="increment(2)">+</button>
  </div>
</template>

<script lang='ts'>
import {createNamespacedHelpers} from 'vuex'
const {mapState,mapActions}=createNamespacedHelpers('couter')
import {computed} from 'vue'
 export default{
   computed:{
    ...mapState(['count'])
   },
   methods:{
    ...mapActions({increment:'incrementAsync'})
   }
 }
</script>

<style lang='scss' scoped>
</style>

三、pinia

1、概念

官网地址:Pinia | The intuitive store for Vue.js

Pinia 是 Vue 的存储库,它允许跨组件/页面共享状态。实际上,pinia就是Vuex的升级版,官网也说过,为了尊重原作者,所以取名pinia,而没有取名Vuex,所以大家可以直接将pinia比作为Vue3的Vuex

2、为什么要使用pinia

  • pinia中只有state、getter、action,抛弃了Vuex中的Mutation,Vuex中mutation一直都不太受小伙伴们的待见,pinia直接抛弃它了,这无疑减少了我们工作量。

  • pinia中action支持同步和异步,Vuex不支持

  • 良好的Typescript支持,毕竟我们Vue3都推荐使用TS来编写,这个时候使用pinia就非常合适了

  • pinia分模块不需要modules

  • 体积非常小,只有1KB左右。

3、安装和配置

在终端执行如下命令进行安装

javascript 复制代码
yarn add pinia

在src/main.ts中引入

javascript 复制代码
import { createApp } from 'vue'
import App from './App.vue'
import {createPinia} from 'pinia'
const pinia=createPinia()
const app=createApp(App)
app.use(pinia)
app.mount('#app')

4、快速入门

  • 在src/store/counter.ts定义store
javascript 复制代码
import {defineStore} from 'pinia'
const useCounterStore =defineStore('counter',{
    state:()=>{
        return{
            count:0
        }
    },
    getters:{
        doubleCount:state=>state.count*2
    },
    actions:{
        increment(){
            this.count++
        }
    }
})
export default useCounterStore
  • 在组件中使用操作store
javascript 复制代码
<template>
  <div>
    <h2>{{count}}</h2>
    <button @click="increment">+</button>
  </div>
</template>

<script lang='ts'>
import useCounterStore from './store/counter'
import {storeToRefs} from 'pinia'
 export default{
   setup(){
    const store=useCounterStore()
    const {count}=storeToRefs(store)
    const {increment}=store
    return{
      count,
      increment
    }
   }
 }
</script>

5、使用

javascript 复制代码
import {defineStore} from 'pinia'

interface IState{
    name:string,
    age:number,
    job:string
}

const useUsersStore=defineStore('users',{
    state:():IState=>{
        return{
            name:'张三丰',
            age: 120,
            job: '掌门'
        }
    },
    getters:{
        getName:(state):string=>state.name,
        getAge:(state):number=>state.age,
        getJob:(state):string=>state.job,
        getUserInfo:(state):string=>`姓名:${state.name}\t年龄:${state.age}\t职业:{state.job}`
    },
    actions:{
        modifyUserInfo(name:string,age:number,job:string){
            this.name=name
            this.age=age
            this.job=job
        }
    }
})
export default useUsersStore

组件中使用store

javascript 复制代码
<template>
  <div>
    <h1>用户信息</h1>
    <div>姓名:{{name}}</div>
    <div>年龄:{{age}}</div>
    <div>职业:{{job}}</div>
    <button @click="modifyUserInfo">修改用户信息</button>
    <button @click="resetUserInfo">重置用户信息</button>
    <button @click="patchUserInfo">批量修改</button>
  </div>
</template>

<script lang='ts'>
 import useUsersStore from './store/users'
 import {storeToRefs} from 'pinia'
 export default{
   setup(){
    const store=useUsersStore()
    const {name,age,job}=storeToRefs(store)
    const modifyUserInfo=():void=>{
      store.modifyUserInfo('杨逍',20,'明教左使')
    }
    const resetUserInfo=():void=>{
      store.$reset()
    }
    const patchUserInfo=():void=>{
      store.$patch({
        name:'周芷若',
        age:21
      })
    }
    return {
      name,age,job,
      modifyUserInfo,
      resetUserInfo,
      patchUserInfo
    }
   }
 }
</script>

<style lang='scss' scoped>
</style>

6、持久化

  • 下载安装
javascript 复制代码
yarn add pinia-plugin-persist
  • 修改之前的目录结构

在src/store/index.ts

javascript 复制代码
import {createPinia} from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'
const store=createPinia()
store.use(piniaPluginPersist)
export default store

修改main.ts文件

javascript 复制代码
import { createApp } from 'vue'
import App from './App.vue'
import store from './store'
const app=createApp(App)
app.use(store)
app.mount('#app')
  • 在相应的模块中开启持久化
javascript 复制代码
import {defineStore} from 'pinia'
const useUsersStore=defineStore('users',{
    state:():=>{
    },
    getters:{
    },
    actions:{
    },
    persist:{
        enabled:true
    }
})
export default useUsersStore

默认情况下,pinia持久化的数据存储在sessionStorage中,如果要存储到localStorage中,设置如下

  • 设置到localstorage中
javascript 复制代码
import {defineStore} from 'pinia'
const useUsersStore=defineStore('users',{
    state:():=>{
    },
    getters:{
    },
    actions:{
    },
    persist:{
        enabled:true,
        strategies:[
            {
                key:'my_user',
                storage:localStorage
            }
        ]
    }
})
export default useUsersStore

默认所有的state都会进行缓存,你能够通过paths指定要持久化的字段,其余的则不持久化

javascript 复制代码
import {defineStore} from 'pinia'
const useUsersStore=defineStore('users',{
    state:():=>{
    },
    getters:{
    },
    actions:{
    },
    persist:{
        enabled:true,
        strategies:[
            {
                key:'my_user',
                storage:localStorage,
                paths:['name','job']
            }
        ]
    }
})
export default useUsersStore
相关推荐
y先森19 分钟前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy19 分钟前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu108301891122 分钟前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿1 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡2 小时前
commitlint校验git提交信息
前端
天天进步20153 小时前
Vue+Springboot用Websocket实现协同编辑
vue.js·spring boot·websocket
虾球xz3 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇3 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒3 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员3 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js