Корзина BX.Vue

подключить vue
php до вызова компонента
\Bitrix\Main\UI\Extension::load("ui.vue");
\Bitrix\Main\UI\Extension::load("ui.vue.vuex");
template.php пустой

script.js
;(function (window) {   
   "use strict"

   const BX = window.BX;

   BX.Vue.component("basket", {
      props: {},
      data() {
         return {
            items: this.$store.state.items,
         }
      },
      created() {
         BX.Vue.event.$on("updateBasket", this.updateBasket)
      },
      mounted: function () {
         //this.$root.$on("sendMessage", this.eventCallback)         
      },
      updated: function () {},
      beforeDestroy() {},
      methods: {
         updateBasket: function () {
            this.getBasket()
         },
         getBasket: function () {
            store.commit("setLoad", true)
            var request = BX.ajax.runComponentAction("sell:basket", "getBasket", {
               mode: "class",
               method: "GET",
            })

            request.catch(function (response) {
               console.log(response.errors[response.errors.length - 1].message)
            })

            request.then(function (response) {
               if (response.status == "success") {
                  var items = []
                  for (var prop in response.data.items) {
                     items.push(response.data.items[prop])
                  }

                  store.commit("setbasketItems", items)
                  store.commit("setTotalprice", response.data.totalPrice)
                  store.commit("setLoad", false)
               }
            })
         },
         remove: function (ins) {
            var t = this

            var request = BX.ajax.runComponentAction("sell:basket", "DeleteInstallation", {
               mode: "class",
               data: {
                  installation: ins,
                  sessid: BX.message("bitrix_sessid"),
               },
            })

            request.catch(function (response) {
               console.log(response.errors[response.errors.length - 1].message)
               store.commit("setLoad", false)
            })

            request.then(function (response) {
               if (response.status == "success") {
                  t.getBasket()
               }
            })
         },
         save: function () {},
      },
      computed: {},
      template: `
       <div class="asside-basket">
         <div class="asside-block basket-title" >
            <div class="h4 text-center basket-h4">Cart</div>
         </div>
         <div class="loader-container square-rotate-3d" v-if="this.$store.state.loaded">
            <div class="loader"><div class="square"></div></div>
         </div>
         <div  v-if="!this.$store.state.loaded">
            <div class="asside-block__empty" v-if="this.$store.state.items.length==0"></div>
            <div class="asside-block"  v-if="this.$store.state.items.length==0">
               <div class="basket-item__title" style="margin-top:20px">
                  <p><b>Your Cart is empty</b></p>
                  <p>Please choose Product, Type of subscription, Type of License and number of working places and press Submit button to fullfill the Cart.</p>
                  <p class="mb-0">The nanoCAD Platform is already chosen!</p>
               </div>
            </div>
            <div v-if="this.$store.state.items.length>0">
                <div class="basket-items">
                  <div class="asside-block" v-for="item in this.$store.state.items" :key="item.installation">
                     <div class="basket-row-header">
                        <a href="javascript:void(0)" class="basket-close" v-on:click="remove(item.installation)" v-bind:data-remove="item.installation"></a>
                     </div>       
                     <div class="basket-item__title">Product</div>
                     <div class="row basket-row" v-for="basketItem in item.items" :key="basketItem.id">
                        <div class="col basket-row__title">{{basketItem.title}}</div>
                        <div class="col-auto basket-row__price">
                           <strike v-if="basketItem.discount && basketItem.discount!=basketItem.price">{{basketItem.discount}}</strike><br v-if="basketItem.discount  && basketItem.discount!=basketItem.price"/>
                           <span>$</span>{{basketItem.price}}
                        </div>
                     </div>
                     <div class="row basket-row">
                        <div class="col basket-row__title" v-html=item.summary></div>
                        <div class="col-auto basket-row__price"></div>
                     </div>
                     <div class="row">
                          <div class="col basket-item__title mb-0">Price for product:</div>
                          <div class="col-auto basket-row__price mb-0"><span>$</span><b>{{item.totalPrice}}</b></div>
                     </div>
                  </div>
               </div> 
               <div class="asside-block basket-total-block" v-if="this.$store.state.items.length>0">
                    <div class="row basket-row mb-0">
                       <div class="col basket-item__title">Total price:</div>
                       <div class="col-auto basket-row__price basket-row__price_main"><span>$</span><b>{{this.$store.state.totalPrice}}</b></div>
                    </div>
                    <a href="/order/checkout/" class="btn btn-blue w-100">Submit</a>
               </div>
            </div>
         </div>           
      </div> 
        `,
   })
})(window)

подписываемся на событие
BX.Vue.event.$on("updateBasket", this.updateBasket)
вызываем событие
BX.Vue.event.$emit("updateBasket", {});