微语 微语:代码适合中午敲,早晚出BUG

VUE3+Pinia购物车核心代码 Vue

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

export const Info = defineStore("Info", () => {
  // 店铺信息
  let shopInfo = ref<any>({});
  let changeInfo = (val: any) => {
    shopInfo.value = val;
  };
  // 商品
  let goods = ref<any>([]);
  let GoodsChange = (val: any) => {
    goods.value = val;
  };
  // 商品数量增加减少
  let addNum = (val: any, num: any) => {
    for (let obj of goods.value) {
      for (let arr of obj.foods) {
        if (arr.id === val.id) {
          arr.num += num;
        }
      }
    }
  };
  // 清空购物车
  let clearCart = () => {
    for (let obj of goods.value) {
      for (let child of obj.foods) {
        child.num = 0;
      }
    }
  };
  // 计算商品大于0
  let shopPing = computed(() => {
    let newArr = [];
    for (let obj of goods.value) {
      for (let arr of obj.foods) {
        if (arr.num > 0) {
          newArr.push(arr);
        }
      }
    }
    return newArr;
  });
  // 商品详情
  let goodsInfo = ref<any>({});
  let changeGoods = (val: any) => {
    goodsInfo.value = val;
  };
  return {
    shopInfo,
    changeInfo,
    goodsInfo,
    changeGoods,
    goods,
    GoodsChange,
    addNum,
    shopPing,
    clearCart,
  };
});

better-scroll左右联动使用方法 Vue

let leftScroll: any; //左边滚动
let rightScroll: any; // 右边滚动
// 点击事件  点击左边右边滚动到指定位置
let changeNumber = (index: any) => {
    rightScroll.scrollToElement('#key' + index, 1500)
}
// 实现左右联动

// 计算属性 计算右边盒子高度 并且对数组进行计算返回一个数组对象
let heightArr = computed(() => {
    let harr = ref<any>([])
    store.goods.forEach((obj: any, i: any) => {
        harr.value.push(document.getElementById(i)?.offsetHeight)
    })
    let newArr = ref<any>([])
    let totalHeight = ref(0)
    harr.value.forEach((arr: any, n: any) => {
        newArr.value.push({ min: totalHeight.value, max: totalHeight.value + arr, index: n })
        totalHeight.value += arr
    })
    return newArr.value
})
//初始化
onMounted(() => {
    leftScroll = new BScroll('.list_left', { click: true, probeType: 3 });
    rightScroll = new BScroll('.list_right', { click: true, probeType: 3 });
    //右边滚动事件
    rightScroll.on('scroll', (pos: any) => {
        let _y = Math.floor(Math.abs(pos.y))

        // 循环高度数组 进行判断使其在某一个区间联动左边滚动
        for (let obj of heightArr.value) {
            if (_y >= obj.min && _y <= obj.max) {
                active.value = obj.index
                leftScroll.scrollToElement('#left' + obj.index, 500)
            }
        }
    })
})

Pinia的基本使用方法 Vue

创建

引入

import { defineStore } from 'pinia'

定义,把变量变量暴露出去

export const useShopInfoStore = defineStore('shop', () => {
  let shopInfo = ref()
  let exInfo = (val: any) => {
    shopInfo.value = val
  }
  return {shopInfo,exInfo}
})

使用

引入

import { useShopInfoStore } from '../stores/counter'
let Shopstore = useShopInfoStore()

使用

Shopstore.shopInfo

如果需要结构要使用storeToRefs()来保持数据的响应式

引入storeToRefs

import { storeToRefs } from 'pinia'
let { shopInfo } = storeToRefs(Shopstore)

这样就可以不需要Shopstore.shopInfo拿到里面的值,而是直接shopInfo就可以拿到里面的值

方法的使用,直接Shopstore.exInfo(val) 传进去一个形惨,pinia里面会接受,并且根据逻辑进行处理。


使用vue3+TS提示模块无法找到。 Vue

创建页面也可以正常访问,但是ts报错找不不到模块,可以尝试使用下面方法解决

1.在根目录下面创建 shims-vue.d.ts ,放入下面代码,如果第二和代码段不行,可以尝试第一个。


// declare module '*.vue' {
//     import type { DefineComponent } from 'vue'
//     const component: DefineComponent<{}, {}, any>
//     export default component
// }

declare module '*.vue' {
    import type { DefineComponent } from 'vue'
    const component: ComponentOptions | ComponentOptions['setup']
    export default component
}

echarts数据叠加统计 前端

echarts数据叠加统计

echarts默认配置项会数据叠加统计 stack: 'Total',删掉 stack配置项即可


WebSocket使用方法 前端

1.创建WS对象,与服务器建立webscoket链接

let ws: WebSocket
ws = new WebSocket('ws接口地址')

2.监听ws对象是否建立链接成功

ws.onopen = () => {
    //只要成功,就会触发此回调
}

3.主动推送一个消息给服务器

ws.send( "内容" )

4.监听服务器推送的消息

ws.onmessage = (e) => {
 console.log(e); 
}

5.前端主动断开链接

ws.close()

基于Vue3,webscoket聊天室 Vue

基于Vue3,webscoket聊天室

