28. 表单验证

课程练习

串接 API 并可以呈现产品列表、加入购物车、购物车列表功能,表单送出前进行表单验证。

课程练习连结

// JS


// 汇入语系档案
import zh_TW from './zh_TW.js';
// console.log(zh_TW);

Vue.component('loading' , VueLoading);

// 将 VeeValidate input 验证工具载入 作为全域注册
Vue.component('ValidationProvider', VeeValidate.ValidationProvider);

// 将 VeeValidate 完整表单 验证工具载入 作为全域注册
Vue.component('ValidationObserver', VeeValidate.ValidationObserver);

// 加入至 VeeValidate 的设定档案
VeeValidate.localize('tw', zh_TW);

// 表单 Class 设定档案
VeeValidate.configure({
  classes: {
    valid: 'is-valid',
    invalid: 'is-invalid',
  }
});


new Vue ({

  el: '#app',

  //资料
  data: {
    tempProduct: {},
    products: [],
    isLoading: false,
    carts: [],
    cartTotal: 0,
    status: {
      loadingItem:'',
    },
    uuid: '',
    apiPath: '',

    //表单
    form: {
      name: '',
      email: '',
      tel: '',
      address: '',
      payment: '',
      message: '',
    },



  },

  
  //方法 (会重复使用放这)
  methods: {    
    //取得产品资料
    getProducts(page = 1) { //使用page参数带进来 , =1 为参数预设值
      //进入此画面进行loading
      this.isLoading = true;
      //取得前台api
      const url = `${this.apiPath}/api/${this.uuid}/ec/products?page=${page}`;
      //取得远端资料
      axios.get(url).then(res => {
        // console.log(res);
        this.isLoading = false; //拿掉loading
        this.products = res.data.data; //将取得资料套入products里
      }).catch(error => {
        this.isLoading = false; //读取失败时 , 也要拿掉loading
      });
    },

    //取得单一产品资料
    getProduct(id) {
      //点击按钮 loading 动作
      this.status.loadingItem = id; //*有出错可能是data里的status未定义到.loadingItem
      //取得前台api
      const url = `${this.apiPath}/api/${this.uuid}/ec/product/${id}`;
      // console.log(id);
      axios.get(url).then(res => {
        // console.log(res);
        this.status.loadingItem = ''; //清掉点击按钮 loading 动作
        // this.tempProduct = res.data.data; //将取得资料暂存 tempProduct 里
        // this.tempProduct.num = 1; //预设数量为 1
        //进阶写法 (es6方式)
        this.tempProduct = {
          ...res.data.data,
          num: 1 
        };
        $('#productModal').modal('show'); //开启视窗
      });
    },
    
    //新增到购物车
    addToCart(id , quantity = 1) {      
      //取得前台api
      const url = `${this.apiPath}/api/${this.uuid}/ec/shopping`;
      //定义购物车
      const cart = {
        product: id,
        quantity, //*es6写法 , 当属性名称与值相同 , 可以缩写成同一个
      };
      // console.log(cart);
      axios.post(url , cart) //将单笔购物车资讯送上去
        .then(res => {
          this.isLoading = false; //拿掉loading
          console.log(res);
          this.getCart(); //重新取得购物车内容
          $('#productModal').modal('hide'); //关闭视窗
        })
        .catch(error => {
          this.isLoading = false; //拿掉loading
          console.log(error.response);
        });
    },

    //取得购物车
    getCart() {
      //进入此画面进行loading
      this.isLoading = true;
      //取得前台api
      const url = `${this.apiPath}/api/${this.uuid}/ec/shopping`;
      axios.get(url)
        .then(res => {    
          // console.log('购物车' , res);
          this.carts = res.data.data;
          this.updateTotal(); //增加删减後都会执行计算总价
          this.isLoading = false; //拿掉loading
        });      
    },

    //重新计算总价
    updateTotal() {
      //计算总价
      this.carts.forEach( item => {
        this.cartTotal += item.product.price * item.quantity;
      });
    },

    //更新数量
    updateQuantity(id , quantity) {
      //进入此画面进行loading
      this.isLoading = true;
      //取得前台api
      const url = `${this.apiPath}/api/${this.uuid}/ec/shopping`;
      //定义购物车
      const cart = {
        product: id,
        quantity, //*es6写法 , 当属性名称与值相同 , 可以缩写成同一个
      };
      // console.log(cart);
      axios.patch(url , cart) //将单笔购物车资讯送上去
        .then(res => {
          this.isLoading = false; //拿掉loading
          console.log(res);
          this.getCart(); //重新取得购物车内容
        })
        .catch(error => {
          this.isLoading = false; //拿掉loading
          console.log(error.response);
        });
    },

    //清除购物车所有品项
    removeAllCartItem() {
      //进入此画面进行loading
      this.isLoading = true;
      //取得前台api
      const url = `${this.apiPath}/api/${this.uuid}/ec/shopping/all/product`;
      
      axios.delete(url) //将单笔购物车资讯送上去
        .then(res => {
          this.isLoading = false; //拿掉loading
          this.getCart(); //重新取得购物车内容
        }); 
    },

    //清除购物车单一品项
    removeCartItem(id) {
      //进入此画面进行loading
      this.isLoading = true;
      //取得前台api
      const url = `${this.apiPath}/api/${this.uuid}/ec/shopping/${id}`;
      
      axios.delete(url) //将单笔购物车资讯送上去
        .then(res => {
          this.isLoading = false; //拿掉loading
          this.getCart(); //重新取得购物车内容
        }); 
    },

    //订单表单
    createOrder() {
      //进入此画面进行loading
      this.isLoading = true;
      //取得前台api
      const url = `${this.apiPath}/api/${this.uuid}/ec/orders`;

      axios.post(url, this.form)
        .then((res) => {
          if (res.data.data.id) {
            this.isLoading = false; //拿掉loading           
            $('#orderModal').modal('show'); // 跳出提示讯息         
            this.getCart(); //重新取得购物车内容
          }
        }).catch((error) => {
          this.isLoading = false; //拿掉loading      
          console.log(error.response.data.errors);
        });
    },


  },


  //创建 (只会单次使用放这)
  created() {
    this.getProducts();
    this.getCart();
  },


});

<<:  Day 28 Quantum Protocols and Quantum Algorithms

>>:  第28天:箭头函式与this()

计算资源及资料的设定02

建立了计算资源後,接下来要建立及处理有关资料的部分。 在Microsoft Azure Machin...

Day2 初次窥探配对框架

在开始实作与了解细部功能前,让我们先初步的看过整体架构是怎麽运作的,以利後续 demo 实作与各部件...

【第3天】资料前处理-YOLOv4与自动框选中文字

现况 观察主办单位提供的资料集(约7万张图档),发现图档大致分为下列几种。 1.1 图档内只有1个中...

[Day20] Scrum失败经验谈 – 只想得太大太远

Scrum是大家想要导入的文化与工具,在分享了很多工具、体会和方法後,感觉是个好时机要来讲如何导入s...

Day21-"排序、搜寻介绍"

剩最後10篇了,一起加油! 我们通常都会一次存入多笔资料,在这时候搜寻以及排序就变得相当重要,若是做...