前面已经将一些课程加入购物车中,并保存到了后端的redis数据库中,此时做购物车页面时,我们需要将在前端向后端发送请求,用来获取数据数据

购物车页面

1.首先后端要将数据构建好,后端视图函数如下代码:

(post请求是将加入购物车的课程信息加入到redis中,其中对于价格在存储的时候要计算折扣后的价格,而get请求则是redis中取出数据到发送前端页面中)

cart/view:

  1.  
  1. from django.conf import settings
    from rest_framework import status
    from rest_framework.response import Response
    from django_redis import get_redis_connection
    from rest_framework.views import APIView
    from courses.models import Course
    from rest_framework.permissions import IsAuthenticated
    from .utils import get_course_real_price
  1. class CartAPIView(APIView):
  2. permission_classes = [IsAuthenticated]
  3. def post(self,request):
  4. """添加课程到购物车"""
  5. # 接受客户端提交过来的课程ID
  6. course_id = request.data.get("course_id")
  7. try:
  8. course = models.Course.objects.get(pk=course_id, status=0)
  9. except:
  10. return Response({"message": "当前课程不存在或者已经下架了"}, status=status.HTTP_400_BAD_REQUEST)
  11.       
  1.      # 计算课程的真实价格
         price = get_course_real_price(course)
  1. # 把课程id和课程价格保存到购物车中redis中
  2. # redis中使用hash类型保存数据
  3. redis = get_redis_connection("cart")
  4. # 获取当前登陆用户的ID,并写入redis中
  5. user_id = request.user.id
  6. pl = redis.pipeline()
  7. pl.multi()
  8. pl.hset("cart_%s" % user_id, course_id, str(course.price))
  9. # 把当前课程默认为勾选状态[勾选状态也要保存到redis中]
  10. # redis中使用set类型保存数据
  11. pl.sadd("cart_select_%s" % user_id, course_id)
  12. pl.execute()
  13.  
  14. # 返回响应操作
  15. return Response({"message": "success"}, status=status.HTTP_200_OK)
  16.  
  17. def get(self,request):
  18. # 获取当前登陆用户
  19. user_id = request.user.id
  20. # 从redis中获取所有的课程信息和勾选状态
  21. redis = get_redis_connection("cart")
  22. course_list = redis.hgetall("cart_%s" % user_id)
  23. selected_list = redis.smembers("cart_select_%s" % user_id)
  24.  
  25. # 构造数据返回给前端
  26. data = []
  27. for course_id, price in course_list.items():
  28. course_id = course_id.decode()
  29. price = price.decode()
  30.  
  31. try:
  32. course_info = models.Course.objects.get(pk=course_id)
  33. except:
  34. return Response({"message": "请求有误,请联系客服"}, status=status.HTTP_507_INSUFFICIENT_STORAGE)
  35. data.append({
  36. "id": course_id,
  37. "price": price,
  38. "selected": course_id.encode() in selected_list,
  39. "course_img": HOST+course_info.course_img.url,
  40. "name": course_info.name,
  41. })
  42.  
  43. # 返回给客户端
  44. return Response(data, status=status.HTTP_200_OK)

其中关于计算折扣的详细方法如下:

cart/utils:

  1. from decimal import Decimal
  2.  
  3. def get_course_real_price(course):
  4. price = course.price
  5. st = course.price_service_type # 价格服务类型
  6. if st is not None:
  7. all_services = st.priceservices.all() # 当前价格类型的所有服务策略
  8. if st != None and len(all_services) > 0:
  9. if all_services[0].condition > 0: # 是否有设置了价格服务,没有设置价格服务的课程,服务为值None
  10. # 1. 优惠条件值大于0,则属于满减
  11. service_list = all_services
  12. # 进行满减价格计算
  13. real_sale = 0 # 保存满足条件的优惠值
  14. for item in service_list:
  15. item.condition = int(item.condition)
  16. item.sale = int(item.sale)
  17. if course.price > item.condition and real_sale <= item.sale:
  18. real_sale = item.sale
  19. price = course.price - real_sale
  20.  
  21. else: # 优惠条件值为0,则表示是限时折扣或者限时免费
  22. if all_services[0].sale == "-1":
  23. # 2. 限时免费
  24. price = 0
  25. else:
  26. # 3. 限时折扣
  27. # 把优惠值sale中的*去掉
  28. sale = all_services[0].sale[1:]
  29. price = course.price * Decimal(sale)
  30. else:
  31. # 原价
  32. price = course.price
  33.  
  34. return "%.2f" % price

