点击商品:进入详情页(页面布局)(带着疑问来做)

170 阅读2分钟

注意点:

1 注意,首页使用了better-scroll -S 滚动 ,点击事件默认关闭,要记得开启: click: true, // 将clcik设置为true

问题点:

  1. A B C 三个组件 : A(父组件) 给B子组件传递了数组--> B(子组件用props接收数据) --> C组件(引用了B组件,如何把B组件中接收到的A组件porps数据 也传给C组件) 兄弟之间传值无效 (未解决:自己直接写数据了,不用组件之间相互传递,先记着后面再看这个问题吧,)

image.png

问题1 解决方案: 有用vuex可以处理: A父组件请求获取到了数据,通过vuex的数据管理方式存储进去 vuex的操作:在mutations:{}中定义一个方法,里面有2个参数,第一个是 state,第二个是要存储的数据

vuex : 组件里相关步骤:
state:{
list:[]
}

mutations:{
 initData(state,data){
 this.state.list = data
 }
}

A父组件:
1. 先引入mutations
import {mapMutations} from 'vuex'
2. 在methods中 解构mutations,里面放的是vuex中mutations中定义的方法名
methods:{
...mapMutations(['initData'])
 this.initData(要存储的接口返回数据)
}
3. 接口请求获取到的数据,直接赋值给解构中initData方法,

3.1 引入 state数据:也是用解构赋值的方法
import {mapMutations,mapState} from 'vuex'

3.2 使用A组件存储给vuex中state的list数据,在computed中解构,
   其实vuex中state 的数据相当于 computed,所以用computed来解构
computed:{
    ...mapState(['list'])
}
3.3 这样就可以在A组件直接使用了list 数据了,
其他组件要使用也就可以像A组件一样 引入 然后解构赋值就可以使用了

2. 详情页头部布局【display:flex布局】遇上 【position: absolute / fixed 】的失效问题 :blog.csdn.net/qq_31967569…

  1. 关闭better-scroll滚动到最底部或者顶部的弹性效果 blog.csdn.net/weixin_4375…

技术点:

0 当头部 2个不同的展示,一次只能展示一个的时候,采用相同的一个变量来判断: 第一个默认为展示状态: 第二个取反就可以

判断:
第一个默认为true  <div class="default" v-show="headersIsShow">
    
第二个取反就可以 <div class="transparent" v-show="!headersIsShow" :style="styleOpacity">

第一个
image.png

第二个

image.png

1 头部滚动的时候,透明度动画效果

image.png

1 采用:动态绑定:style="styleOpacity"来计算赋值,平时很少写动态绑定样式的,很陌生,值得记录 
   
   html部分:
   <div class="transparent" v-show="!headersIsShow" :style="styleOpacity">
      <div class="transparent-header">
        <i class="iconfont icon-zuojiantou"></i>
        <span>商品详情</span>
        <span>商品评价</span>
        <i class="iconfont icon-shouye-weixuanzhong"></i>
      </div>
    </div>
    
    
    数据部分:
   data() {
    return {
      headersIsShow: true,
      BSscroll: "",
      scrollHeight: 0,
      styleOpacity: {},
    };
  },
  
  滚动部分:
   mounted() {
    this.BSscroll = new BScroll(".wrapper", {
      probeType: 3,
      bounce: false,
      click: true, // 将clcik设置为true
   });

    // 获取滚动的高度
    this.BSscroll.on("scroll", (pop) => {
      // console.log(pop);
      this.scrollHeight = Math.abs(pop.y);
      //计算 opacity 动态值
      let opacityNum =
        this.scrollHeight / 300 >= 1 ? 1 : this.scrollHeight / 300;
      console.log(this.scrollHeight);
      this.styleOpacity = { opacity: opacityNum }; // opacity 动态赋值
      this.scrollHeight >= 50
        ? (this.headersIsShow = false)
        : (this.headersIsShow = true);
    });
  },

全部代码:

