07.智慧商城——商品详情页、加入购物车、拦截器封装token

news2024/11/25 22:53:46

01. 商品详情 - 静态布局

在这里插入图片描述

静态结构 和 样式

<template>
  <div class="prodetail">
    <van-nav-bar fixed title="商品详情页" left-arrow @click-left="$router.go(-1)" />

    <van-swipe :autoplay="3000" @change="onChange">
      <van-swipe-item v-for="(image, index) in images" :key="index">
        <img :src="image" />
      </van-swipe-item>

      <template #indicator>
        <div class="custom-indicator">{{ current + 1 }} / {{ images.length }}</div>
      </template>
    </van-swipe>

    <!-- 商品说明 -->
    <div class="info">
      <div class="title">
        <div class="price">
          <span class="now">¥0.01</span>
          <span class="oldprice">¥6699.00</span>
        </div>
        <div class="sellcount">已售1001件</div>
      </div>
      <div class="msg text-ellipsis-2">
        三星手机 SAMSUNG Galaxy S23 8GB+256GB 超视觉夜拍系统 超清夜景 悠雾紫 5G手机 游戏拍照旗舰机s23
      </div>

      <div class="service">
        <div class="left-words">
          <span><van-icon name="passed" />七天无理由退货</span>
          <span><van-icon name="passed" />48小时发货</span>
        </div>
        <div class="right-icon">
          <van-icon name="arrow" />
        </div>
      </div>
    </div>

    <!-- 商品评价 -->
    <div class="comment">
      <div class="comment-title">
        <div class="left">商品评价 (5条)</div>
        <div class="right">查看更多 <van-icon name="arrow" /> </div>
      </div>
      <div class="comment-list">
        <div class="comment-item" v-for="item in 3" :key="item">
          <div class="top">
            <img src="http://cba.itlike.com/public/uploads/10001/20230321/a0db9adb2e666a65bc8dd133fbed7834.png" alt="">
            <div class="name">神雕大侠</div>
            <van-rate :size="16" :value="5" color="#ffd21e" void-icon="star" void-color="#eee"/>
          </div>
          <div class="content">
            质量很不错 挺喜欢的
          </div>
          <div class="time">
            2023-03-21 15:01:35
          </div>
        </div>
      </div>
    </div>

    <!-- 商品描述 -->
    <div class="desc">
      <img src="https://uimgproxy.suning.cn/uimg1/sop/commodity/kHgx21fZMWwqirkMhawkAw.jpg" alt="">
      <img src="https://uimgproxy.suning.cn/uimg1/sop/commodity/0rRMmncfF0kGjuK5cvLolg.jpg" alt="">
      <img src="https://uimgproxy.suning.cn/uimg1/sop/commodity/2P04A4Jn0HKxbKYSHc17kw.jpg" alt="">
      <img src="https://uimgproxy.suning.cn/uimg1/sop/commodity/MT4k-mPd0veQXWPPO5yTIw.jpg" alt="">
    </div>

    <!-- 底部 -->
    <div class="footer">
      <div class="icon-home">
        <van-icon name="wap-home-o" />
        <span>首页</span>
      </div>
      <div class="icon-cart">
        <van-icon name="shopping-cart-o" />
        <span>购物车</span>
      </div>
      <div class="btn-add">加入购物车</div>
      <div class="btn-buy">立刻购买</div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'ProDetail',
  data () {
    return {
      images: [
        'https://img01.yzcdn.cn/vant/apple-1.jpg',
        'https://img01.yzcdn.cn/vant/apple-2.jpg'
      ],
      current: 0
    }
  },
  methods: {
    onChange (index) {
      this.current = index
    }
  }
}
</script>