2.关于设置勾选的商品发送到后端保存以及按钮删除购物车课程

后端代码:

cart/view:(由于此时前端发送过来的数据含有数字,另外开一个类(CartCourseAPIView)处理此次请求)

post:前端携带相应的取消或添加勾选购物车内课程的选项,后端根据携带值得真假,做相应的增加或删除勾选项

delete:用于处理前端按钮删除某个购物车课程的处理,需要在购物车课程列表中删除对应键值对,并在勾选集合中删掉对应的id值

  1. class CartCourseAPIView(APIView):
  2. permission_classes = [IsAuthenticated]
  3.  
  4. def post(self,request,pk):
  5. user = request.user
  6. print("user_id",user.id)
  7. try:
  8. course = models.Course.objects.get(pk=pk)
  9. except models.Course.DoesNotExist:
  10. return Response({"message": ""}, status=status.HTTP_400_BAD_REQUEST)
  11.  
  12. #获取勾选状态
  13. is_selected = request.data.get("is_select")
  14.  
  15. #引入redis
  16. redis = get_redis_connection("cart")
  17. if is_selected:
  18. # redis中增加当前课程id到勾选集合中
  19. redis.sadd("cart_select_%s" % user.id, pk)
  20. else:
  21. # redis中删除当前课程id
  22. redis.srem("cart_select_%s" % user.id, pk)
  23.  
  24. return Response({"message": ""}, status=status.HTTP_200_OK)
  25.  
  26. def delete(self,request,pk):
  27.  
  28. user = request.user
  29. try:
  30. course = models.Course.objects.get(pk=pk)
  31. except models.Course.DoesNotExist:
  32. return Response({"message": "无效的课程标号"}, status=status.HTTP_400_BAD_REQUEST)
  33.  
  34. # 从购物车和勾选集合中删除指定的数据
  35. redis = get_redis_connection("cart")
  36. pl = redis.pipeline()
  37. pl.multi()
  38. pl.hdel("cart_%s" % user.id, pk)
  39. pl.srem("cart_select_%s" % user.id, pk)
  40. pl.execute()
  41.  
  42. return Response({"message": "删除成功!"}, status=status.HTTP_200_OK)

前端页面要做的一些功能:

加载数据时,从后端拿数据,发送请求:

cart.vue

  1. //计算各种折算后,购物车的总价
  2. total_price(){
  3. // 计算总价格
  4. let cl = this.course_list;
  5. let total = 0;
  6. for(let i = 0;i<cl.length;i++){
  7. if(cl[i].selected){
  8. total+=parseFloat(cl[i].price);
  9. }
  10. }
  11. total = total.toFixed(2);
  12. this.total = total;
  13. },
  14. },
  15. created() {
  16. let _this = this;
  17. // 发起请求获取购物车中的商品信息
  18. _this.$axios.get("http://127.0.0.1:8000/cart/",{
  19. headers: {
  20. 'Authorization': 'JWT ' + _this.token
  21. },
  22. responseType: 'json',
  23. }).then(response=>{
  24. console.log("response.data",response.data)
  25. _this.course_list = response.data;
  26. this.total_price()
  27. })
  28.  
  29. },

勾选购物车内课程选项时:

1.在每次用户点击选项框时,向后台发送请求,更新后端redis中的勾选项集合(采用监视的方法,只要选项的值变动,便发送请求),

2.在发送请求成功后,需要通知父组件更新,结算的总结各

  1. Template:
  2. <el-col :span="2" class="checkbox"><el-checkbox label="" v-model="course.selected" name="type"></el-checkbox></el-col>
  3.  
  4. script标签内:
  5.  
  6. watch:{
  7. "course.selected":function(){
  8. let _this = this;
  9. _this.$axios.post(`http://127.0.0.1:8000/cart/${this.course.id}`,{
  10. is_select: _this.course.selected
  11. },{
  12. headers:{
  13. // 附带已经登录用户的jwt token 提供给后端,一定不能疏忽这个空格
  14. 'Authorization':'JWT '+_this.token
  15. },
  16. responseType:"json",
  17. }).then(response=>{
  18.  
  19.       //通知父组件更改价格
  20. _this.$emit("change_select");
  21. }).catch(error=>{
  22. console.log( error.response );
  23. })
  24. }
  25. },