<template>
  <div class="detials">
    <!-- header -->
    <header>
      <div class="headers">
        <div class="default" v-show="headersIsShow">
          <i class="iconfont icon-zuojiantou"></i>
          <i class="iconfont icon-shouye-weixuanzhong"></i>
        </div>
        <div class="transparent" v-show="!headersIsShow" :style="styleOpacity">
          <div class="transparent-header">
            <i class="iconfont icon-zuojiantou"></i>
            <span>商品详情</span>
            <span>商品评价</span>
            <i class="iconfont icon-shouye-weixuanzhong"></i>
          </div>
        </div>
      </div>
    </header>
    <!-- swiper -->
    <section class="wrapper">
      <div class="scroll">
        <Swiper></Swiper>
        <div class="info">
          <div class="title">
            <h1>靠谱龙井1号 250g 高性价比</h1>
            <div>外形一般但入口顺且浓郁</div>
          </div>
          <div class="present-price">
            <p>68</p>
          </div>
          <div class="original-price">
            <span>价格:</span>
            <del>¥168</del>
          </div>
        </div>
        <div class="imgs">
          <img src="../../../public/images/detials1.jpeg" alt />
        </div>
      </div>
    </section>
    <Footer></Footer>
  </div>
</template>

<script>
import Swiper from "@/components/details/Swiper.vue";
import Footer from "@/components/details/Footer.vue";
// 引入插件
import BScroll from "better-scroll";
export default {
  components: {
    Swiper,
    Footer,
  },
  data() {
    return {
      headersIsShow: true,
      BSscroll: "",
      scrollHeight: 0,
      styleOpacity: {},
    };
  },
  mounted() {
    this.BSscroll = new BScroll(".wrapper", {
      probeType: 3,
      bounce: false,
      click: true, // 将clcik设置为true
    });

    // 获取滚动的高度
    this.BSscroll.on("scroll", (pop) => {
      // console.log(pop);
      this.scrollHeight = Math.abs(pop.y);
      let opacityNum =
        this.scrollHeight / 300 >= 1 ? 1 : this.scrollHeight / 300;
      console.log(this.scrollHeight);
      this.styleOpacity = { opacity: opacityNum };
      this.scrollHeight >= 50
        ? (this.headersIsShow = false)
        : (this.headersIsShow = true);
    });
  },
};
</script>
<style lang="less" scoped>
.headers {
  position: fixed;
  width: 100%;
  z-index: 999;
  // overflow: hidden;
}
.transparent {
  position: fixed;
  width: 100vw;
  height: 1.066667rem;
  box-sizing: border-box;
  background-color: #fff;
}
.transparent-header {
  display: flex;
  // overflow: hidden;
  justify-content: space-between;
  align-items: center;
  font-size: 0.426667rem;
  width: 100vw;
  margin: 10px 0;
  i {
    margin: 0 0.4rem;
  }
  // padding: 0.266667rem;
}
.default {
  display: flex;
  justify-content: space-between;
  margin: 0.133333rem;
  i {
    width: 0.96rem;
    line-height: 0.96rem;
    text-align: center;
    color: #fff;
    font-size: 0.48rem;
    border-radius: 100%;
    background-color: rgba(0, 0, 0, 0.3);
  }
}
.imgs {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}
section {
  display: flex;
  flex-direction: column;
  width: 100vw;
  height: 100vh;
  .scroll {
    flex: 1;
  }
}
.info {
  margin: 0.266667rem;
}
.title {
  padding-bottom: 0.4rem;
  border-bottom: 1px solid #999;
  h1 {
    font-size: 0.48rem;
    font-weight: 500;
    padding: 0.133333rem 0;
  }
  div {
    font-size: 0.32rem;
    color: #999;
  }
}
.present-price {
  color: red;
  padding: 0.133333rem 0;
}
.present-price p::before {
  content: "¥";
  display: inline-block;
  font-size: 0.373333rem;
}
.original-price {
  font-size: 0.32rem;
  color: #999;
}
</style>