<style lang="less" scoped>
.prodetail {
  padding-top: 46px;
  ::v-deep .van-icon-arrow-left {
    color: #333;
  }
  img {
    display: block;
    width: 100%;
  }
  .custom-indicator {
    position: absolute;
    right: 10px;
    bottom: 10px;
    padding: 5px 10px;
    font-size: 12px;
    background: rgba(0, 0, 0, 0.1);
    border-radius: 15px;
  }
  .desc {
    width: 100%;
    overflow: scroll;
    ::v-deep img {
      display: block;
      width: 100%!important;
    }
  }
  .info {
    padding: 10px;
  }
  .title {
    display: flex;
    justify-content: space-between;
    .now {
      color: #fa2209;
      font-size: 20px;
    }
    .oldprice {
      color: #959595;
      font-size: 16px;
      text-decoration: line-through;
      margin-left: 5px;
    }
    .sellcount {
      color: #959595;
      font-size: 16px;
      position: relative;
      top: 4px;
    }
  }
  .msg {
    font-size: 16px;
    line-height: 24px;
    margin-top: 5px;
  }
  .service {
    display: flex;
    justify-content: space-between;
    line-height: 40px;
    margin-top: 10px;
    font-size: 16px;
    background-color: #fafafa;
    .left-words {
      span {
        margin-right: 10px;
      }
      .van-icon {
        margin-right: 4px;
        color: #fa2209;
      }
    }
  }

  .comment {
    padding: 10px;
  }
  .comment-title {
    display: flex;
    justify-content: space-between;
    .right {
      color: #959595;
    }
  }

  .comment-item {
    font-size: 16px;
    line-height: 30px;
    .top {
      height: 30px;
      display: flex;
      align-items: center;
      margin-top: 20px;
      img {
        width: 20px;
        height: 20px;
      }
      .name {
        margin: 0 10px;
      }
    }
    .time {
      color: #999;
    }
  }

  .footer {
    position: fixed;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 55px;
    background-color: #fff;
    border-top: 1px solid #ccc;
    display: flex;
    justify-content: space-evenly;
    align-items: center;
    .icon-home, .icon-cart {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      font-size: 14px;
      .van-icon {
        font-size: 24px;
      }
    }
    .btn-add,
    .btn-buy {
      height: 36px;
      line-height: 36px;
      width: 120px;
      border-radius: 18px;
      background-color: #ffa900;
      text-align: center;
      color: #fff;
      font-size: 14px;
    }
    .btn-buy {
      background-color: #fe5630;
    }
  }
}
    
.tips {
  padding: 10px;
}
</style>

LazyloadVue 指令,使用前需要对指令进行注册。

import { Lazyload } from 'vant'
Vue.use(Lazyload)

02. 商品详情 - 动态渲染介绍

  1. 动态路由参数,获取商品 id
computed: {
  goodsId () {
    return this.$route.params.id
  }
},
  1. 封装 api 接口 api/product.js
// 获取商品详情数据
export const getProDetail = (goodsId) => {
  return request.get('/goods/detail', {
    params: {
      goodsId
    }
  })
}
  1. 一进入页面发送请求,获取商品详情数据
data () {
  return {
    images: [
      'https://img01.yzcdn.cn/vant/apple-1.jpg',
      'https://img01.yzcdn.cn/vant/apple-2.jpg'
    ],
    current: 0,
    detail: {},
  }
},

async created () {
  this.getDetail()
},

methods: {
  ...
  async getDetail () {
    const { data: { detail } } = await getProDetail(this.goodsId)
    this.detail = detail
    this.images = detail.goods_images
  }
}
  1. 动态渲染
<div class="prodetail" v-if="detail.goods_name">

<van-swipe :autoplay="3000" @change="onChange">
  <van-swipe-item v-for="(image, index) in images" :key="index">
    <img v-lazy="image.external_url" />
  </van-swipe-item>

  <template #indicator>
    <div class="custom-indicator">{{ current + 1 }} / {{ images.length }}</div>
  </template>
</van-swipe>

<!-- 商品说明 -->
<div class="info">
  <div class="title">
    <div class="price">
      <span class="now">¥{{ detail.goods_price_min }}</span>
      <span class="oldprice">¥{{ detail.goods_price_max }}</span>
    </div>
    <div class="sellcount">已售{{ detail.goods_sales }}件</div>
  </div>
  <div class="msg text-ellipsis-2">
    {{ detail.goods_name }}
  </div>

  <div class="service">
    <div class="left-words">
      <span><van-icon name="passed" />七天无理由退货</span>
      <span><van-icon name="passed" />48小时发货</span>
    </div>
    <div class="right-icon">
      <van-icon name="arrow" />
    </div>
  </div>
</div>

<!-- 商品描述 -->
<div class="tips">商品描述</div>
<div class="desc" v-html="detail.content"></div>

03. 商品详情 - 动态渲染评价

  1. 封装接口 api/product.js
// 获取商品评价
export const getProComments = (goodsId, limit) => {
  return request.get('/comment/listRows', {
    params: {
      goodsId,
      limit
    }
  })
}
  1. 页面调用获取数据
import defaultImg from '@/assets/default-avatar.png'