2.按钮删除购物车课程,需要做的有:

1.用delete请求向后端发送携带要删除课程id的值

2.在点击该删除按钮时,同时告知父组件应该删除该项课程(涉及到子传父的数据交互问题)

3.在点击该删除按钮时,应该刷新所勾选的购物车的课程结算金额,因为实在父组件中展示的总价,也要对父组件发送更新总价的通知

cartitem.vue中(cart的子组件)

  1. template内:
  2. <el-col :span="4" class="course-delete"><span @click="delete_course(course.id)">删除</span></el-col>
  3.  
  4. script内:
  5.  
  6. props:["course","course_key"], //父组件传递过来的数据
  7. methods:{
  8. //按删除键删除购物车的课程
  9. delete_course(course_id){
  10. let _this = this;
  11. this.$axios.delete(`http://127.0.0.1:8000/cart/${this.course.id}`, {
  12. headers: {
  13. // 附带已经登录用户的jwt token 提供给后端,一定不能疏忽这个空格
  14. 'Authorization': 'JWT ' + _this.token
  15. },
  16. responseType: "json",
  17. }).then(response => {
  18.  
  19. // 发送信息给父组件,通过父组件删除当前子组件
  20. _this.$emit("delete_course",_this.course_key);
  21. }).catch(error => {
  22. console.log(error.response);
  23. });
  24. },
  25. },

cart.vue中(cartitem的父组件):

  1. template:
  2. <CartItem v-for="item,course_key in course_list" :course="item" @change_select="total_price" @delete_course="del_course" :course_key="course_key" />
  3.  
  4. script:
  5. export default {
  6. name:"Cart",
  7. data(){
  8. return {
  9. total:0,
  10. course_list:[],
  11. token: localStorage.token || sessionStorage.token,
  12. }
  13. },
  14.  
  15. components:{
  16. Header,
  17. Footer,
  18. CartItem,
  19. },
  20. methods:{
  21. del_course(course_key) {
  22. //course_key是通过字传父传回来,用于删除已删除的的购物车的课程
  23. this.course_list.splice(course_key, 1);
  24. // 重新计算总价格
  25. this.total_price();
  26. },
  27. //计算各种折算后,购物车的总价
  28. total_price(){
  29. // 计算总价格
  30. let cl = this.course_list;
  31. let total = 0;
  32. for(let i = 0;i<cl.length;i++){
  33. if(cl[i].selected){
  34. total+=parseFloat(cl[i].price);
  35. }
  36. }
  37. total = total.toFixed(2);
  38. this.total = total;
  39. },
  40. },
  41. created() {
  42. let _this = this;
  43. // 发起请求获取购物车中的商品信息
  44. _this.$axios.get("http://127.0.0.1:8000/cart/",{
  45. headers: {
  46. 'Authorization': 'JWT ' + _this.token
  47. },
  48. responseType: 'json',
  49. }).then(response=>{
  50. console.log("response.data",response.data)
  51. _this.course_list = response.data;
  52. this.total_price() //在加载数据的时候也要对总价做出计算
  53. })
  54.  
  55. },
  56. }

详细的完整代码如下:

后端试图cart/view

  1. from django.shortcuts import render
  2.  
  3. # Create your views here.
  4. from django_redis import get_redis_connection
  5. from rest_framework import status
  6. from rest_framework.permissions import IsAuthenticated
  7. from rest_framework.response import Response
  8. from rest_framework.views import APIView
  9.  
  10. from luffy.apps.cart.utils import get_course_real_price
  11. from luffy.apps.courses import models
  12. from luffy.settings import HOST
  13.  
  14. class CartAPIView(APIView):
  15. permission_classes = [IsAuthenticated]
  16. def post(self,request):
  17. """添加课程到购物车"""
  18. # 接受客户端提交过来的课程ID
  19. course_id = request.data.get("course_id")
  20. try:
  21. course = models.Course.objects.get(pk=course_id, status=0)
  22. except:
  23. return Response({"message": "当前课程不存在或者已经下架了"}, status=status.HTTP_400_BAD_REQUEST)
  24.  
  25. # 计算课程的真实价格,调用写好的的在utils的计算折扣的方法
  26. price = get_course_real_price(course)
  27.  
  28. # 把课程id和课程价格保存到购物车中redis中
  29. # redis中使用hash类型保存数据
  30. redis = get_redis_connection("cart")
  31. # 获取当前登陆用户的ID,并写入redis中
  32. user_id = request.user.id
  33. pl = redis.pipeline()
  34. pl.multi()
  35. pl.hset("cart_%s" % user_id, course_id, price)
  36. # 把当前课程默认为勾选状态[勾选状态也要保存到redis中]
  37. # redis中使用set类型保存数据
  38. pl.sadd("cart_select_%s" % user_id, course_id)
  39. pl.execute()
  40.  
  41. # 返回响应操作
  42. return Response({"message": "success"}, status=status.HTTP_200_OK)
  43.  
  44. def get(self,request):
  45. # 获取当前登陆用户
  46. user_id = request.user.id
  47. # 从redis中获取所有的课程信息和勾选状态
  48. redis = get_redis_connection("cart")
  49. course_list = redis.hgetall("cart_%s" % user_id)
  50. selected_list = redis.smembers("cart_select_%s" % user_id)
  51.  
  52. # 构造数据返回给前端
  53. data = []
  54. for course_id, price in course_list.items():
  55. course_id = course_id.decode()
  56. price = price.decode()
  57.  
  58. try:
  59. course_info = models.Course.objects.get(pk=course_id)
  60. except:
  61. return Response({"message": "请求有误,请联系客服"}, status=status.HTTP_507_INSUFFICIENT_STORAGE)
  62. data.append({
  63. "id": course_id,
  64. "price": price,
  65. "selected": course_id.encode() in selected_list,
  66. "course_img": HOST+course_info.course_img.url,
  67. "name": course_info.name,
  68. })
  69.  
  70. # 返回给客户端
  71. return Response(data, status=status.HTTP_200_OK)
  72.  
  73. class CartCourseAPIView(APIView):
  74. permission_classes = [IsAuthenticated]
  75.  
  76. def post(self,request,pk):
  77. user = request.user
  78. print("user_id",user.id)
  79. try:
  80. course = models.Course.objects.get(pk=pk)
  81. except models.Course.DoesNotExist:
  82. return Response({"message": ""}, status=status.HTTP_400_BAD_REQUEST)
  83.  
  84. #获取勾选状态
  85. is_selected = request.data.get("is_select")
  86.  
  87. #引入redis
  88. redis = get_redis_connection("cart")
  89. if is_selected:
  90. # redis中增加当前课程id到勾选集合中
  91. redis.sadd("cart_select_%s" % user.id, pk)
  92. else:
  93. # redis中删除当前课程id
  94. redis.srem("cart_select_%s" % user.id, pk)
  95.  
  96. return Response({"message": ""}, status=status.HTTP_200_OK)
  97.  
  98. def delete(self,request,pk):
  99.  
  100. user = request.user
  101. try:
  102. course = models.Course.objects.get(pk=pk)
  103. except models.Course.DoesNotExist:
  104. return Response({"message": "无效的课程标号"}, status=status.HTTP_400_BAD_REQUEST)
  105.  
  106. # 从购物车和勾选集合中删除指定的数据
  107. redis = get_redis_connection("cart")
  108. pl = redis.pipeline()
  109. pl.multi()
  110. pl.hdel("cart_%s" % user.id, pk)
  111. pl.srem("cart_select_%s" % user.id, pk)
  112. pl.execute()
  113.  
  114. return Response({"message": "删除成功!"}, status=status.HTTP_200_OK)

