0
点赞
收藏
分享

微信扫一扫

vue+vant仿微信聊天画面做了个点击按钮出现土味情话的界面

进击的铁雾 2022-04-06 阅读 325
android

最近在学习框架vue,不得不说vue确实上手快,但用的vant组件库里找了老半天都没找到聊天框样式的组件,啧,实在想用,就自己搭了个,其实就这个气泡框的角花了点时间,用到了伪元素类。

效果图如下:

                                       

直接上代码

页面结构代码:

<template>
  <div class="main">
    <!-- 仿微信的聊天框 -->
    <!-- 顶部导航栏 -->
    <van-sticky :offset-top="0">
      <div class="tar">
        <van-nav-bar
          title="对方正在娇羞中..."
          left-arrow
          @click-left="onClickLeft"
          class="tar_back"
        >
          <template #right>
            <van-icon name="ellipsis" size="18" />
          </template>
        </van-nav-bar>
      </div>
    </van-sticky>

    <!-- 长按淡出气泡提示框 -->
    <van-popover
      v-model="showPopover"
      trigger="manual"
      :actions="actions"
      placement="right-end"
      :offset="[0, -130]"
      @select="onSelect"
    >
      <template #reference>
        <!-- <div class="content">
          <span
            v-html="content"
            @touchstart="start()"
            @touchend="end()"
            @click="showPopover = false"
          ></span>
          <p>长按可以点赞收藏哦~</p>
        </div> -->

        <!-- 聊天内容 -->
        <div
          @touchstart="start()"
          @touchend="end()"
          @click="showPopover = false"
          class="content"
        >
          <ul>
            <li
              v-for="(item, index) in loveArray"
              :key="index"
              :class="'text-' + item.class"
              :style="{ '--url': item.url }"
            >
              <span>{{ item.text }}</span>
            </li>
          </ul>
          <p>长按可以点赞收藏哦~</p>
        </div>
      </template>
    </van-popover>

    <!-- 聊天内容 -->
    <!-- <div >
      <ul>
        <li
          v-for="(item, index) in loveArray"
          :key="index"
          :class="'text-' + item.class"
          :style="{ '--url': item.url }"
        >
          <span>{{ item.text }}</span>
        </li>
      </ul>
      <p>长按可以点赞收藏哦~</p>
    </div> -->
    <!-- 换一个按钮 -->
    <div class="changeButton">
      <van-button class="button" type="primary" @click="Change">
        不喜欢~ 那换一个吧
      </van-button>
    </div>
  </div>
</template>

 js代码:

这里把网络请求和本地存储的代码封装到了http里。调用起来不要太方便

import { get, post } from "../../http/axios";
import { Toast } from "vant";
import {
  setLikeList,
  setStarList,
  getLikeList,
  getStarList,
} from "../../http/likeAndstarUtils";

Toast.setDefaultOptions({ duration: 800 });

let baseURL_btstu = "http://api.btstu.cn";
let baseURL_oddfar = "https://api.oddfar.com/yl";

