整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          Demo購物車

          增sku到購物車

          上次課我們開發到了顯示商品詳情

          有點擊"添加到購物車"的按鈕

          但是沒有反應,我們完成添加購物車的功能就能實現這個效果了

          打開mall-order-webapi模塊

          業務邏輯中一些基本的注意事項

          • * 判斷用戶是否登錄,只有登錄后才能將商品新增到購物車
          • * 驗證購物車信息的完整性
          • * 業務邏輯層要判斷新增的sku是否在當前用戶的購物車表中已經存在
          • * 如果不存在是新增sku流程
          • * 如果已經存在,是修改數量的流程

          開發持久層

          持久層要按上面分析的業務邏輯,開發多個方法

          1. 判斷當前登錄用戶購物車中是否包含指定skuid商品的方法
          2. 新增sku到購物車表中
          3. 修改購物車指定sku數量的方法

          mapper包創建OmsCartMapper接口,編寫代碼如下

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

          對應的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">
          <!-- 通用查詢映射結果 -->
          <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>
          <!-- 聲明一個全字符sql片段 -->
          <sql id="SimpleQueryFields">
          <if test="true">
          id,
          user_id,
          sku_id,
          title,
          main_picture,
          price,
          quantity,
          gmt_create,
          gmt_modified
          </if>
          </sql>
          <!-- 判斷當前用戶的購物車列表中是否包含指定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>
          <!-- 新增購物車信息 -->
          <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>
          <!-- 根據購物車id修改數量 -->
          <update id="updateQuantityById" >
          update
          oms_cart
          set
          quantity=#{quantity}
          where
          id=#{id}
          </update>
          </mapper>

          開發業務邏輯層

          創建OmsCartServiceImpl類實現IOmsCartService接口

          實現其中方法,先實現新增購物車的方法即可

          需要注意,我們在業務邏輯層中需要使用用戶的信息

          要單獨編寫一個方法獲取用戶信息,

          @Service
          public class OmsCartServiceImpl implements IOmsCartService {
          @Autowired
          private OmsCartMapper omsCartMapper;
          @Override
          public void addCart(CartAddDTO cartDTO) {
          // 獲取當前登錄用戶的userId
          Long userId=getUserId();
          // 查詢這個userId的用戶是否已經將指定的sku添加到購物車
          OmsCart omsCart=omsCartMapper.selectExistsCart(userId,cartDTO.getSkuId());
          // 判斷查詢結果是否為null
          if(omsCart!=null){
          // 不等于null,表示當前用戶這個sku已經添加在購物車列表中
          // 我們需要做的就是修改它的數量,根據cartDTO對象的quantity屬性值添加
          omsCart.setQuantity(omsCart.getQuantity()+cartDTO.getQuantity());
          // 調用持久層方法修改數量
          omsCartMapper.updateQuantityById(omsCart);
          }else{
          // 如果omsCart是null 會運行else代碼塊
          // 去完成購物車對象的新增,先實例化OmsCart對象
          OmsCart newOmsCart=new OmsCart();
          // 將參數cartDTO的同名屬性賦值給newOmsCart
          BeanUtils.copyProperties(cartDTO,newOmsCart);
          // cartDTO對象中沒有userId屬性,需要單獨賦
          newOmsCart.setUserId(userId);
          // 執行新增
          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) {
          }
          
          // 業務邏輯層獲得用戶信息的方法,因為多個方法需要獲得用戶信息,所以單獨編寫一個方法
          // 這個方法的實現是SpringSecurity提供的登錄用戶的容器
          // 方法的目標是獲得SpringSecurity用戶容器,從容器中獲得用戶信息
          public CsmallAuthenticationInfo getUserInfo(){
          // 獲得SpringSecurity容器對象
          UsernamePasswordAuthenticationToken authenticationToken=
          (UsernamePasswordAuthenticationToken)SecurityContextHolder.
          getContext().getAuthentication();
          // 判斷獲取的容器信息是否為空
          if(authenticationToken!=null){
          // 如果容器中有內容,證明當前容器中有登錄用戶信息
          // 我們獲取這個用戶信息并返回
          CsmallAuthenticationInfo csmallAuthenticationInfo=
          (CsmallAuthenticationInfo)authenticationToken.getCredentials();
          return csmallAuthenticationInfo;
          }
          throw new CoolSharkServiceException(ResponseCode.UNAUTHORIZED,"沒有登錄信息");
          }
          
          // 業務邏輯層中大多數方法都是獲得用戶id,所以編寫一個返回用戶id的方法
          public Long getUserId(){
          return getUserInfo().getId();
          }
          }

          開發控制層

          創建OmsCartController

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

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

          也要注意order模塊application-test.yml的地址和端口號

          都保證正確的前提下

          啟動 leaf passport order

          sso:10002

          order:10005

          先訪問10002登錄獲得JWT 用戶名jackson密碼123456

          先登錄看到JWT 然后復制JWT

          轉到10005 order模塊 文檔管理->全局參數設置->添加參數

          參數名:Authorization

          參數值:Bearer [粘貼JWT]

          然后刷新當前10005的界面

          然后進行發送請求即可成功!

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

          SpringSecurity驗證規則

          SpringSecurity框架登錄后,一定會有一個權限列表

          在userDetails對象中

          我們登錄用戶的這個對象的值可能是

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

          sso模塊前臺用戶登錄時,會authorities屬性中添加ROLE_user權限

          而后臺管理用戶登錄時會向authorities屬性中添加下面屬性

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

          所以想要在控制器運行前判斷權限時就可以使用下面的寫法

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

          hasRole判斷是專用于判斷當前用戶角色的指令

          hasRole會自動在我們判斷的內容前添加ROLE_

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

          開發查詢購物車功能

          開發持久層

          OmsCartMapper添加方法如下

          // 根據當前用戶id查詢購物車列表
          List<CartStandardVO> selectCartsByUserId(Long userId);

          OmsCartMapper.xml添加對應內容

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

          開發業務邏輯層

          OmsCartServiceImpl業務實現

          返回值支持分頁結果,按分頁條件查詢

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

          下面開發控制層,調用方法進行測試

          OmsCartController添加方法如下

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

          啟動nacos\seata

          啟動leaf\sso\order模塊

          測試http://localhost:10005/doc.html

          刪除\清空購物車

          刪除購物車的持久層

          我們刪除購物車的功能支持同時刪除一個或多個購物車中的商品

          基本思路就是將一個要刪除的購物車商品的id數組傳入到Mapper中進行刪除

          在OmsCartMapper接口中添加放方法

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

          對應的mapper.xml

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

          刪除購物車的業務邏輯層

          OmsCartServiceImpl添加方法

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

          開發控制層代碼

          OmsCartController

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

          開發清空當前登錄用戶購物車的功能

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

          清空購物車功能

          Mapper接口

          // 刪除當前用戶購物車中所有內容
          int deleteCartsByUserId(Long userId);

          mapper.xml

          <!-- 刪除當前用戶購物車中所有內容 -->
          <delete id="deleteCartsByUserId">
          delete from
          oms_cart
          where
          user_id=#{userId}
          </delete>

          OmsCartServiceImpl

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

          OmsCartController

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

          修改購物車商品數量

          開發業務邏輯層

          因為前面我們已經完成了修改購物車數量的持久層,所以不需要再編寫了,直接從業務層開始

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

          控制層OmsCartController

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

          重啟order測試清空和修改購物車數量的功能

          學習記錄,如有侵權請聯系刪除

          物車是一個商城程序的典型功能模塊,之前使用jquery制作過,也使用angular開發過,今天將使用Vue實現購物車效果,使用的主要技術有vue+axios+mockJS等。

          購物車的主要功能如下:

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

          2. 點擊單個商品上的加號減號進行數量的增加和減少,右邊小計實時計算出這個商品的價格合計。

          3. 點擊單個商品上的刪除按鈕將商品從購物車中刪除。

          4. 底部已選實時顯示已經勾選的商品,右邊合計金額實時顯示所有勾選的商品的小計之和。

          購物車的實現效果如圖所示:

          1、 HTML頁面布局和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">清空購物車</button>
          總計:<b>¥{{itotal}}</b>
          </template>
          </div>
          </body>
          </html>
          

          二、創建一個Vue對象,設置購物車數據屬性

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

          三、假設從后臺請求到數據,然后賦值到Vue對象中

          后臺數據由mockjs模擬,使用axios發起請求獲取數據

          3.1 安裝axios

          npm install axios
          

          3.2 請求url地址

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

          3.3 發起請求獲取數據

          created:function(){
          var th = this;
          //當vue實例化完成使用axios異步請求數據
          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攔截請求,模擬數據

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

          四、計算購物車的總價

          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;
          }
          }
          

          五、購物車中增加和減少數量

          methods:{
          //在購物車中增加數量
          caradd:function(index,id,store){
          //判斷數量是否超過庫存
          if(this.nums[id]>store){
          return;
          }
          //this.car[index].num+=1;//數量加1
          this.nums[id]+=1;
          this.$set(this.car,index,this.car[index]);
          },
          //在購物車中減少數量
          carsub:function(index,id){
          //數量少于1時,刪除商品
          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]);
          }
          }
          

          六、添加商品,刪除商品,清空購物車

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

          最終效果

          我們把這個小項目分為三個文件:

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

          1 index.js

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

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

          一般來說,這里的 data 來源于服務端數據,這里為了簡便,所以直接定義好的數據:

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

          當 mounted 時,默認全選購物車內的所有商品。

          computed: {
           /**
           * 總價
           * @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();
           }
          }
          

          在計算屬性中,我們定義了總價的計算方式,它會綁定勾選的 checkList 來計算總價。之所以使用 toLocaleString 方法,是因為小數部分會自動四舍五入,而且還會以千分位表示出來,很方便哦O(∩_∩)O~

          methods: {
           /**
           * 減少購買數量
           * @param index
           */
           reduceCount: function (index) {
           if (this.list[index].count === 1) return;
           this.list[index].count--;
           },
           /**
           * 增加購買數量
           * @param index
           */
           addCount: function (index) {
           this.list[index].count++;
           },
           /**
           * 移除商品
           * @param index
           */
           remove: function (index) {
           console.log("remove-index:" + index);
           this.list.splice(index, 1);
           //獲取商品序號
           var id = index + 1;
           //移除實際參與計算的商品
           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);//清空數組
           }
           },
           /**
           * 全選
           */
           checkAll: function () {
           console.log("全選");
           this.checkInItems('checkAll');
           this.checkList = this.list.concat();//復制商品列表
           },
           /**
           * 全選或全不選
           * @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 中,我們定義了以下功能方法:

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

          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 樣式,用于解決網絡慢時的閃屏問題。還定義了表格的相關樣式。

          3 index.html

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

          <!DOCTYPE html>
          <html lang="en">
          <head>
           <meta charset="UTF-8">
           <title>購物車</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>
          

          因為有可能購物車中的商品被全部刪除,所以我們在此加了判斷,如果列表為空,則給出友好提示:

          <template v-if="list.length">
           ...
          </template>
          <!--當購物車為空時,則提示-->
          <div v-else>購物車內暫時沒有商品</div>
          

          接著用 table 來展示購物車內的商品列表:

          <table>
           <thead>
           <tr>
           <th><input id="checkAll" type="checkbox" class="checkAll" @click="checkAllOrNot($event)"></th>
           <th>序號</th>
           <th>商品</th>
           <th>單價</th>
           <th>數量</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>總價:¥{{totalPrice}}</div>
          
          • 使用 v-for 指令,循環迭代出商品列表。
          • 表格內的每一個勾選框與按鈕都綁定了相應的事件。全選框與每一行的勾選框還傳入了原生 DOM 事件 $event,用于獲取當前所操作的元素。
          • *這里對減少商品數量的按鈕進行了判斷,當相應商品的數量只剩下一個時,綁定 disabled 樣式,讓它變成不可用。

          4 演示


          主站蜘蛛池模板: 国产精品一区在线观看你懂的| 午夜影院一区二区| 人妻无码第一区二区三区| 国模大胆一区二区三区| 日韩精品无码一区二区三区 | 亚洲国产精品一区二区成人片国内| 一区二区三区在线|欧| 亚洲国产专区一区| 国产精品亚洲一区二区三区在线观看| 午夜福利av无码一区二区| 国产亚洲情侣一区二区无| 国产伦精品一区二区三区免.费 | 久久一区二区明星换脸| 一区二区三区在线免费观看视频 | 久久人妻内射无码一区三区| 亚洲av午夜精品一区二区三区| 国产激情一区二区三区小说| 日韩在线一区二区| 一区二区三区视频| 亚洲国产精品无码久久一区二区| 中文日韩字幕一区在线观看| 国产精品 一区 在线| 国产一区二区免费在线| 视频一区二区在线播放| 国产在线精品一区二区| 国产伦精品一区二区三区免.费 | 一区二区三区视频网站| 四虎精品亚洲一区二区三区| 色多多免费视频观看区一区| 日韩一区二区三区精品| 亚洲高清偷拍一区二区三区| 亚洲爽爽一区二区三区| 国产成人无码一区二区在线观看 | 国产福利一区二区三区| 亚洲欧美一区二区三区日产| 国内精品视频一区二区八戒| 日韩精品无码一区二区三区免费| 亚洲熟妇成人精品一区| 国产aⅴ一区二区三区| 一区二区三区影院| 日韩高清国产一区在线|