博客

  • react-router在组件外操作路由

    思路:创建可供组件外部使用的 history 对象

    步骤

    1. 创建 utils/history.ts,在里面创建一个 history 对象并导出
    2. App.tsx 中使用 Router 组件来替代 BrowserRouter,并将外部 history 对象关联到 Router

    utils/history.ts

    import { createBrowserHistory } from 'history'
    
    const history = createBrowserHistory()
    
    export default history

    App.tsx

    import { Router, Redirect, Route } from 'react-router-dom'
    import history from './utils/history'
    
    <Router history={history}>

    使用

    import history from './utils/history' // 导入history对象
    history.push('/home') // 跳转路由
  • craco配置postcss不生效

    craco.config.ts添加postcss插件不起作用,在根目录下新建postcss配置文件并导出空对象即可

    新建postcss.config.ts

    添加

    export default {}
  • Vue3自动导入常用api

    unplugin-auto-import让API自动导入

    比如

    1. 可以让vueAPI里面的ref,reactive,watch,watchEffect等等api直接写在setup内,
    2. 可以让vue-router中的createRouter,createWebHashHistory,createWebHistory,useRoute,useRouter等API直接写在setup内
    3. 也可以让pinia中的createPinia,definStore直接写在setup内,都不需要再import导入了

    安装

    npm i unplugin-auto-import -D
    or
    yarn add unplugin-auto-import -D

    配置vite.config.js

    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'
    import AutoImport from 'unplugin-auto-import/vite'
    
    // https://vitejs.dev/config/
    export default defineConfig({
        plugins: [
            vue(),
            // 自动引入vue的api
            AutoImport({
                // 后续vue/vue-router/pinia的API都不需要再单独import到setup里面了
                imports: ['vue', 'vue-router', 'pinia'],
                //dts: 'src/auto-imports...', // 可以自定义文件生成的位置与是否生成,默认是根目录下
                dts: false,
            }),
        ],
    })

    使用

    <script lang="ts" setup>
    // onmounted属于vue的api不需要单独引入了
    // import { onMounted } from 'vue'
    
    onMounted(() => {
      console.log('unplugin-auto-import')
    })
    </script>

    https://blog.csdn.net/SunFlower914/article/details/126579209

  • Vue3自定义组件名字

    在使用setup语法糖的时候没办法直接定义组件的名字,有两种解决方法

    写两个script标签

    <script lang="ts">
    import { defineComponent, onMounted } from 'vue'
    //script1:用来定义name
    export default defineComponent({
      name: '自定义name'
    })
    </script>
    
    <script lang="ts" setup>
     //script2:用来定义setup语法糖
    </script>

    使用vite-plugin-vue-setup-extend

    安装
    npm i vite-plugin-vue-setup-extend -D
    配置vite.config.js
    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'
    // 引入vite-plugin-vue-setup-extend
    import VueSetupExtend from 'vite-plugin-vue-setup-extend'
    
    export default defineConfig({
      // 配置
        plugins: [vue(), VueSetupExtend()],
    })
    使用
    <script lang="ts" setup name="自定义name">
    // 使用vite-plugin-vue-setup-extend插件
    </script>

    https://blog.csdn.net/SunFlower914/article/details/126579209

  • Vue+ts使用animate.css

    安装

    npm install animate.css --save
    or
    yarn add animate.css

    在main.ts中引入

    import { createApp } from 'vue'
    import App from './App.vue'
    // 引入animate.css
    import 'animate.css'
    
    createApp(App).mount('#app')

    此时会提示找不到模块“animate.css”或其相应的类型声明

    解决方法

    找到 src/vite-env.d.ts(老版本Vite为shims-vue.d.ts)

    添加下面代码

    declare module 'animate.css' 
    // 声明animate.css的类型,否则引入animate.css会报错,提示找不到animate.css模块

    使用

    组件中使用animate.css,需要注意的是,样式class类名,必须加上animate__animated,其次则是要引入动画的class类名,如animate__slideInUp

    <template>
      <div class="content-box animate__animated animate__slideInUp">
        滑动进入特效演示
      </div>
    </template>

    修改动画属性

    方法一:直接通过动画class类名animated修改

    .animated {
        -webkit-animation-duration: 1s; 
        animation-duration: 2s; // 动画执行时间
        -webkit-animation-fill-mode: both;
        animation-fill-mode: both;
    }

    方法二:修改指定动画的属性

    .animate__slideInUp {
        -webkit-animation-duration: 1s; 
        animation-duration: 2s; // 动画执行时间
        -webkit-animation-fill-mode: both;
        animation-fill-mode: both;
    }

    方法三:在要执行动画的div设置stye

    <div 
        class="content-box animate__animated animate__slideInUp"
        :style="{animationDuration: '500ms'}"
        >
    </div>

    vue+ts或者react+ts如何使用animate.css

  • uni-app中flyio的使用

    在 src 目录下创建 utils 目录,并添加 request.js

    import FlyIO from 'flyio/dist/npm/wx'
    
    // 创建新的 FlyIO 实例
    const service = new FlyIO()
    
    // 设置超时
    service.config.timeout = 5000;
    
    // 设置请求基地址
    service.config.baseURL = 'https://www.xxx.xxx'
    
    // 请求拦截器
    service.interceptors.request.use((request) => {
        uni.showLoading({
            title: "加载中...",
            mask: true
        })
        return request
    })
    
    // 响应拦截器
    service.interceptors.response.use((response) => {
        // 隐藏加载框
        uni.hideLoading()
    
        // 只取返回的数据字段
        return response.data
    }, (err) => {
        uni.hideLoading()
        return Promise.reject(err)
    })
    
    // 导出
    export default service

    在 main.js 中将 request.js 模块导出的 flyio 实例,挂载到 Vue.prototype

    // 导入 request.js 模块
    import service from '@/utils/request'
    
    // 挂载到 Vue.prototype
    Vue.prototype.$service = service
  • Vite配置preprocessorOptions全局引入less

    css.preprocessorOptions.less.additionalData

    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'
    // https://vitejs.dev/config/
    export default defineConfig({
      plugins: [ vue() ],
      css: {
        preprocessorOptions: {
          less: {
            additionalData: `
              @import "@/assets/styles/variables.less";
              @import "@/assets/styles/mixins.less";
            `
          }
        }
      }
    })
  • 【开源】查看网站在不同设备的预览效果

    Vue3 + Vite

    每次更新网站都要重新截图、做预览图,太麻烦了!于是就有了这个小工具,这样每次更新只需要输入网址直接截图就可以了✨

    创意来自 web-multiterminal-preview

    开源地址

    Gitee

    https://gitee.com/liaoliao314/multiterminal-preview

    Github

    https://github.com/liaoliao0314/multiterminal-preview

    在线预览

    • 可以预览你的网站在不同设备下的显示效果
    • 可以自定义不同设备的网址
    • 可以预览单个设备(点击设备边框即可)

    (没有制作截屏功能)

    小小练习,技术有限,没有考虑兼容性,为了方便自己更新网站的时候用。

    预览图

  • 监听Pinia仓库中的数据变化

    当仓库中state数据发生变化时,可以通过$subscribe进行监听

    <script setup>
        import { storeToRefs } from 'pinia'
        import useStore from './store'
        const { test } = useStore()
        const { name, website } = storeToRefs(test)
      // 监听仓库数据变化
        const subscribe = test.$subscribe((mutation, state) => {},{})
    
      // 触发action
        test.changeName('liaoliao')
    </script>

    详解

    store.$subscribe((mutation, state)=>{} , {})

    $subscribe()有两个参数

    第一个参数

    回调函数 函数带有两个参数mutationstate

    mutation

    对象 有三个属性 eventsstoreIdtype

    events 包含state变化前后的数据

    {
        "effect": {
                         ...
        },
        "target": {
            "name": "liaoliao",
            "website": "https://liaooo.cn"
        },
        "type": "set",
        "key": "name",
        "newValue": "liaoliao",
        "oldValue": "liao"
    }

    storeId

    当前仓库的名字

    storeID: "test"

    type

    用什么方式触发变化

    type: "direct"
    // "direct" 通过 action 变化的
    // "patch object" 通过 $patch 传递对象的方式改变的
    // "patch function"  通过 $patch 传递函数的方式改变的

    第二个参数

    对象 一些参数配置

    {
      detached: false,
      immediate:false,
      deep:false,
      flush:'···',
    }

    detached

    布尔值

    默认false 订阅所在的组件被卸载时,订阅停止

    如果设置detached值为true 时,即使所在组件被卸载,订阅依然生效

    主动停止订阅

    const subscribe = test.$subscribe((mutation, state) => {},{})
    // 调用变量主动停止订阅
    subscribe()

    Pinia

    https://pinia.vuejs.org/core-concepts/state.html#subscribing-to-the-state

    Vuex

    https://vuex.vuejs.org/zh/api/index.html#subscribe

  • Pinia的使用

    安装

    yarn add pinia
    # or
    npm i pinia

    基本使用

    在main.js中挂载Pinia

    import { createPinia } from 'pinia'
    const Pinia = createPinia()
    
    createApp(App).use(Pinia).mount('#app')

    新建仓库文件

    src/test.js

    引入defineStore方法
    import { defineStore } from 'pinia'
    创建store

    命名规则:useXxxStore

    defineStore( storeID , {state,actions,getters} )

    参数1:store的唯一标识,也就是仓库名字

    参数2:对象,可以在对象内提供state、actions、getters

    const useTestStore = defineStore('test', {
      // state是一个函数 在返回的对象中写数据
        state: () => {
            return {
                name: 'liao',
                website: 'https://liaooo.cn',
            }
        },
        actions: {},
        getters: {}
    })
    
    export default useTestStore
    在组件中使用
    <script setup>
        import useTestStore from './store/test'
        const test = useTestStore()
    </script>
    
    <template>
        {{ test.name }}
        {{ test.website }}
    </template>

    actions的使用

    Pinia中没有mutations,只有actions

    在actions中添加方法并修改数据

    ...
    actions: {
            changeName(name) {
                this.name = name
            }
      }
    ...

    在组件中使用actions

    <script setup>
        import useTestStore from './store'
        const test = useTestStore()
      // 执行actions中的方法
        test.changeName('liaoliao')
    </script>

    getters的使用

    添加getter

    ...
    getters: {
            infoPage() {
                return this.website + '/talking'
            },
        }
    ...

    在组件中使用

    <template>
        ...
        {{ test.infoPage }}
    </template>
    
    <script setup>
        import useTestStore from './store'
        const test = useTestStore()
        ...
    </script>

    storeToRefs的使用

    直接解构store中的数据会导致数据丢失响应式特性

    <script setup>
        import useTestStore from './store'
        const test = useTestStore()
      // 解构出来的数据将不再是响应式的
        const { name, website } = test
        ...
    </script>

    使用storeToRefs可以使解构出来的数据依旧是响应式的

    <script setup>
      // 从pinia中引入storeToRefs方法
      import { storeToRefs } from 'pinia'
        ...
        const { name, website } = storeToRefs(test)
        ...
    </script>

    模块化

    根据项目复杂程度,有时候需要存储较多数据,可以定义多个store,最后统一用一个根store整合

    新建user模块

    src/store/user.js

    import { defineStore } from 'pinia'
    
    const useUserStore = defineStore('user', {})
    
    export default useUserStore

    新建······模块

    新建根store

    src/store/index.js

    // 导入所有store
    import useUserStore from './user'
    import use···Store from './···'
    
    // 统一导出useStore()方法
    export default function useStore() {
      return {
        user: useUserStore(),
         ···: use···Store()
      }
    }

    在组件中使用

    <script setup>
        import { storeToRefs } from 'pinia'
        import useStore from './store'
      // 解构user store
        const { user } = useStore()
        const { name, pwd } = storeToRefs(user)
    </script>

    订阅store中数据的变化($subscribe)

    store.$subscribe详见下一篇笔记