前端cart.vue(父组件):

  1. <template>
  2. <div class="cart">
  3. <Header/>
  4. <div class="cart-info">
  5. <h3 class="cart-top">我的购物车 <span>共1门课程</span></h3>
  6. <div class="cart-title">
  7. <el-row>
  8. <el-col :span="">&nbsp;</el-col>
  9. <el-col :span="">课程</el-col>
  10. <el-col :span="">有效期</el-col>
  11. <el-col :span="">单价</el-col>
  12. <el-col :span="">操作</el-col>
  13. </el-row>
  14. </div>
  15. <CartItem v-for="item in course_list" :course="item" @change_select="total_price" @delete_course="del_course" :course_key="course_key" />
  16. <div class="calc">
  17. <el-row>
  18. <el-col :span="">&nbsp;</el-col>
  19. <el-col :span="">
  20. <el-checkbox label="全选" name="type"></el-checkbox></el-col>
  21. <el-col :span="" class="del"><i class="el-icon-delete"></i>删除</el-col>
  22. <el-col :span="" class="count">总计:¥{{total}}</el-col>
  23. <el-col :span="" class="cart-calc">去结算</el-col>
  24. </el-row>
  25. </div>
  26. </div>
  27. <Footer/>
  28. </div>
  29. </template>
  30.  
  31. <script>
  32. import Header from "./common/Header"
  33. import Footer from "./common/Footer"
  34. import CartItem from "./common/CartItem"
  35. export default {
  36. name:"Cart",
  37. data(){
  38. return {
  39. total:0,
  40. course_list:[],
  41. token: localStorage.token || sessionStorage.token,
  42. }
  43. },
  44.  
  45. components:{
  46. Header,
  47. Footer,
  48. CartItem,
  49. },
  50. methods:{
  51. del_course(course_key) {
  52. //course_key是通过字传父传回来,用于删除已删除的的购物车的课程
  53. this.course_list.splice(course_key, 1);
  54. // 重新计算总价格
  55. this.total_price();
  56. },
  57. //计算各种折算后,购物车的总价
  58. total_price(){
  59. // 计算总价格
  60. let cl = this.course_list;
  61. let total = 0;
  62. for(let i = 0;i<cl.length;i++){
  63. if(cl[i].selected){
  64. total+=parseFloat(cl[i].price);
  65. }
  66. }
  67. total = total.toFixed(2);
  68. this.total = total;
  69. },
  70. },
  71. created() {
  72. let _this = this;
  73. // 发起请求获取购物车中的商品信息
  74. _this.$axios.get("http://127.0.0.1:8000/cart/",{
  75. headers: {
  76. 'Authorization': 'JWT ' + _this.token
  77. },
  78. responseType: 'json',
  79. }).then(response=>{
  80. console.log("response.data",response.data)
  81. _this.course_list = response.data;
  82. this.total_price()
  83. })
  84.  
  85. },
  86. }
  87. </script>
  88.  
  89. <style scoped>
  90. .cart{
  91. margin-top: 80px;
  92. }
  93. .cart-info{
  94. overflow: hidden;
  95. width: 1200px;
  96. margin: auto;
  97. }
  98. .cart-top{
  99. font-size: 18px;
  100. color: #666;
  101. margin: 25px 0;
  102. font-weight: normal;
  103. }
  104. .cart-top span{
  105. font-size: 12px;
  106. color: #d0d0d0;
  107. display: inline-block;
  108. }
  109. .cart-title{
  110. background: #F7F7F7;
  111. }
  112. .cart-title .el-row,.cart-title .el-col{
  113. height: 80px;
  114. font-size: 14px;
  115. color: #333;
  116. line-height: 80px;
  117. }
  118. .calc .el-col{
  119. height: 80px;
  120. line-height: 80px;
  121. }
  122. .calc .el-row span{
  123. font-size: 18px!important;
  124. }
  125. .calc .el-row{
  126. font-size: 18px;
  127. color: #666;
  128. margin-bottom: 300px;
  129. margin-top: 50px;
  130. background: #F7F7F7;
  131. }
  132. .calc .del{
  133.  
  134. }
  135. .calc .el-icon-delete{
  136. margin-right: 15px;
  137. font-size: 20px;
  138. }
  139. .calc .count{
  140. text-align: right;
  141. margin-right:62px;
  142. }
  143. .calc .cart-calc{
  144. width: 159px;
  145. height: 80px;
  146. border: none;
  147. background: #ffc210;
  148. font-size: 18px;
  149. color: #fff;
  150. text-align: center;
  151. cursor: pointer;
  152. }
  153. </style>