<template>
    <MyCart title="聊天室">
        <template #button>
            <el-button @click="chat" type="primary">加入聊天室</el-button>
        </template>
        <template #default>
            <div class="info" ref="scrollContainer">
                <div class="people"><span>在线人数:{{ number }}</span> </div>
                <div :class="{ 'left': item.state === 0, 'right': item.state === 1 }" v-for="(item, index) in datainfo"
                    :key="index">
                    <div class="img">
                        <img :src="item.head" alt="头像">
                    </div>
                    <div class="title">
                        <div class="Usertitle"> <span>{{ item.userName }}</span></div>
                        <div class="text">
                            <p>{{ item.data }}</p>
                        </div>
                    </div>
                </div>
            </div>
            <div class="info-foot">
                <el-input v-model="input" placeholder="请输入聊天内容" @keyup.enter="handleEnter" />
                <div class="send"> <el-button @click="sends" type="primary">点击发送</el-button></div>
            </div>
        </template>
    </MyCart>
</template>

<script lang="ts" setup>
import { ref, watch } from 'vue';
import MyCart from '../components/MyCard.vue'
let input = ref('')
let datainfo = ref<Array<msg>>([])
let number = ref()//总人数
let img = "https://t9.baidu.com/it/u=954632137,1492850490&fm=218&app=126&size=f242,150&n=0&f=JPEG&fmt=auto?s=9628FE054373C7CE5406AD6D0300506B&sec=1691600400&t=75097cd4d59b3feec556752f3da3b042"
const scrollContainer = ref(null);
interface msg {
    data: string//消息内容
    head: string//头像
    type?: string//是消息
    userName: string//用户名
    state: number//状态
}

// 1.与服务器建立连接
let ws: WebSocket
let chat = () => {
    console.log('加入聊天室')
    ws = new WebSocket('ws://129.211.169.131:10009/globalchat')
    // 3.监听服务器推送事件
    ws.onopen = () => {
        console.log('与服务器建立成功');
        ws.send(JSON.stringify({
            type: 'name',
            data: "小诸葛",
            head: "https://t9.baidu.com/it/u=954632137,1492850490&fm=218&app=126&size=f242,150&n=0&f=JPEG&fmt=auto?s=9628FE054373C7CE5406AD6D0300506B&sec=1691600400&t=75097cd4d59b3feec556752f3da3b042"        //string:头像url
        }))
    }
    // 监听服务器推送事件
    ws.onmessage = (e) => {
        let data = JSON.parse(e.data)
        console.log(data);
        if (typeof data.data == 'number') {
            number.value = data.data
        }
        if (data.type === 'message') {
            if (data.userName === '小诸葛') {
                data.state = 1
            }
            else {
                data.state = 0
            }
            datainfo.value.push(data)
        }
        console.log(datainfo, '123');
        // ElNotification({
        //     title: '通知',
        //     message: data.data,
        // })
    }

}

let msg = () => {
    ws.send(JSON.stringify({
        type: 'message',   //string: 固定message
        data: input.value
    }));
    input.value = ''
}
let sends = () => {
    msg()
}
// 回车
const handleEnter = () => {
    msg()
}
watch(datainfo.value, () => {
    if (scrollContainer.value) {
        setTimeout(() => {
            const container = scrollContainer.value as unknown as HTMLElement;
            if (container) {
                container.scrollTop = container.scrollHeight;
            }
        }, 0);
    }
});
 //处理破图

</script>

<style lang="scss" scoped>
.info-foot {
    margin-top: 10px;
}

.info {
    width: 100%;
    height: 590px;
    background-color: #35a2ef;
    padding: 20px;
    overflow-y: scroll;
    scroll-behavior: smooth;
    /* 添加平滑滚动效果 */
    border-radius: 5px;

}

.el-card__body {
    position: relative;
}

.people {
    position: absolute;
    right: 41px;
    top: 108px;
    min-width: 112px;
    height: 30px;
    border-radius: 15px;
    background-color: #fff;
    font-size: 12px;
    display: flex;
    align-items: center;
    padding: 0 12px;
    justify-content: center;
}

.send {
    text-align: right;
    margin-top: 10px;

    button {
        width: 150px;
    }
}

.left,
.right {
    width: auto;
    display: flex;
    margin-bottom: 30px;

    .img {
        border-radius: 50%;
        overflow: hidden;
        width: 50px;
        height: 50px;
    }

    img {
        width: 50px;
        height: 50px;
    }

    .title {
        display: flex;
        flex-direction: column;
        justify-content: center;
        margin: 0 8px;
        max-width: 40%;
    }

    .Usertitle {
        color: #fff;
    }

    .text {
        background-color: #fff;
        padding: 5px;
        border-radius: 8px;
        min-height: 34px;
        min-width: 50px;

        p {
            word-break: break-all;
        }
    }
}

.right {
    flex-direction: row-reverse;

    .Usertitle {
        text-align: right;
    }
}

/* 设置滚动条轨道 */
::-webkit-scrollbar {
    width: 5px;
    /* 设置滚动条宽度 */
}

/* 设置滚动条滑块 */
::-webkit-scrollbar-thumb {
    background-color: #35a2ef;

}
</style>