data () {
  return {
    ...
    total: 0,
    commentList: [],
    defaultImg
},

async created () {
  ...
  this.getComments()
},
    
async getComments () {
  const { data: { list, total } } = await getProComments(this.goodsId, 3)
  this.commentList = list
  this.total = total
},
  1. 动态渲染评价
<!-- 商品评价 -->
<div class="comment" v-if="total > 0">
  <div class="comment-title">
    <div class="left">商品评价 ({{ total }})</div>
    <div class="right">查看更多 <van-icon name="arrow" /> </div>
  </div>
  <div class="comment-list">
    <div class="comment-item" v-for="item in commentList" :key="item.comment_id">
      <div class="top">
        <img :src="item.user.avatar_url || defaultImg" alt="">
        <div class="name">{{ item.user.nick_name }}</div>
        <van-rate :size="16" :value="item.score / 2" color="#ffd21e" void-icon="star" void-color="#eee"/>
      </div>
      <div class="content">
        {{ item.content }}
      </div>
      <div class="time">
        {{ item.create_time }}
      </div>
    </div> 
  </div>
</div>

04. 加入购物车 - 唤起弹窗

在这里插入图片描述

  1. 按需导入 van-action-sheet
import { ActionSheet } from 'vant'
Vue.use(ActionSheet)
  1. 准备 van-action-sheet 基本结构
<van-action-sheet v-model="showPannel" :title="mode === 'cart' ? '加入购物车' : '立刻购买'">
	弹窗
</van-action-sheet>
    
data () {
  return {
    ...
    mode: 'cart'
    showPannel: false
  }
},
  1. 注册点击事件,点击时唤起弹窗
<div class="btn-add" @click="addFn">加入购物车</div>
<div class="btn-buy" @click="buyFn">立刻购买</div>

addFn () {
  this.mode = 'cart'
  this.showPannel = true
},
buyFn () {
  this.mode = 'buyNow'
  this.showPannel = true
}
  1. 完善结构
<van-action-sheet v-model="showPannel" :title="mode === 'cart' ? '加入购物车' : '立刻购买'">
  <div class="product">
    <div class="product-title">
      <div class="left">
        <img src="http://cba.itlike.com/public/uploads/10001/20230321/8f505c6c437fc3d4b4310b57b1567544.jpg" alt="">
      </div>
      <div class="right">
        <div class="price">
          <span>¥</span>
          <span class="nowprice">9.99</span>
        </div>
        <div class="count">
          <span>库存</span>
          <span>55</span>
        </div>
      </div>
    </div>
    <div class="num-box">
      <span>数量</span>
      数字框占位
    </div>
    <div class="showbtn" v-if="true">
      <div class="btn" v-if="true">加入购物车</div>
      <div class="btn now" v-else>立刻购买</div>
    </div>
    <div class="btn-none" v-else>该商品已抢完</div>
  </div>
</van-action-sheet>
.product {
  .product-title {
    display: flex;
    .left {
      img {
        width: 90px;
        height: 90px;
      }
      margin: 10px;
    }
    .right {
      flex: 1;
      padding: 10px;
      .price {
        font-size: 14px;
        color: #fe560a;
        .nowprice {
          font-size: 24px;
          margin: 0 5px;
        }
      }
    }
  }

  .num-box {
    display: flex;
    justify-content: space-between;
    padding: 10px;
    align-items: center;
  }

  .btn, .btn-none {
    height: 40px;
    line-height: 40px;
    margin: 20px;
    border-radius: 20px;
    text-align: center;
    color: rgb(255, 255, 255);
    background-color: rgb(255, 148, 2);
  }
  .btn.now {
    background-color: #fe5630;
  }
  .btn-none {
    background-color: #cccccc;
  }
}
  1. 动态渲染
<van-action-sheet v-model="showPannel" :title="mode === 'cart' ? '加入购物车' : '立刻购买'">
  <div class="product">
    <div class="product-title">
      <div class="left">
        <img :src="detail.goods_image" alt="">
      </div>
      <div class="right">
        <div class="price">
          <span>¥</span>
          <span class="nowprice">{{ detail.goods_price_min }}</span>
        </div>
        <div class="count">
          <span>库存</span>
          <span>{{ detail.stock_total }}</span>
        </div>
      </div>
    </div>
    <div class="num-box">
      <span>数量</span>
      数字框组件
    </div>
    <div class="showbtn" v-if="detail.stock_total > 0">
      <div class="btn" v-if="mode === 'cart'">加入购物车</div>
      <div class="btn now" v-if="mode === 'buyNow'">立刻购买</div>
    </div>
    <div class="btn-none" v-else>该商品已抢完</div>
  </div>
</van-action-sheet>

05. 加入购物车 - 封装数字框组件

在这里插入图片描述

  1. 封装组件 components/CountBox.vue
<template>
  <div class="count-box">
    <button @click="handleSub" class="minus">-</button>
    <input :value="value" @change="handleChange" class="inp" type="text">
    <button @click="handleAdd" class="add">+</button>
  </div>
</template>

    
<script>
export default {
  props: {
    value: {
      type: Number,
      default: 1
    }
  },
  methods: {
    handleSub () {
      if (this.value <= 1) {
        return
      }
      this.$emit('input', this.value - 1)
    },
    handleAdd () {
      this.$emit('input', this.value + 1)
    },
    handleChange (e) {
      // console.log(e.target.value)
      const num = +e.target.value // 转数字处理 (1) 数字 (2) NaN

      // 输入了不合法的文本 或 输入了负值,回退成原来的 value 值
      if (isNaN(num) || num < 1) {
        e.target.value = this.value
        return
      }

      this.$emit('input', num)
    }
  }
}
</script>
    

<style lang="less" scoped>
.count-box {
  width: 110px;
  display: flex;
  .add, .minus {
    width: 30px;
    height: 30px;
    outline: none;
    border: none;
    background-color: #efefef;
  }
  .inp {
    width: 40px;
    height: 30px;
    outline: none;
    border: none;
    margin: 0 5px;
    background-color: #efefef;
    text-align: center;
  }
}
</style>

  1. 使用组件
import CountBox from '@/components/CountBox.vue'

export default {
  name: 'ProDetail',
  components: {
    CountBox
  },
  data () {
    return {
      addCount: 1
      ...
    }
  },
}

<div class="num-box">
  <span>数量</span>
  <CountBox v-model="addCount"></CountBox>
</div>

06. 加入购物车 - 判断 token 登录提示

说明:加入购物车,是一个登录后的用户才能进行的操作,所以需要进行鉴权判断,判断用户 token 是否存在

  1. 若存在:继续加入购物车操作
  2. 不存在:提示用户未登录,引导到登录页

1. 按需注册 dialog 组件
import { Dialog } from 'vant'
Vue.use(Dialog)
  1. 按钮注册点击事件
<div class="btn" v-if="mode === 'cart'" @click="addCart">加入购物车</div>
  1. 添加 token 鉴权判断,跳转携带回跳地址
async addCart () {
  // 判断用户是否有登录,因为这里要根据用户的选择判断是否要跳转到登录页面,我们之前在路由前置守卫中设置过拦截路径为:['/pay', '/myorder'],
  //这里是用户访问这两个页面直接拦截前往登录页面,并没有询问用户的意见,所以不能直接在前置守卫中进行拦截。
  if (!this.$store.getters.token) {
    this.$dialog.confirm({
      title: '温馨提示',
      message: '此时需要先登录才能继续操作哦',
      confirmButtonText: '去登录',
      cancelButtonText: '再逛逛'
    })
      .then(() => {
        //注意这里使用replace而不是使用push,push会新增浏览记录,而replace则是替换浏览记录,A页面replaceB时,A的浏览纪律会被B替换
        this.$router.replace({
          path: '/login',
          query: {
            backUrl: this.$route.fullPath
          }
        })
      })
      .catch(() => {})
    return
  }
  console.log('进行加入购物车操作')
}
  1. 登录后,若有回跳地址,则回跳页面
// 判断有无回跳地址
const url = this.$route.query.backUrl || '/'
this.$router.replace(url)

07. 加入购物车 - 封装接口进行请求

在这里插入图片描述

  1. 封装接口 api/cart.js
// 加入购物车,goodSkulId为商品的规格,例如颜色,大小
export const addCart = (goodsId, goodsNum, goodsSkuId) => {
  return request.post('/cart/add', {
    goodsId,
    goodsNum,
    goodsSkuId
  })
}
  1. 页面中调用请求
data () {
  return {
      cartTotal: 0
  }  
},

async addCart () {
  ...
  const { data } = await addCart(this.goodsId, this.addCount, this.detail.skuList[0].goods_sku_id)
  this.cartTotal = data.cartTotal
  this.$toast('加入购物车成功')
  this.showPannel = false
},

在这里插入图片描述

  1. 请求拦截器中,统一携带 token
// 自定义配置 - 请求/响应 拦截器
// 添加请求拦截器
instance.interceptors.request.use(function (config) {
  ...
  const token = store.getters.token
  if (token) {
    config.headers['Access-Token'] = token
    config.headers.platform = 'H5'
  }
  return config
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error)
})
  1. 准备小图标