前端cartitem.vue(子组件):

  1. <template>
  2. <div class="cart-item">
  3. <el-row>
  4. <el-col :span="2" class="checkbox"><el-checkbox label="" v-model="course.selected" name="type"></el-checkbox></el-col>
  5. <el-col :span="10" class="course-info">
  6. <img :src="course.course_img" alt="">
  7. <span>{{course.name}}</span>
  8. </el-col>
  9. <el-col :span="4">
  10. <el-select v-model="duration">
  11. <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option>
  12. </el-select>
  13. </el-col>
  14. <el-col :span="4" class="course-price">¥{{course.price}}</el-col>
  15. <el-col :span="4" class="course-delete"><span @click="delete_course(course.id)">删除</span></el-col>
  16. </el-row>
  17. </div>
  18. </template>
  19.  
  20. <script>
  21. export default {
  22. name:"CartItem",
  23.  
  24. props:["course","course_key"],
  25.  
  26. data(){
  27. return {
  28. token: localStorage.token || sessionStorage.token,
  29. duration: 60,
  30. options:[
  31. {value:30,label:"一个月有效"},
  32. {value:60,label:"二个月有效"},
  33. {value:90,label:"三个月有效"},
  34. {value:-1,label:"永久有效"},
  35. ],
  36.  
  37. }
  38. },
  39. mounted(){
  40.  
  41. },
  42.  
  43. methods:{
  44. //按删除键删除购物车的课程
  45. delete_course(course_id){
  46. let _this = this;
  47. this.$axios.delete(`http://127.0.0.1:8000/cart/${this.course.id}`, {
  48. headers: {
  49. // 附带已经登录用户的jwt token 提供给后端,一定不能疏忽这个空格
  50. 'Authorization': 'JWT ' + _this.token
  51. },
  52. responseType: "json",
  53. }).then(response => {
  54.  
  55. // 发送信息给父组件,通过父组件删除当前子组件
  56. _this.$emit("delete_course",_this.course_key);
  57. }).catch(error => {
  58. console.log(error.response);
  59. });
  60. },
  61. },
  62. watch:{
  63. "course.selected":function(){
  64. let _this = this;
  65. _this.$axios.post(`http://127.0.0.1:8000/cart/${this.course.id}`,{
  66. is_select: _this.course.selected
  67. },{
  68. headers:{
  69. // 附带已经登录用户的jwt token 提供给后端,一定不能疏忽这个空格
  70. 'Authorization':'JWT '+_this.token
  71. },
  72. responseType:"json",
  73. }).then(response=>{
  74. _this.$emit("change_select");
  75. }).catch(error=>{
  76. console.log( error.response );
  77. })
  78. }
  79. },
  80. }
  81. </script>
  82.  
  83. <style scoped>
  84. .cart-item{
  85. height: 250px;
  86. }
  87. .cart-item .el-row{
  88. height: 100%;
  89. }
  90. .course-delete{
  91. font-size: 14px;
  92. color: #ffc210;
  93. cursor: pointer;
  94. }
  95. .el-checkbox,.el-select,.course-price,.course-delete{
  96. display: flex;
  97. align-items: center;
  98. justify-content: center;
  99. height: 100%;
  100. }
  101. .el-checkbox{
  102. padding-top: 55px;
  103. }
  104. .el-select{
  105. padding-top: 45px;
  106. width: 118px;
  107. height: 28px;
  108. font-size: 12px;
  109. color: #666;
  110. line-height: 18px;
  111. }
  112. .course-info img{
  113. width: 175px;
  114. height: 115px;
  115. margin-right: 35px;
  116. vertical-align: middle;
  117. }
  118. .cart-item .el-col{
  119. padding: 67px 10px;
  120. vertical-align: middle!important;
  121. }
  122. .course-info{
  123.  
  124. }
  125. </style>

