VITE + VUE3

139 阅读2分钟

1. 搭建项目

npm create vite@latest vite-vue3-ts -- --template vue-ts

2. 安装sass

npm install sass -D

3. 安装路由

npm install vue-router@4

这里面需要确定一下,vue3里最好使用router4以上的版本,否则支持不是很友好。

// router/index.ts
import {createRouter, createWebHistory, createWebHashHistory, RouteRecordRaw, Router} from 'vue-router'

const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    name: 'hello',
    component: () => import('@/pages/Home.vue')
  },
  {
    path: '/login',
    name: 'login',
    component: () => import('@/pages/Login/Login.vue')
  },
  {
    path: '/fortress',
    name: 'fortress',
    component: () => import('@/pages/Fortress/Index.vue')
  }
]

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

export default router
// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

const app = createApp(App)
app.use(router)
app.mount('#app')

defineProps

在子组件中接收如组件传过来的数据

<script setup>
import {defineProps} from 'vue'
defineProps({
    msg: {
        type: String,
        default: 'aaaaa'
    }
})
</script>

defineEmits

<script setup>
// 子组件
const props = defineProps({
    num: {
        type: Number,
        default: 100
    }
})
const emit = defineEmits(['update: num'])
const btn = () => {
    emit('update: num', 200)   //修改num的值
}
</script>
// 父组件
<List v-model:num='num'></List>
let num = ref(1)

自动导入vue和vue-router的函数

npm i unplugin-auto-import -D

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import path from 'path'
export default defineConfig({
 base: './',
 resolve: {
   alias: {
     "@": path.resolve(__dirname, "src"),
   },
 },
 plugins: [vue(),
 AutoImport({
   imports: ['vue', 'vue-router'],   //自动导入vue和vue-router相关函数
   resolvers: [ElementPlusResolver()],
 }),
 Components({
   resolvers: [ElementPlusResolver()],
 }),
 ],
 server: {
   host: '0.0.0.0',
   proxy: {
     "/api": {
       target: 'http://192.168.101.57:8080/',
       ws: true,
       changeOrigin: true,
     }
   }
 }
})

toRefs

完成数据的解构

<script setup>
let obj = reactive({
    name: '张三',
    age: 18
})
let {name, age} = toRefs(obj)
</script>

watch

  1. 监听一个数据
watch(msg, (newVal, oldVal) => {
    console.log(newVal, oldVal)
}, {
    immediate: true  // 初始化监听
})
  1. 监听多个数据
watch([msg, str], (newVal, oldVal) => {
    console.log(newVal, oldVal)
}, {
    immediate: true
})
  1. 监听对象中某个对象
watch(() => obj.arr, (newVal, oldVal) => {
    console.log(newVal, oldVal)
})
watch([msg, str, () => obj.arr], (newVal, oldVal) => {
    console.log(newVal, oldVal)
})
  1. 立即执行监听函数
watchEffect(() => {
    console.log(msg.value)
})

useRoute 和 useRouter

<script setup>
import {useRoute, useRouter} from 'vue-router'  //若配置了自动引入此处可以不再导入
const router = useRouter()
const go = () => router.push('/about')
</script>

兄弟组件直接的传值

  1. mitt

npm install mitt -S

// plugins/Bus.js
import mitt from 'mitt'
const emitter = mitt()
export default emitter
// A 组件
emitter.emit('fn', str)
// B 组件
emitter.on('fn', e => {
    s.value = e.value
})

插槽

  • 匿名插槽
  • 具名插槽
  • 作用域插槽
  • 动态插槽

Teleport 传送

注意顺序,必须传送到有这个Dom的内容

<teleport to="#xxx"></teleport>
<teleport to=".xxx"></teleport>
<teleport to="body"></teleport>

动态组件

<keep-alive>
    <component :is="currentComponent.com"></component>
</keep-alive>

异步组件

  1. 组件按需引入,当用户访问到了组件,再去加载组件
<template>
    <div ref="target">
        <C v-if="targetIsVisible"></C>
    </div>
</template>
<script setup>
    import {useIntersectionObserver} from '@vueuse/core'
    const C = defineAsyncComponent(() => import('../compontents/C.vue'))
    const target = ref(null)
    const targetIsVisible = ref(false)
    const {stop} = useIntersectionObserver(target, ([{isIntersecting}]) => {
        if(isIntersecting){
            targetIsVisible.value = isIntersecting
        }
    })
</script>
  1. 分包
<Suspense>
    <template #default>
        <A></A>
    </template>
    <template #fallback>
        加载中...
    </template>
</Suspense>
<script setup>
    const A = defineAsyncComponent(() => import('../compontents/A.vue'))
</script>

minix

Provide / Inject 依赖注入

// 父组件
<script setup>
provide('changeNum', 100)
</script>

// 子孙组件
<script setup>
const aNum = inject('changeNum')
</script>

vuex

<script setup>
import {useStore} from 'vuex'
let store = useStore()
let num = computed(() => store.state.num)
let total = computed(() => store.getters.total)
store.commit('xxx')
store.dispatch('xxx')
</script>

持久化存储

localstorage

npm install vuex-persistedstate -S

Pinia

  • 支持选项式API和组合式API的写法
  • pinia没有mutations,只有 state,getters,actions
  • pinia分模块不需要modules
  • ts支持良好
  • 自动化代码拆分
  • pinia体积更小、性能更好
  • pinia可以直接修改state数据
  1. 安装

npm install pinia

  1. 在main.js中引用
import {createPinia} from 'pinia'
createApp(App)..use(createPinia()).use(router).mount('#app')
  1. store/index.js
import {defineStore} from 'pinia'
export const useStore = defineStore('storeId', {
    state: () => {
        return {
            num: 0,
            name: 'xxxxxx'
        }
    },
    getters: {
        changeNum(){
            return this.num + 1000
        }
    },
    actions: {
        updateNum(val){
            this.num += val
        }
    }
})
  1. 在组件中使用
<script setup>
import { storeToRefs } from 'pinia'
import { useStore } from '../store'
const store = useStore()
let {name, num, changeNum} = storeToRefs(store)
const changeName = () => {
    name.value = 'lisi'
    
    //批量修改
    store.$patch(state => {
        state.num++
        state.name = 'xxx'
    })
}

const btn = () => {
    store.updateNum(200)
}
</script>
  1. 持久化存储

pinia-plugin-persist