Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 国产精品视频网址,天堂网www在线资源链接,欧美午夜在线视频

          整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          Demo購(gòu)物車

          增sku到購(gòu)物車

          上次課我們開(kāi)發(fā)到了顯示商品詳情

          有點(diǎn)擊"添加到購(gòu)物車"的按鈕

          但是沒(méi)有反應(yīng),我們完成添加購(gòu)物車的功能就能實(shí)現(xiàn)這個(gè)效果了

          打開(kāi)mall-order-webapi模塊

          業(yè)務(wù)邏輯中一些基本的注意事項(xiàng)

          • * 判斷用戶是否登錄,只有登錄后才能將商品新增到購(gòu)物車
          • * 驗(yàn)證購(gòu)物車信息的完整性
          • * 業(yè)務(wù)邏輯層要判斷新增的sku是否在當(dāng)前用戶的購(gòu)物車表中已經(jīng)存在
          • * 如果不存在是新增sku流程
          • * 如果已經(jīng)存在,是修改數(shù)量的流程

          開(kāi)發(fā)持久層

          持久層要按上面分析的業(yè)務(wù)邏輯,開(kāi)發(fā)多個(gè)方法

          1. 判斷當(dāng)前登錄用戶購(gòu)物車中是否包含指定skuid商品的方法
          2. 新增sku到購(gòu)物車表中
          3. 修改購(gòu)物車指定sku數(shù)量的方法

          mapper包創(chuàng)建OmsCartMapper接口,編寫代碼如下

          @Repository
          public interface OmsCartMapper {
          // 判斷當(dāng)前用戶的購(gòu)物車列表中是否包含指定sku商品的方法
          OmsCart selectExistsCart(@Param("userId") Long userId,@Param("skuId") Long skuId);
          // 新增商品到購(gòu)物車表中
          void saveCart(OmsCart omsCart);
          // 修改指定購(gòu)物車商品的數(shù)量的方法
          void updateQuantityById(OmsCart omsCart);
          }

          對(duì)應(yīng)的Mapper.xml文件

          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
          <mapper namespace="cn.tedu.mall.order.mapper.OmsCartMapper">
          <!-- 通用查詢映射結(jié)果 -->
          <resultMap id="BaseResultMap" type="cn.tedu.mall.pojo.order.model.OmsCart">
          <id column="id" property="id" />
          <result column="user_id" property="userId" />
          <result column="sku_id" property="skuId" />
          <result column="title" property="title" />
          <result column="main_picture" property="mainPicture" />
          <result column="price" property="price" />
          <result column="quantity" property="quantity" />
          <result column="gmt_create" property="gmtCreate" />
          <result column="gmt_modified" property="gmtModified" />
          <result column="bar_code" property="barCode"/>
          <result column="data" property="data"/>
          </resultMap>
          <!-- 聲明一個(gè)全字符sql片段 -->
          <sql id="SimpleQueryFields">
          <if test="true">
          id,
          user_id,
          sku_id,
          title,
          main_picture,
          price,
          quantity,
          gmt_create,
          gmt_modified
          </if>
          </sql>
          <!-- 判斷當(dāng)前用戶的購(gòu)物車列表中是否包含指定sku商品的方法 -->
          <select id="selectExistsCart" resultType="cn.tedu.mall.pojo.order.model.OmsCart">
          select
          <include refid="SimpleQueryFields" />
          from
          oms_cart
          where
          user_id=#{userId}
          and
          sku_id=#{skuId}
          </select>
          <!-- 新增購(gòu)物車信息 -->
          <insert id="saveCart" useGeneratedKeys="true" keyProperty="id">
          insert into oms_cart(
          user_id,
          sku_id,
          title,
          main_picture,
          price,
          quantity
          ) values(
          #{userId},
          #{skuId},
          #{title},
          #{mainPicture},
          #{price},
          #{quantity}
          )
          </insert>
          <!-- 根據(jù)購(gòu)物車id修改數(shù)量 -->
          <update id="updateQuantityById" >
          update
          oms_cart
          set
          quantity=#{quantity}
          where
          id=#{id}
          </update>
          </mapper>

          開(kāi)發(fā)業(yè)務(wù)邏輯層

          創(chuàng)建OmsCartServiceImpl類實(shí)現(xiàn)IOmsCartService接口

          實(shí)現(xiàn)其中方法,先實(shí)現(xiàn)新增購(gòu)物車的方法即可

          需要注意,我們?cè)跇I(yè)務(wù)邏輯層中需要使用用戶的信息

          要單獨(dú)編寫一個(gè)方法獲取用戶信息,

          @Service
          public class OmsCartServiceImpl implements IOmsCartService {
          @Autowired
          private OmsCartMapper omsCartMapper;
          @Override
          public void addCart(CartAddDTO cartDTO) {
          // 獲取當(dāng)前登錄用戶的userId
          Long userId=getUserId();
          // 查詢這個(gè)userId的用戶是否已經(jīng)將指定的sku添加到購(gòu)物車
          OmsCart omsCart=omsCartMapper.selectExistsCart(userId,cartDTO.getSkuId());
          // 判斷查詢結(jié)果是否為null
          if(omsCart!=null){
          // 不等于null,表示當(dāng)前用戶這個(gè)sku已經(jīng)添加在購(gòu)物車列表中
          // 我們需要做的就是修改它的數(shù)量,根據(jù)cartDTO對(duì)象的quantity屬性值添加
          omsCart.setQuantity(omsCart.getQuantity()+cartDTO.getQuantity());
          // 調(diào)用持久層方法修改數(shù)量
          omsCartMapper.updateQuantityById(omsCart);
          }else{
          // 如果omsCart是null 會(huì)運(yùn)行else代碼塊
          // 去完成購(gòu)物車對(duì)象的新增,先實(shí)例化OmsCart對(duì)象
          OmsCart newOmsCart=new OmsCart();
          // 將參數(shù)cartDTO的同名屬性賦值給newOmsCart
          BeanUtils.copyProperties(cartDTO,newOmsCart);
          // cartDTO對(duì)象中沒(méi)有userId屬性,需要單獨(dú)賦
          newOmsCart.setUserId(userId);
          // 執(zhí)行新增
          omsCartMapper.saveCart(newOmsCart);
          }
          }
          
          @Override
          public JsonPage<CartStandardVO> listCarts(Integer page, Integer pageSize) {
          return null;
          }
          
          @Override
          public void removeCart(Long[] ids) {
          }
          
          @Override
          public void removeAllCarts() {
          }
          
          @Override
          public void removeUserCarts(OmsCart omsCart) {
          }
          
          @Override
          public void updateQuantity(CartUpdateDTO cartUpdateDTO) {
          }
          
          // 業(yè)務(wù)邏輯層獲得用戶信息的方法,因?yàn)槎鄠€(gè)方法需要獲得用戶信息,所以單獨(dú)編寫一個(gè)方法
          // 這個(gè)方法的實(shí)現(xiàn)是SpringSecurity提供的登錄用戶的容器
          // 方法的目標(biāo)是獲得SpringSecurity用戶容器,從容器中獲得用戶信息
          public CsmallAuthenticationInfo getUserInfo(){
          // 獲得SpringSecurity容器對(duì)象
          UsernamePasswordAuthenticationToken authenticationToken=
          (UsernamePasswordAuthenticationToken)SecurityContextHolder.
          getContext().getAuthentication();
          // 判斷獲取的容器信息是否為空
          if(authenticationToken!=null){
          // 如果容器中有內(nèi)容,證明當(dāng)前容器中有登錄用戶信息
          // 我們獲取這個(gè)用戶信息并返回
          CsmallAuthenticationInfo csmallAuthenticationInfo=
          (CsmallAuthenticationInfo)authenticationToken.getCredentials();
          return csmallAuthenticationInfo;
          }
          throw new CoolSharkServiceException(ResponseCode.UNAUTHORIZED,"沒(méi)有登錄信息");
          }
          
          // 業(yè)務(wù)邏輯層中大多數(shù)方法都是獲得用戶id,所以編寫一個(gè)返回用戶id的方法
          public Long getUserId(){
          return getUserInfo().getId();
          }
          }

          開(kāi)發(fā)控制層

          創(chuàng)建OmsCartController

          @RestController
          @RequestMapping("/oms/cart")
          @Api(tags = "購(gòu)物車管理模塊")
          public class OmsCartController {
          @Autowired
          private IOmsCartService omsCartService;
          // 新增購(gòu)物車信息的控制層方法
          @PostMapping("/add")
          @ApiOperation("新增購(gòu)物車信息")
          // 判斷當(dāng)前用戶是否具有普通用戶權(quán)限ROLE_user
          // sso模塊登錄時(shí),會(huì)在用戶的權(quán)限列表中添加ROLE_user權(quán)限
          @PreAuthorize("hasRole('ROLE_user')")
          // cartAddDTO參數(shù)是需要經(jīng)過(guò)SpringValidation框架驗(yàn)證的
          // @Validated就是激活框架驗(yàn)證功能,如果cartAddDTO不滿足驗(yàn)證要求,會(huì)自動(dòng)運(yùn)行
          // 統(tǒng)一由異常處理類中的BingingException異常處理
          public JsonResult addCart(@Validated CartAddDTO cartAddDTO){
          omsCartService.addCart(cartAddDTO);
          return JsonResult.ok("成功添加到購(gòu)物車");
          }
          }

          先注意sso模塊application-test.yml的地址和端口號(hào)(密碼有兩個(gè))

          也要注意order模塊application-test.yml的地址和端口號(hào)

          都保證正確的前提下

          啟動(dòng) leaf passport order

          sso:10002

          order:10005

          先訪問(wèn)10002登錄獲得JWT 用戶名jackson密碼123456

          先登錄看到JWT 然后復(fù)制JWT

          轉(zhuǎn)到10005 order模塊 文檔管理->全局參數(shù)設(shè)置->添加參數(shù)

          參數(shù)名:Authorization

          參數(shù)值:Bearer [粘貼JWT]

          然后刷新當(dāng)前10005的界面

          然后進(jìn)行發(fā)送請(qǐng)求即可成功!

          <dependency>
          <groupId>javax.xml.bind</groupId>
          <artifactId>jaxb-api</artifactId>
          <version>2.3.0</version>
          </dependency>

          SpringSecurity驗(yàn)證規(guī)則

          SpringSecurity框架登錄后,一定會(huì)有一個(gè)權(quán)限列表

          在userDetails對(duì)象中

          我們登錄用戶的這個(gè)對(duì)象的值可能是

          {"authorities":["ROLE_user"],"id":1,"userType":"USER","username":"jackson"}

          sso模塊前臺(tái)用戶登錄時(shí),會(huì)authorities屬性中添加ROLE_user權(quán)限

          而后臺(tái)管理用戶登錄時(shí)會(huì)向authorities屬性中添加下面屬性

          ["/pms/product/read","/pms/product/update","/pms/product/delete"]

          所以想要在控制器運(yùn)行前判斷權(quán)限時(shí)就可以使用下面的寫法

          @PreAuthorize("hasAuthority('ROLE_user')")

          hasRole判斷是專用于判斷當(dāng)前用戶角色的指令

          hasRole會(huì)自動(dòng)在我們判斷的內(nèi)容前添加ROLE_

          @PreAuthorize("hasRole('ROLE_user')")

          開(kāi)發(fā)查詢購(gòu)物車功能

          開(kāi)發(fā)持久層

          OmsCartMapper添加方法如下

          // 根據(jù)當(dāng)前用戶id查詢購(gòu)物車列表
          List<CartStandardVO> selectCartsByUserId(Long userId);

          OmsCartMapper.xml添加對(duì)應(yīng)內(nèi)容

          <!-- 根據(jù)用戶id查詢購(gòu)物車信息 -->
          <select id="selectCartsByUserId"
          resultType="cn.tedu.mall.pojo.order.vo.CartStandardVO">
          select
          <include refid="SimpleQueryFields" />
          from
          oms_cart
          where
          user_id=#{id}
          </select>

          開(kāi)發(fā)業(yè)務(wù)邏輯層

          OmsCartServiceImpl業(yè)務(wù)實(shí)現(xiàn)

          返回值支持分頁(yè)結(jié)果,按分頁(yè)條件查詢

          // 根據(jù)用戶id分頁(yè)查詢當(dāng)前用戶的購(gòu)物車列表
          @Override
          public JsonPage<CartStandardVO> listCarts(Integer page, Integer pageSize) {
          // 獲得用戶id
          Long userId=getUserId();
          // 執(zhí)行查詢前設(shè)置分頁(yè)條件
          PageHelper.startPage(page,pageSize);
          // 執(zhí)行分頁(yè)查詢
          List<CartStandardVO> list=omsCartMapper.selectCartsByUserId(userId);
          // 實(shí)例化PageInfo對(duì)象獲得分頁(yè)信息后將它轉(zhuǎn)換為JsonPage返回
          return JsonPage.restPage(new PageInfo<>(list));
          }

          下面開(kāi)發(fā)控制層,調(diào)用方法進(jìn)行測(cè)試

          OmsCartController添加方法如下

          // 分頁(yè)查詢當(dāng)前用戶購(gòu)物車中的信息
          @GetMapping("/list")
          @ApiOperation("分頁(yè)查詢當(dāng)前用戶購(gòu)物車中的信息")
          @ApiImplicitParams({
          @ApiImplicitParam(value = "頁(yè)碼",name = "page",dataType = "int",example = "1"),
          @ApiImplicitParam(value = "每頁(yè)條數(shù)",name = "pageSize",
          dataType = "int",example = "5")
          })
            @PreAuthorize("hasRole('ROLE_user')")
          public JsonResult<JsonPage<CartStandardVO>> listCartByPage(
            // 當(dāng)控制器參數(shù)可能為空,當(dāng)空時(shí),我們要給它賦默認(rèn)值時(shí),可以用下面的格式
            @RequestParam(required = false,defaultValue = WebConsts.DEFAULT_PAGE)
            Integer page,
            @RequestParam(required = false,defaultValue = WebConsts.DEFAULT_PAGE_SIZE)
          Integer pageSize
          ){
            // 控制層調(diào)用業(yè)務(wù)邏輯層代碼
            JsonPage<CartStandardVO> jsonPage=omsCartService.listCarts(page,pageSize);
            return JsonResult.ok(jsonPage);
          }

          啟動(dòng)nacos\seata

          啟動(dòng)leaf\sso\order模塊

          測(cè)試http://localhost:10005/doc.html

          刪除\清空購(gòu)物車

          刪除購(gòu)物車的持久層

          我們刪除購(gòu)物車的功能支持同時(shí)刪除一個(gè)或多個(gè)購(gòu)物車中的商品

          基本思路就是將一個(gè)要?jiǎng)h除的購(gòu)物車商品的id數(shù)組傳入到Mapper中進(jìn)行刪除

          在OmsCartMapper接口中添加放方法

          // 根據(jù)購(gòu)物車的id刪除商品(支持刪除多個(gè)商品)
          int deleteCartsByIds(Long[] ids);

          對(duì)應(yīng)的mapper.xml

          <!-- 根據(jù)id刪除購(gòu)物車信息 -->
          <delete id="deleteCartsByIds">
          delete from
          oms_cart
          where
          id in
          <foreach collection="ids" item="id" separator="," open="(" close=")">
          #{id}
          </foreach>
          </delete>

          刪除購(gòu)物車的業(yè)務(wù)邏輯層

          OmsCartServiceImpl添加方法

          // 按ids數(shù)組中的id值刪除cart表中信息
          @Override
          public void removeCart(Long[] ids) {
          // 刪除是包含返回值的
          int rows=omsCartMapper.deleteCartsByIds(ids);
          if(rows==0){
          throw new CoolSharkServiceException(ResponseCode.NOT_FOUND,
          "購(gòu)物車中沒(méi)有您要?jiǎng)h除的商品");
          }
          }

          開(kāi)發(fā)控制層代碼

          OmsCartController

          @PostMapping("/delete")
          @ApiOperation("根據(jù)用戶選擇的購(gòu)物車商品刪除(支持批量)")
          @ApiImplicitParam(value = "刪除購(gòu)物車的id",name="ids",required = true,
          dataType = "array")
          @PreAuthorize("hasRole('ROLE_user')")
          public JsonResult removeCartsByIds(Long[] ids){
          omsCartService.removeCart(ids);
          return JsonResult.ok();
          }

          開(kāi)發(fā)清空當(dāng)前登錄用戶購(gòu)物車的功能

          <delete id="deleteCartsByUserId">
          delete from
          oms_cart
          where
          user_id=#{userId}
          </delete>
          @Override
          public void removeAllCarts() {
          }

          清空購(gòu)物車功能

          Mapper接口

          // 刪除當(dāng)前用戶購(gòu)物車中所有內(nèi)容
          int deleteCartsByUserId(Long userId);

          mapper.xml

          <!-- 刪除當(dāng)前用戶購(gòu)物車中所有內(nèi)容 -->
          <delete id="deleteCartsByUserId">
          delete from
          oms_cart
          where
          user_id=#{userId}
          </delete>

          OmsCartServiceImpl

          // 清空當(dāng)前登錄用戶購(gòu)物車
          @Override
          public void removeAllCarts() {
          Long userId=getUserId();
          int rows=omsCartMapper.deleteCartsByUserId(userId);
          if(rows==0){
          throw new CoolSharkServiceException(ResponseCode.NOT_FOUND,"您的購(gòu)物車中沒(méi)有商品");
          }
          }

          OmsCartController

          // 根據(jù)用戶id清空購(gòu)物車
          @PostMapping("/delete/all")
          @ApiOperation("根據(jù)用戶id清空購(gòu)物車")
          @PreAuthorize("hasRole('ROLE_user')")
          public JsonResult removeCartsByUserId(){
          omsCartService.removeAllCarts();;
          return JsonResult.ok("購(gòu)物車已清空");
          }

          修改購(gòu)物車商品數(shù)量

          開(kāi)發(fā)業(yè)務(wù)邏輯層

          因?yàn)榍懊嫖覀円呀?jīng)完成了修改購(gòu)物車數(shù)量的持久層,所以不需要再編寫了,直接從業(yè)務(wù)層開(kāi)始

          // 修改購(gòu)物車商品數(shù)量的方法
          @Override
          public void updateQuantity(CartUpdateDTO cartUpdateDTO) {
          // 持久層中已經(jīng)包含了修改數(shù)量的方法,但是參數(shù)是OmsCart
          // 將本方法的cartUpdateDTO參數(shù)值賦值給OmsCart再調(diào)用持久層方法即可
          OmsCart omsCart=new OmsCart();
          BeanUtils.copyProperties(cartUpdateDTO,omsCart);
          // 調(diào)用持久層實(shí)施修改
          omsCartMapper.updateQuantityById(omsCart);
          }

          控制層OmsCartController

          // 修改購(gòu)物車數(shù)量
          @PostMapping("/update/quantity")
          @ApiOperation("修改購(gòu)物車數(shù)量")
          @PreAuthorize("hasRole('ROLE_user')")
          public JsonResult updateQuantity(@Validated CartUpdateDTO cartUpdateDTO){
          omsCartService.updateQuantity(cartUpdateDTO);
          return JsonResult.ok("修改完成");
          }

          重啟order測(cè)試清空和修改購(gòu)物車數(shù)量的功能

          學(xué)習(xí)記錄,如有侵權(quán)請(qǐng)聯(lián)系刪除

          物車是一個(gè)商城程序的典型功能模塊,之前使用jquery制作過(guò),也使用angular開(kāi)發(fā)過(guò),今天將使用Vue實(shí)現(xiàn)購(gòu)物車效果,使用的主要技術(shù)有vue+axios+mockJS等。

          購(gòu)物車的主要功能如下:

          1. 勾選全選,所有商品全部選中。在取消全選框的時(shí)候所有商品取消選擇。

          2. 點(diǎn)擊單個(gè)商品上的加號(hào)減號(hào)進(jìn)行數(shù)量的增加和減少,右邊小計(jì)實(shí)時(shí)計(jì)算出這個(gè)商品的價(jià)格合計(jì)。

          3. 點(diǎn)擊單個(gè)商品上的刪除按鈕將商品從購(gòu)物車中刪除。

          4. 底部已選實(shí)時(shí)顯示已經(jīng)勾選的商品,右邊合計(jì)金額實(shí)時(shí)顯示所有勾選的商品的小計(jì)之和。

          購(gòu)物車的實(shí)現(xiàn)效果如圖所示:

          1、 HTML頁(yè)面布局和css樣式

          <!DOCTYPE html>
          <html lang="en">
          <head>
          <meta charset="UTF-8">
          <title>Document</title>
          <style>
          table{
          border-collapse:collapse;
          float: left;
          border:1px solid #999;
          }
          #btn{
          background:#999;
          color: #fff;
          }
          #shop{
          list-style: none;
          }
          #shop li{
          width: 400px;
          height:150px;
          border:1px solid #999;
          }
          #shop .p{
          width:200px;
          height:30px;
          background:gray;
          color: #fff;
          text-align: center;
          line-height:30px;
          }
          #shop .p1{
          color:orange;
          float: left;
          }
          #shop .p2{
          color: #999;
          float: left;
          margin-left:10px;
          }
          #shop .p3{
          clear: both;
          }
          </style>
          </head>
          <body>
          <div id="app">
          <ul id="shop">
          <li v-for="item,index in plist" :key="item.id" id="li">
          <p class="p">{{item.title}}</p>
          <p class="p1">¥{{item.sprice}}</p>
          <p class="p2"><del>¥{{item.price}}</del></p>
          <p class="p3">
          <span v-if="nums[item.id]">
          <button @click="sub(item)">-</button>
          {{nums[item.id]}}
          </span>
          <button @click="add(item)">+</button>
          </p>
          </li>
          </ul>
          <template v-if="car.length">
          <table border="1px">
          <tr v-for="item,index in car">
          <td>{{item.title}}</td>
          <td>
          ¥{{item.sprice}}
          <del>¥{{item.price}}</del>
          </td>
          <td>
          <button @click="carsub(index,item.id)">-</button>
          {{nums[item.id]}}
          <button @click="caradd(index,item.id,item.store)">+</button>
          </td>
          </tr>
          </table>
          <button @click="empty" id="btn">清空購(gòu)物車</button>
          總計(jì):<b>¥{{itotal}}</b>
          </template>
          </div>
          </body>
          </html>
          

          二、創(chuàng)建一個(gè)Vue對(duì)象,設(shè)置購(gòu)物車數(shù)據(jù)屬性

          var vm = new Vue({
          el:"#app",
          data:{
          plist:[],//存放列表數(shù)據(jù)
          car:[],
          nums:{},
          buyed:[]
          }
          });
          

          三、假設(shè)從后臺(tái)請(qǐng)求到數(shù)據(jù),然后賦值到Vue對(duì)象中

          后臺(tái)數(shù)據(jù)由mockjs模擬,使用axios發(fā)起請(qǐng)求獲取數(shù)據(jù)

          3.1 安裝axios

          npm install axios
          

          3.2 請(qǐng)求url地址

          var baseurl="http://axiostest.itsource.cn";
          

          3.3 發(fā)起請(qǐng)求獲取數(shù)據(jù)

          created:function(){
          var th = this;
          //當(dāng)vue實(shí)例化完成使用axios異步請(qǐng)求數(shù)據(jù)
          axios.get(baseurl+'/plists').then(function(res){
          th.plist=th.plist.concat(res.data.plists);
          //console.log(res.data)
          }).catch(function(err){
          console.log(err)
          });
          }
          

          3.4 mockjs攔截請(qǐng)求,模擬數(shù)據(jù)

          var data = {
          "list|10-20":
          [
          {
          "id":"@guid",
          "title":"@ctitle",
          "price|1-100.2":0,
          "sprice":function(){
          return this.price-3;
          },
          "store|2-20":1
          }
          ]
          }
          

          四、計(jì)算購(gòu)物車的總價(jià)

          computed:{
          itotal:function(){
          var total=0;
          for(var i=0;i<this.car.length;i++){
          total+=this.car[i].sprice*this.nums[this.car[i].id];
          }
          return total;
          }
          }
          

          五、購(gòu)物車中增加和減少數(shù)量

          methods:{
          //在購(gòu)物車中增加數(shù)量
          caradd:function(index,id,store){
          //判斷數(shù)量是否超過(guò)庫(kù)存
          if(this.nums[id]>store){
          return;
          }
          //this.car[index].num+=1;//數(shù)量加1
          this.nums[id]+=1;
          this.$set(this.car,index,this.car[index]);
          },
          //在購(gòu)物車中減少數(shù)量
          carsub:function(index,id){
          //數(shù)量少于1時(shí),刪除商品
          if(this.nums[id]<=1){
          this.car.splice(index,1);
          this.buyed.splice(index,1);
          delete this.nums[id];
          return;
          }
          //this.car[index].num-=1;//商品-1
          this.nums[id]-=1;
          this.$set(this.car,index,this.car[index]);
          }
          }
          

          六、添加商品,刪除商品,清空購(gòu)物車

          物車一般包含商品名稱、單價(jià)、數(shù)量等信息,數(shù)量可以任意新增或減少,商品項(xiàng)也可刪除,還可以支持全選或多選:

          最終效果

          我們把這個(gè)小項(xiàng)目分為三個(gè)文件:

          • index.html (頁(yè)面)
          • index.js (Vue 腳本)
          • style.css (樣式)

          1 index.js

          首先在 js 中初始化 Vue 實(shí)例,整體模板如下:

          var app = new Vue({
           el: '#app',
           data: {
           ...
           },
           mounted: function () {
           ...
           },
           computed: {
           ...
           },
           methods: {
           ...
           }
          });
          

          一般來(lái)說(shuō),這里的 data 來(lái)源于服務(wù)端數(shù)據(jù),這里為了簡(jiǎn)便,所以直接定義好的數(shù)據(jù):

          data: {
           /**
           * 購(gòu)物車中的商品列表
           */
           list: [
           {
           id: 1,
           name: '韓國(guó)進(jìn)口海牌海苔',
           price: 39.9,
           count: 1
           },
           {
           id: 2,
           name: '印尼進(jìn)口 Nabati 麗巧克(Richoco)休閑零食 巧克力味 威化餅干',
           price: 11.8,
           count: 1
           },
           {
           id: 3,
           name: '菲律賓進(jìn)口 道吉草 奶油夾',
           price: 6.5,
           count: 1
           }
           ],
           //選中的商品列表,用于計(jì)算總價(jià)
           checkList: []
           }
          
          • list 用于展示 購(gòu)物車中的商品列表。
          • checkList 用于表示勾選中的商品列表,后面,我們會(huì)利用它來(lái)計(jì)算選中商品的總價(jià)。
          mounted: function () {
           //默認(rèn)全選
           this.checkAll();
           this.checkAllElement(document.querySelector(".checkAll"));
          }
          

          當(dāng) mounted 時(shí),默認(rèn)全選購(gòu)物車內(nèi)的所有商品。

          computed: {
           /**
           * 總價(jià)
           * @returns {string}
           */
           totalPrice: function () {
           var total = 0;
           for (var i = 0; i < this.checkList.length; i++) {
           var item = this.checkList[i];
           total += item.price * item.count;
           }
           return total.toLocaleString();
           }
          }
          

          在計(jì)算屬性中,我們定義了總價(jià)的計(jì)算方式,它會(huì)綁定勾選的 checkList 來(lái)計(jì)算總價(jià)。之所以使用 toLocaleString 方法,是因?yàn)樾?shù)部分會(huì)自動(dòng)四舍五入,而且還會(huì)以千分位表示出來(lái),很方便哦O(∩_∩)O~

          methods: {
           /**
           * 減少購(gòu)買數(shù)量
           * @param index
           */
           reduceCount: function (index) {
           if (this.list[index].count === 1) return;
           this.list[index].count--;
           },
           /**
           * 增加購(gòu)買數(shù)量
           * @param index
           */
           addCount: function (index) {
           this.list[index].count++;
           },
           /**
           * 移除商品
           * @param index
           */
           remove: function (index) {
           console.log("remove-index:" + index);
           this.list.splice(index, 1);
           //獲取商品序號(hào)
           var id = index + 1;
           //移除實(shí)際參與計(jì)算的商品
           var $checkList = this.checkList;
           for (var i = 0; i < $checkList.length; i++) {
           var item = $checkList[i];
           if (item.id == id) {
           $checkList.splice(i, 1);
           }
           }
           },
           /**
           * 全選或全不選
           * @param event
           */
           checkAllOrNot: function (event) {
           if (event.target.checked) {//全選
           this.checkAll();
           console.log("checkList:" + this.checkList);
           } else { // 全不選
           console.log("全不選");
           this.checkInItems('noCheckAll');
           this.checkList.splice(0);//清空數(shù)組
           }
           },
           /**
           * 全選
           */
           checkAll: function () {
           console.log("全選");
           this.checkInItems('checkAll');
           this.checkList = this.list.concat();//復(fù)制商品列表
           },
           /**
           * 全選或全不選
           * @param type checkAll:全選;其他:全不選
           */
           checkInItems: function (type) {
           var items = document.querySelectorAll('.checkItem');
           for (var i = 0; i < items.length; i++) {
           var item = items[i];
           if (type === 'checkAll') {
           item.checked = true;
           } else {
           item.checked = false;
           }
           }
           },
           /**
           * 勾選或不勾選
           */
           checkItem: function (event, index) {
           console.log("checkItem");
           var element = event.target;
           var $allCheck = document.querySelector(".checkAll");
           if (element.checked) {//勾選,加入已選擇列表
           this.checkList.push(this.list[index]);
           this.checkAllElement($allCheck);
           } else {//不勾選,從已選擇列表中去除
           this.checkList.splice(index, 1);
           $allCheck.checked = false;
           }
           },
           /**
           * 勾選全選框
           * @param element
           */
           checkAllElement: function (element) {
           //如果所有的商品都已被勾選,則勾選全選框
           if (this.checkList.length == this.list.length) {
           element.checked = true;
           }
           }
          }
          

          在 methods 中,我們定義了以下功能方法:

          • 減少與增加購(gòu)買數(shù)量。在減少購(gòu)買數(shù)量方法中,我們對(duì)當(dāng)前所對(duì)應(yīng)商品的數(shù)量進(jìn)行了二次確認(rèn),讓代碼變得更加健壯(HTML 模板可能被修改,button 被替換為 div 或者 span,那么 disabled 樣式就變得無(wú)效啦)。
          • 移除某件商品。因?yàn)橘?gòu)物車中的商品列表與實(shí)際勾選的商品列表數(shù)量上有可能存在差異,所以我們必須通過(guò)找到商品 ID 再進(jìn)行刪除。
          • 勾選相關(guān)操作(全選、全不選、單選、單不選等)

          2 style.css

          [v-cloak] {
           display: none;
          }
          table {
           border: 1px solid #e9e9e9;
           border-collapse: collapse;
           border-spacing: 0;
           empty-cells: show;
          }
          th {
           font: bold 12px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
           color: #4f6b72;
           border-right: 1px solid #C1DAD7;
           border-bottom: 1px solid #C1DAD7;
           border-top: 1px solid #C1DAD7;
           letter-spacing: 2px;
           text-transform: uppercase;
           text-align: left;
           padding: 6px 6px 6px 12px;
           background: #CAE8EA;
          }
          td {
           border-right: 1px solid #C1DAD7;
           border-bottom: 1px solid #C1DAD7;
           background: #fff;
           font-size:14px;
           padding: 6px 6px 6px 12px;
           color: #4f6b72;
          }
          

          這里定義了 v-cloak 樣式,用于解決網(wǎng)絡(luò)慢時(shí)的閃屏問(wèn)題。還定義了表格的相關(guān)樣式。

          3 index.html

          接著在 index.html 中引入 Vue 腳本與樣式文件。基本模板如下:

          <!DOCTYPE html>
          <html lang="en">
          <head>
           <meta charset="UTF-8">
           <title>購(gòu)物車</title>
           <link rel="stylesheet" type="text/css" href="style.css">
          </head>
          <body>
          <div id="app" v-cloak>
           ...
          </div>
          <script src="https://cdn.bootcss.com/vue/2.2.2/vue.min.js"></script>
          <script src="index.js"></script>
          </body>
          </html>
          

          因?yàn)橛锌赡苜?gòu)物車中的商品被全部刪除,所以我們?cè)诖思恿伺袛?,如果列表為空,則給出友好提示:

          <template v-if="list.length">
           ...
          </template>
          <!--當(dāng)購(gòu)物車為空時(shí),則提示-->
          <div v-else>購(gòu)物車內(nèi)暫時(shí)沒(méi)有商品</div>
          

          接著用 table 來(lái)展示購(gòu)物車內(nèi)的商品列表:

          <table>
           <thead>
           <tr>
           <th><input id="checkAll" type="checkbox" class="checkAll" @click="checkAllOrNot($event)"></th>
           <th>序號(hào)</th>
           <th>商品</th>
           <th>單價(jià)</th>
           <th>數(shù)量</th>
           <th>操作</th>
           </tr>
           </thead>
           <tbody>
           <tr v-for="(item,index) in list">
           <td><input type="checkbox" class="checkItem" @click="checkItem($event,index)"></td>
           <td>{{index+1}}</td>
           <td>{{item.name}}</td>
           <td>{{item.price}}</td>
           <td>
           <button @click="reduceCount(index)" :disabled="item.count===1">-</button>
           {{item.count}}
           <button @click="addCount(index)">+</button>
           </td>
           <td>
           <button @click="remove(index)">刪除</button>
           </td>
           </tr>
           </tbody>
          </table>
          <div>總價(jià):¥{{totalPrice}}</div>
          
          • 使用 v-for 指令,循環(huán)迭代出商品列表。
          • 表格內(nèi)的每一個(gè)勾選框與按鈕都綁定了相應(yīng)的事件。全選框與每一行的勾選框還傳入了原生 DOM 事件 $event,用于獲取當(dāng)前所操作的元素。
          • *這里對(duì)減少商品數(shù)量的按鈕進(jìn)行了判斷,當(dāng)相應(yīng)商品的數(shù)量只剩下一個(gè)時(shí),綁定 disabled 樣式,讓它變成不可用。

          4 演示


          主站蜘蛛池模板: 国产午夜福利精品一区二区三区| 亚洲伦理一区二区| 日韩精品一区二区三区四区 | 精品一区二区三区色花堂 | 亚洲一区精品伊人久久伊人| 国产成人精品日本亚洲专一区| 国产午夜精品一区二区三区嫩草 | 精品亚洲av无码一区二区柚蜜| 国产成人一区二区三区视频免费| V一区无码内射国产| 色一情一乱一伦一区二区三区| 成人精品视频一区二区三区尤物| 麻豆aⅴ精品无码一区二区| 亚洲一区二区三区香蕉| 中文字幕亚洲一区| 熟女性饥渴一区二区三区| 精品久久国产一区二区三区香蕉| 韩国一区二区三区| 国产波霸爆乳一区二区| 中文字幕无码免费久久9一区9| 国产精品第一区第27页| 亚洲老妈激情一区二区三区| 中文字幕一区二区人妻性色| 精品国产福利第一区二区三区| 亚洲无线码一区二区三区| 久久一区二区三区精品| 一区二区中文字幕| 亚洲综合在线一区二区三区| 精品国产一区二区三区香蕉| 亚洲精品色播一区二区| 国产一区二区三区在线电影| 天堂不卡一区二区视频在线观看 | 麻豆国产在线不卡一区二区| 日韩熟女精品一区二区三区| 福利片福利一区二区三区| av在线亚洲欧洲日产一区二区| 日本一区二区在线| 极品尤物一区二区三区| 国产主播福利精品一区二区| 久久精品一区二区影院| 少妇特黄A一区二区三区|