export default {
  data() {
    return {
      url_right:
        "url(" +
        "https://tva2.sinaimg.cn/large/9bd9b167gy1fzjvskibgzj20b40b4t9b.jpg" +
        ")",
      url_left:
        "url(" +
        "https://tva2.sinaimg.cn/large/9bd9b167ly1fzjwklpbihj20b40b4mxx.jpg" +
        ")",
      loveArray: [],
      showPopover: false,
      actions: [
        { text: "喜欢", icon: "like-o", index: 1 },
        { text: "收藏", icon: "star-o", index: 2 },
      ],
      likeList: [],
      starList: [],
    };
  },
  created() {
    Toast.loading({
      message: "加载中...",
      forbidClick: true,
      loadingType: "spinner",
    });
    this.Change();
  },
  methods: {
    onClickLeft() {
      this.$router.go(-1);
    },
    async Change() {
      Toast.loading({
        message: "加载中...",
        forbidClick: true,
        loadingType: "spinner",
      });
      this.actions[0].icon = "like-o";
      this.actions[1].icon = "star-o";
      //每次点击清空一下数组,防止for循环的数据留下
      // this.loveArray = [];
      //请求男头数据
      let data_myimg = {
        // api_key: "b116b45ef651aa8d",
        method: "zsy",
        lx: "a1",
        format: "json",
      };

      // let myimgUrl = await get(baseURL_btstu, "/sjtx/api.php", data_myimg);
      // this.url_right = "url(" + myimgUrl.data.imgurl + ")";
      // console.log(myimgUrl.data.imgurl);
      //请求女头数据
      let data_sheimg = {
        method: "zsy",
        lx: "b1",
        format: "json",
      };
      // let girlimgUrl = await get(baseURL_btstu, "/sjtx/api.php", data_sheimg);
      // this.url_left = "url(" + girlimgUrl.data.imgurl + ")";
      //请求土味情话数据
      let data_love = {
        c: 1001,
        encode: "json",
      };
      let HappyRes = await get(baseURL_oddfar, "/q.php", data_love);
      // console.log(HappyRes.data.text);
      // console.log(this.loveArray);
      // this.loveArray = myarray;
      if (HappyRes.data.code == 200) {
        //将需要的文案拿出
        let text = HappyRes.data.text;
        //通过先拆分在合并字符串的方法,将“”符号删除
        let StringFrist = text.split("“");
        let Stringtwo = StringFrist.join("");
        let Stringthree = Stringtwo.split("”");
        let ResultString = Stringthree.join("");
        // 通过<br>字符分割文本
        let myarray = ResultString.split("<br>");
        // console.log(myarray);
        //空数组暂时存放push后的数据,用于解决点击按钮后数据消失
        let PushArray = [];
        // v-for循环偶数class为right,奇数class为left
        for (var i = 0; i < myarray.length; i++) {
          let loveObj = new Object();
          // i为偶数,在右边渲染,奇数在左边渲染
          if ((i & 1) === 0) {
            loveObj.text = myarray[i];
            loveObj.class = "right";
            loveObj.url = this.url_right;
          } else {
            loveObj.text = myarray[i];
            loveObj.class = "left";
            loveObj.url = this.url_left;
          }
          PushArray.push(loveObj);
        }
        this.loveArray = PushArray;
      } else {
        Toast.fail("网络连接失败");
      }
    },
    start() {
      clearTimeout(this.loop); //再次清空定时器,防止重复注册定时器
      this.loop = setTimeout(() => {
        // console.log("长按了");
        this.showPopover = true;
      }, 500);
    },
    end() {
      clearTimeout(this.loop); //清空定时器,防止重复注册定时器
    },
    onSelect(action) {
      if (action.index == 1) {
        if (action.icon == "like-o") {
          this.actions[0].icon = "like";
          let likeObj = new Object();
          likeObj.loveArray = this.loveArray;
          likeObj.title = "土味情话";
          //若本地存储中的列表为null则直接存储
          if (
            !getLikeList() &&
            typeof getLikeList() != "undefined" &&
            getLikeList() != 0
          ) {
            this.likeList.push(likeObj);
            setLikeList(this.likeList);
          } else {
            //不为null则先取出再存储
            this.likeList = getLikeList();
            this.likeList.push(likeObj);
            setLikeList(this.likeList);
          }
        } else {
          this.actions[0].icon = "like-o";
          // delToken();
          // localStorage.removeItem('LikeList')
        }
      } else {
        //收藏
        if (action.icon == "star-o") {
          this.actions[1].icon = "star";
          let starObj = new Object();
          starObj.loveArray = this.loveArray;
          starObj.title = "土味情话";
          //若本地存储中的列表为null则直接存储
          if (
            !getStarList() &&
            typeof getStarList() != "undefined" &&
            getStarList() != 0
          ) {
            this.starList.push(starObj);
            setStarList(this.starList);
          } else {
            //不为null则先取出再存储
            this.starList = getStarList();
            this.starList.push(starObj);
            setStarList(this.starList);
          }
        } else {
          this.actions[1].icon = "star-o";
        }
      }
    },
  },
};

 本来是写了随机头像的,太那个api请求数据太tm的慢了,就给注释掉了,有需要的可自取,有一说一是真的慢,这后端写的也太捞了。

最后是css的代码:

.main {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100vh;
  font-size: 16px;
  position: relative;
  background-color: #ededed;
  box-shadow: 0 0 10px 3px rgba(0, 0, 0, 0.2);
}
.main .tar .tar_back {
  background-color: #ededed;
  box-shadow: 0px 1px 1px 0px rgba(212, 212, 212, 0.6);
}
.van-popover__wrapper{
  width: 100%;
}
.main ul {
  padding: 20px 45px;
  list-style: none;
}
.main li {
  padding: 10px 10px 10px 10px;
  margin-bottom: 5px;
  position: relative;
  /* 让页面内的文字不可被选中 */
  -webkit-user-select: none;
  -moz-user-select: none;
  -o-user-select: none;
  user-select: none;
}
.main li span {
  display: inline-block;
  border-radius: 7px;
  background: #a6e860;
  padding: 6px 10px 8px 10px;
  max-width: 88%;
  word-wrap: break-word;
}
.main li.text-left span {
  background: white;
}
/* 伪元素类,在文本框前面加上头像 */
.main li.text-left:before {
  content: "";
  width: 38px;
  height: 38px;
  border-radius: 3px;
  display: block;
  background: var(--url);
  background-size: 100%;
  position: absolute;
  left: -40px;
  top: 10px;
}
/* 伪元素类 加上气泡框的角 */
.main li.text-left span:after {
  content: "";
  width: 0px;
  height: 0px;
  display: block;
  /* transparent 透明色 */
  border: 7px solid transparent;
  /* 在右边生成一个白色的小三角 */
  border-right: 7px solid white;
  position: absolute;
  left: -3px;
  top: 12px;
}
.text-right {
  text-align: right;
}
.text-right span {
  text-align: left;
}
.main li.text-right:after {
  content: "";
  width: 38px;
  height: 38px;
  border-radius: 3px;
  display: block;
  background: var(--url);
  background-size: 100%;
  position: absolute;
  right: -38px;
  top: 10px;
}
.main li.text-right span:after {
  content: "";
  width: 0px;
  height: 0px;
  display: block;
  border: 7px solid transparent;
  border-left: 7px solid #a6e860;
  position: absolute;
  right: -3px;
  top: 11px;
}
.changeButton {
  text-align: center;
}
p {
  /* text-align: center; */
  margin-left: 70px;
  font-size: 12px;
  color: rgb(133, 131, 131);
}
.button {
  margin: 50px auto;
  border-radius: 8px;
}
举报

相关推荐

0 条评论