商品详情页:在首页home中:点击猜你喜欢跳转商品详情页(前后端数据一起处理 )用了:提高性能 keep-alive

157 阅读1分钟

技术点:

  1. 路由传参:

    1.1 用query : 显式传参

    1.2 params:隐式传参(注意:跳转的路径要用name,不然无法获取到传的参数)

      methods: {
         // 通过路由方式跳转到详情页
         goDetials(id) {
           // this.$router.push({ path: "/detials", query: { id } }); // 显式传参
           this.$router.push({ name: "Details", params: { id } }); // 隐式传参
           console.log(id);
         },
       },
       
    
  2. 【提高性能 keep-alive 使用】:是在项目的app.vue 使用的 把所有路由请求都用了这个包裹起来

    2.1 会多两个生命周期 activated deactivated

    2.2 使用了keep-alive 之后,会进入到这个生命周期 activated(), 其中router-view 里设置哪些组件需要缓存 哪些不需要缓存, 设置完之后,要在router 的 index文件中 设置一个meta标签 meta: { keepAlive: false // 不需要缓存 },

    image.png

image.png

    2.3 在商品详情页中 写这个生命周期
         activated() {
        // 使用了keep-alive 之后,会进入到这个生命周期
        // 判断路由路径是否发生变化,如果发生变化,就在这里继续发送请求,页面就可以正常访问了
        (注意 请求接口也是通过id请求的,所以这里用id来判断就可以)
        this.$route.query.id == this.id ? "" : this.getDetialData();
        },
        

商品详情页前端代码:

       <template>
  <div class="detials">
    <!-- header -->
    <header>
      <div class="headers">
        <div class="default" v-show="headersIsShow">
          <i class="iconfont icon-zuojiantou" @click="goBack"></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>{{DetialData.introduce}}</h1>
            <div>外形一般但入口顺且浓郁</div>
          </div>
          <div class="present-price">
            <p>{{DetialData.price}}</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";
// 引入封装好的 require
import http from "@/common/api/request.js";
export default {
  components: {
    Swiper,
    Footer,
  },
  data() {
    return {
      headersIsShow: true,
      BSscroll: "",
      scrollHeight: 0,
      styleOpacity: {},
      DetialData: {},
      id: 0,
    };
  },
  created() {
    // 接收传递过来的参数
    console.log(this.$route.query.id);
    this.getDetialData();
    // console.log(12312);
  },
  activated() {
    // 使用了keep-alive 之后,会进入到这个生命周期
    // 判断路由路径是否发生变化,如果发生变化,就在这里继续发送请求,页面就可以正常访问了
    this.$route.query.id == this.id ? "" : this.getDetialData();
  },
  methods: {
    // 请求 猜你喜欢的数据
    async getDetialData() {
      this.id = this.$route.query.id;
      let res = await http.$axios({
        url: "/api/goods/id",
        params: {
          id: this.id,
        },
      });
      this.DetialData = res[0];
      console.log(this.DetialData);
    },
    // 返回上一页 也就是首页
    goBack() {
      this.$router.push("/home");
    },
  },

  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>

后端接口代码:

   // 查询商品详情接口,根据id查询
router.get('/api/goods/id', function (req, res, next) {
  // 查看前端给后端传递过来的数据
  let id = req.query.id
  //  查询数据库
  connection.query(`select * from shoplist where id = ${id}`, function (err, result) {
    if (err) throw err;
    res.send({
      code:0,
      data: result
    })
  })
})