Luffy之购物车页面搭建的更多相关文章

  1. day83:luffy:添加购物车&导航栏购物车数字显示&购物车页面展示

    目录 1.添加购物车+验证登录状态 2.右上方购物车图标的小红圆圈数字 3.Vuex 4.购物车页面展示-后端接口 5.购物车页面展示-前端 6.解决一个购物车数量显示混乱的bug 1.添加购物车+验 ...

  2. 淘宝购物车页面 智能搜索框Ajax异步加载数据

    如果有朋友对本篇文章的一些知识点不了解的话,可以先阅读此篇文章.在这篇文章中,我大概介绍了一下构建淘宝购物车页面需要的基础知识. 这篇文章主要探讨的是智能搜索框Ajax异步加载数据.jQuery的社区 ...

  3. 淘宝购物车页面 PC端和移动端实战

    最近花了半个月的时间,做了一个淘宝购物车页面的Demo.当然,为了能够更加深入的学习,不仅仅有PC端的固定宽度的布局,还实现了移动端在Media Query为768px以下(也就是实现了ipad,ip ...

  4. FineUI小技巧(1)简单的购物车页面

    起因 最初是一位 FineUI 网友对购物车功能的需求,需要根据产品单价和数量来计算所有选中商品的总价. 这个逻辑最好在前台使用JavaScript实现,如果把这个逻辑移动到后台C#实现,则会导致过多 ...

  5. html5与js关于input[type='text']文本框value改变触发事件一些属性的区别oninput,onpropertychange,onchange和文本框的value点击全选状态onclick="select();"。做购物车页面时会要用到。

    关于input[type='text']文本框value改变触发事件一些属性的区别oninput,onpropertychange,onchange和文本框的点击全选状态onclick="s ...

  6. flask-前台布局页面搭建3

    4.前台布局的搭建 由于前端知识有限,我在网上下载的人家的前台源码,附上链接 https://link.jianshu.com/?t=https://github.com/mtianyan/movie ...

  7. 仿联想商城laravel实战---3、前端页面搭建(什么情况下需要路由接参数)

    仿联想商城laravel实战---3.前端页面搭建(什么情况下需要路由接参数) 一.总结 一句话总结: 比如访问课程的时候,不同的课程(比如云知梦),比如访问不同的商品,比如访问不同的分类 //商品详 ...

  8. 仿联想商城laravel实战---2、后端页面搭建(验证码如何在页面中使用)

    仿联想商城laravel实战---2.后端页面搭建(验证码如何在页面中使用) 一.总结 一句话总结: 放在img里面,img的src就是生产验证码的控制器路径: img src="/admi ...

  9. stark组件之显示页面搭建(四)

    页面搭建包括第一如何获取前端传过来的数据,第二如何在前端渲染出对应标签. 一.后台获取数据并进行处理 在路由系统中,每一个路由都对应着一个处理函数,如下所示: def wrapper(self, fu ...

随机推荐

  1. webpack的externals的使用

    externals 官网文档解释的很清楚,就是webpack可以不处理应用的某些依赖库,使用externals配置后,依旧可以在代码中通过CMD.AMD或者window/global全局的方式访问. ...

  2. python框架之Django(1)-第一个Django项目

    准备 自己写一个简单的webServer import socket # 生成socket实例对象 sk = socket.socket() # 绑定IP和端口 sk.bind(("127. ...

  3. 开发流程(Vue)

    1.当你拿到一个需求时,先不要着急完成静态页面 2.重点观察数据结构,进行数据的分析,包括前端所需要的数据类型从而进行数据类型定义(如果是前后端分离的情况下,建议不要考虑前端数据和数据库的数据类型对应 ...

  4. 前端学习历程--js--原型&闭包

    一.数据类型 1.值类型:undefined, number, string, boolean,不是对象 2.引用类型:函数.数组.对象.null.new Number(10)都是对象 3.引用类型判 ...

  5. 设置div 高度 总结

    如果将div 的height 设置为固定的像素值,在不同分辨率的显示屏上,会看到div 在浏览器上的高度不一致.可以以百分比的形式设置div 的高度.注意,这个百分比是针对div 的上一层标签而言的, ...

  6. Vue系列之 => 路由匹配

    路由基本使用,加动画切换 1 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  7. Lucky 7 (容斥原理 + 中国剩余定理)

    题意:求满足7的倍数,不满足其他条件num % p == a 的num的个数. 思路:利用中国剩余定理我i们可以求出7的倍数,但是多算了不满足约定条件又得减去一个,但是又发现多减了,又得加回来.如此, ...

  8. [Luogu]A%BProblem——线性筛素数与前缀和

    题目描述 题目背景 题目名称是吸引你点进来的[你怎么知道的] 实际上该题还是很水的[有种不祥的预感..] 题目描述 区间质数个数 输入输出格式 输入格式: 一行两个整数 询问次数n,范围m接下来n行, ...

  9. 第七篇——Struts2的接收参数

    Struts2的接收参数 1.使用Action的属性接收参数 2.使用Domain Model接收参数 3.使用ModelDriven接收参数 项目实例 1.项目结构 2.pom.xml <pr ...

  10. Jmeter登录后Session自动共享与多线程组并行

    在接口测试中,出于安全考虑接口是需要session才能访问.另外在此基础上,我们还可能模拟不同的客户端登录,需要并行运行移动端线程组. 实现session共享1)修改jmeter安装目录bin下的jm ...