<div class="icon-cart">
  <span v-if="cartTotal > 0" class="num">{{ cartTotal }}</span>
  <van-icon name="shopping-cart-o" />
  <span>购物车</span>
</div>
  1. 定制样式
.footer .icon-cart {
  position: relative;
  padding: 0 6px;
  .num {
    z-index: 999;
    position: absolute;
    top: -2px;
    right: 0;
    min-width: 16px;
    padding: 0 4px;
    color: #fff;
    text-align: center;
    background-color: #ee0a24;
    border-radius: 50%;
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1219571.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python在函数中使用列表作为默认参数

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 在学习中遇到的Python的一个坑&#xff0c;那就是使用列表作为默认参数。 我们知道&#xff0c;在Python中&#xff0c;列表&#xff08;list&#xff09;是可变…

融云五大场景化能力,全面赋能金融行业数智化转型

在高知识密度与大数据处理双向奔赴&#xff0c;「金融大模型」如何推动行业进化&#xff1f;一文中&#xff0c;我们分享了大模型在金融行业的赋能实践和未来场景。关注【融云 RongCloud】&#xff0c;了解协同办公平台更多干货。 其中&#xff0c;融云作为通信服务商&#xf…

开放式耳机和骨传导耳机有什么区别?哪款值得入手?

开放式耳机和骨传导耳机最大的区别就是佩戴方式不同和传声方式不同&#xff0c;相比之下骨传导耳机更值得入手一些。但其实骨传导耳机也是开放式耳机&#xff0c;下面先了解下开放式耳机都有哪几种。 一、开放式耳机分哪几种&#xff1f; 开放式耳机分为气传导和骨传导。这两种…

这样跟国外客户说可能更好

所说最近的一些沟通感受&#xff0c;不知道大家有没有这样的感觉&#xff0c;每当客户说让价格便宜点的时候&#xff0c;我们习惯性的去问定量&#xff0c;如果客户的定量的确也增加不上来&#xff0c;我们可能会直接回复“sorry, we can not ..." 其实本身这句话并没有毛…

PVP2 ProVideoPlayer 2.1.6(PVP2多屏幕演示投放软件)

PVP2 ProVideoPlayer2是一款视频播放和管理软件&#xff0c;旨在帮助用户实现多屏幕视频播放和内容管理。它被广泛应用于演出、活动、会议等场合&#xff0c;可以同时播放多个视频、图像和音频文件&#xff0c;并提供强大的控制和管理功能。 PVP2 ProVideoPlayer2具有直观的用…

使用express连接MySQL数据库编写基础的增、删、改、查、分页等接口

使用express连接MySQL数据库编写基础的增、删、改、查、分页接口 安装express-generator生成器 cnpm install -g express-generator通过生成器创建项目 express peifang-server切换至serverAPI目录 cd peifang-server下载所需依赖 cnpm install 运行项目 npm start访问项…

uniapp 手动调用form表单submit事件

背景&#xff1a; UI把提交的按钮弄成了图片&#xff0c;之前的button不能用了。 <button form-type"submit">搜索</button> 实现&#xff1a; html&#xff1a; 通过 this.$refs.fd 获取到form的vue对象。手动调用里面的_onSubmit()方法。 methods:…

掌握苏宁API,一键获取商品详情,解锁无尽商业可能

苏宁的API接口可以用于获取商品详情。以下是一个示例的API接口&#xff0c;通过商品ID获取商品详情&#xff1a; https://open.suning.com/api/content/product/getById?productId商品ID&appKey你的应用密钥&sign你的签名&formatjson 在上面的接口中&#xff0c…

无人智能货柜:引领便捷购物新体验

无人智能货柜&#xff1a;引领便捷购物新体验 无人智能货柜利用人工智能技术&#xff0c;将传统货架与电子商务相结合&#xff0c;形成智能销售终端。其采用先拿货后付款的购物模式&#xff0c;用户只需扫码、拿货、关门三个简洁流畅的步骤&#xff0c;极大地提升了消费者的购物…

文心一言 VS 讯飞星火 VS chatgpt (137)-- 算法导论11.3 3题

三、用go语言&#xff0c;考虑除法散列法的另一种版本&#xff0c;其中 h(k) k mod m&#xff0c;m 2 p − 1 2^p-1 2p−1&#xff0c;k为按基数 2 p 2^p 2p 表示的字符串。试证明:如果串可由串 y 通过其自身的字符置换排列导出&#xff0c;则x和y具有相同的散列值。给出一个…

Python基础入门---conda 如何管理依赖包以及复制相同环境的

文章目录 创建虚拟环境:创建虚拟环境并指定Python版本:安装依赖包:从环境导出依赖包清单:从依赖包清单创建环境:复制环境:移植环境:在Conda中,你可以使用conda create命令来创建和管理虚拟环境,而使用conda install命令来安装和管理依赖包。以下是一些基本的命令和步骤…

工业镜头中的远心镜头与普通镜头的光路

普通镜头&#xff1a; 主光线与镜头光轴有角度&#xff0c;工件上下移动时&#xff0c;像的大小有变化。 FOV&#xff1e;镜头前端直径。 物方远心镜头&#xff1a; 物方主光线平行于光轴&#xff0c;物距发生改变时&#xff0c;像高不会发生改变&#xff0c;测得的物体尺寸大…

技术实践|高斯集群服务器双缺省网关故障分析

导语&#xff1a;当前国产化数据库使用范围越来越广泛&#xff0c;在GaussDB数据库的使用过程中难免会遇到一些问题&#xff0c;有的问题是由于在安装过程中没有注意细节而产生的&#xff0c;多数隐患问题都是在特定场景下才会暴露出来&#xff0c;且暴露的时间未知&#xff0c…

MessageSourceUtil读取资源文件

在处理返回值提示的时候&#xff0c;需要根据local返回中文或者英文&#xff0c;因此要使用到国际化内容 操作 1&#xff0c;新建资源文件 在src/main/resources源文件夹下创建一个i18n的子目录&#xff0c; 然后创建中文和英文对应properties文件&#xff0c;然后输入自己的…

如何定位判断是前端的bug还是后端bug?

前言 随着开发软件趋向于大型化复杂化&#xff0c;软件测试逐渐成为一个专业&#xff0c;需要运用专门的方法和手段&#xff0c;需要专门人才来管理。但是外面的小道消息总是在传&#xff1a;软件测试就只是找bug的&#xff01;这个我可就不同意了~ 软件测试员是找bug&#x…

OceanMind海睿思数据中台迎来重磅更新,使用体验全面提升!

为了帮助客户拥有更好的产品使用体验&#xff0c;帮助实施数据治理项目降本增效&#xff0c;OceanMind海睿思的迭代更新从未止步。 OceanMind数据中台再度迎来重磅更新&#xff0c;该版本在大数据方面进行了规划设计&#xff0c;吸纳了30来自于项目的实际需求&#xff0c;更贴…

Linux友人帐之网络编程基础Samba服务器

一、概述 1.1Samba介绍 SMB协议 SMB(Server Message Block,服务信息块)协议是一个高层协议&#xff0c;它提供了在网络上的不同计算机之间共享文件、打印机和不同通信资料的手段。 SMB使用NetBIOS API3实现面向连接的协议&#xff0c;该协议为Vindows客户程序和服务提供了一个…

el-button 的:disabled不生效

添加:key&#xff0c;给个唯一值即可&#xff01;&#xff01;

骨传导耳机品牌排名前十,盘点最受欢迎的五款TOP级骨传导耳机

骨传导耳机品牌排名前十&#xff0c;最受欢迎的五款TOP级骨传导耳机是什么&#xff1f; 耳机市场上有很多品牌和型号的骨传导耳机&#xff0c;每个人对耳机的需求和使用场景也不尽相同。因此&#xff0c;在选择耳机时&#xff0c;确实不能盲目跟风或者仅仅看重品牌。为了帮助大…

视频修复软件 Aiseesoft Video Repair mac中文版功能

AIseesoft Video RepAIr mac是一款专业的视频修复软件&#xff0c;主要用于修复损坏或无法播放的视频文件。AIseesoft Video RepAIr是一个功能强大的程序,可以帮助恢复丢失或损坏的数据的视频。只要您以相同的格式提供示例视频,并在功能强大的技术的支持下,只需单击几下即可收获…