vue购物车案例、v-model进阶、与后端交互

一 购物车案例

- 结算

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>购物车结算</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
    <style>
        table, td {
            border: 1px solid black;
            text-align: center;
        }
    </style>
</head>
<body>
<div id="box">
    <table>
        <tr>
            <td>商品名称</td>
            <td>价格</td>
            <td>数量</td>
            <td>选择</td>
        </tr>
        <tr v-for="item in dataList">
            <td>{{item.name}}</td>
            <td>{{item.price}}</td>
            <td>{{item.number}}</td>
            <td><input type="checkbox" :value="item" v-model="checkGroup"></td>
        </tr>
    </table>
    <br>已选商品:{{checkGroup}}
    <br>总价:{{getPrice()}}
</div>
</body>
<script>
    var vm = new Vue({
        el: '#box',
        data: {
            dataList: [
                {name: '今瓶没', price: 99, number: 2},
                {name: '西柚记', price: 59, number: 1},
                {name: '水壶转', price: 89, number: 5},
            ],
            checkGroup: [],
        },
        methods: {
            getPrice() {
                let sum_price = 0
                for (i in this.checkGroup) {    // 这里的 i 是索引
                    sum_price += this.checkGroup[i]['number'] * this.checkGroup[i]['price']
                }
                return sum_price
            }
        }
    })
</script>
</html>

img

- 全选/全不选

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>全选/全不选</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
    <style>
        table, td {
            border: 1px solid black;
            text-align: center;
        }
    </style>
</head>
<body>
<div id="box">
    <table>
        <tr>
            <td>商品名称</td>
            <td>价格</td>
            <td>数量</td>
            <td>全选/全不选<input type="checkbox" v-model="allChecked" @change="checkAll"></td>
        </tr>
        <tr v-for="item in dataList">
            <td>{{item.name}}</td>
            <td>{{item.price}}</td>
            <td>{{item.number}}</td>
            <td><input type="checkbox" :value="item" v-model="checkGroup" @change="checkOne"></td>
        </tr>
    </table>
    <br>已选商品:{{checkGroup}}
    <br>总价:{{getPrice()}}
</div>
</body>
<script>
    var vm = new Vue({
        el: '#box',
        data: {
            dataList: [
                {name: '今瓶没', price: 99, number: 2},
                {name: '西柚记', price: 59, number: 1},
                {name: '水壶转', price: 89, number: 5},
            ],
            checkGroup: [],
            allChecked: false,
        },
        methods: {
            getPrice() {
                let sum_price = 0
                for (i in this.checkGroup) {    // 这里的 i 是索引
                    sum_price += this.checkGroup[i]['number'] * this.checkGroup[i]['price']
                }
                return sum_price
            },
            checkAll() {
                if (this.checkGroup.length > 0) {
                    this.checkGroup = []
                } else {
                    this.checkGroup = this.dataList
                }
            },
            checkOne() {
                // if (this.checkGroup.length === this.dataList.length) {
                //     this.allChecked = true
                // } else {
                //     this.allChecked = false
                // }
                this.allChecked = this.checkGroup.length === this.dataList.length;
            }
        }
    })
</script>
</html>

img

- 数量加减

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>控制加减</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.3/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="row">
    <div id="box" class="col-md-4 offset-md-1 text-center mt-5 ">
        <table class="table table-bordered">
            <thead>
            <tr>
                <th scope="col">商品名称</th>
                <th scope="col">单价</th>
                <th scope="col">数量</th>
                <th scope="col">全选/全不选 <input type="checkbox" v-model="allChecked" @change="checkAll"></th>
            </tr>
            </thead>
            <tbody>
            <tr v-for="item in dataList">
                <td>{{item.name}}</td>
                <td>{{item.price}}</td>
                <td>
                    <button class="btn link btn-sm" @click="reduceNum(item)">-</button>
                    {{item.number}}
                    <button class="btn link btn-sm" @click="item.number++">+</button>
                </td>
                <td><input type="checkbox" :value="item" v-model="checkGroup" @change="checkOne"></td>
            </tr>
            <tr class="text-left">
                <td colspan="4">总价:{{getPrice()}}
            </tr>
            </tbody>
        </table>
    </div>
</div>
</body>
<script>
    var vm = new Vue({
        el: '#box',
        data: {
            dataList: [
                {name: '今瓶没', price: 99, number: 1},
                {name: '西柚记', price: 59, number: 1},
                {name: '水壶转', price: 89, number: 1},
            ],
            checkGroup: [],
            allChecked: false,
        },
        methods: {
            getPrice() {
                let sum_price = 0
                for (i in this.checkGroup) {
                    sum_price += this.checkGroup[i]['number'] * this.checkGroup[i]['price']
                }
                return sum_price
            },
            checkAll() {
                if (this.checkGroup.length > 0) {
                    this.checkGroup = []
                } else {
                    this.checkGroup = this.dataList
                }
            },
            checkOne() {
                // if (this.checkGroup.length === this.dataList.length) {
                //     this.allChecked = true
                // } else {
                //     this.allChecked = false
                // }
                this.allChecked = this.checkGroup.length === this.dataList.length;
            },
            reduceNum(item) {
                if (item.number === 1) {
                    item.number = 1
                } else {
                    item.number--
                }
            }
        }
    })
</script>
</html>

img

二:v-model进阶

v-model 之 lazy、number、trim

  • lazy:等待input框的数据绑定时区焦点之后再变化
  • number:数字开头,只保留数字,后面的字母不保留;字母开头,都保留
  • trim:去除首位的空格
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-model 之 lazy、number、trim</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
</head>
<body>
<div id="box">
    <input type="text" v-model="myText1" placeholder="normal"> {{myText1}}
    <br>
    <input type="text" v-model.lazy="myText2" placeholder="lazy"> {{myText2}}
    <br>
    <input type="text" v-model.number="myText3" placeholder="number"> {{myText3}}
    <br>
    <input type="text" v-model.trim="myText4" placeholder="trim"> {{myText4}}
</div>
</body>
<script>
    var vm = new Vue({
        el: '#box',
        data: {
            myText1: '',
            myText2: '',
            myText3: '',
            myText4: '',
        },
    })
</script>
</html>

img

 

三 与后端交互 - ajax

版本1 - 出现了跨域问题

前端:index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue与后端交互 - 出现了跨域问题</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
</head>
<body>
<div id="box">
    <button @click="handleClick">加载数据</button>
</div>
</body>
<script>
    let vm = new Vue({
        el: '#box',
        data: {},
        methods: {
            handleClick() {
                $.ajax({
                    url: 'http://127.0.0.1:5000/',    // 发送请求的url,本地的5000端口,是flask的默认端口
                    method: 'get',
                    success: (data) => {
                        console.log(data)
                    }
                })
            }
        }
    })
</script>
</html>
后端:main.py
from flask import Flask    # 这里用轻量级的Flask框架来测试

app = Flask(__name__)


@app.route('/')
def index():
    print('请求来了')
    return 'Hello World'


if __name__ == '__main__':
    app.run()

img

这里可以看出:前端向后端成功发送了请求,后端也成功响应了,但是前端却报错了

这是因为:跨域问题的存在,浏览器检测到前端和后端不是来自同一个,所以认为这是不安全的,所以就拦截了该资源的传递

想要解决这个问题,就要实现:CORS,也就是 跨域资源共享

版本2 - 解决了跨域问题

前端:index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue与后端交互 - 解决了跨域问题</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
</head>
<body>
<div id="box">
    <button @click="handleClick">加载数据</button>
    <p>加载的数据:{{myText}}</p>
</div>
</body>
<script>
    let vm = new Vue({
        el: '#box',
        data: {
            myText: ''
        },
        methods: {
            handleClick() {
                $.ajax({
                    url: 'http://127.0.0.1:5000/',
                    method: 'get',
                    success: (data) => {
                        console.log(data)
                        this.myText = data
                    }
                })
            }
        }
    })
</script>
</html>
后端:main.py
from flask import Flask, make_response

app = Flask(__name__)


@app.route('/')
def index():
    print('请求来了')
    res = make_response('Hello World')
    res.headers['Access-Control-Allow-Origin'] = '*'    # 访问控制允许的源 设置为全部
    return res


if __name__ == '__main__':
    app.run()

img

版本3 - 后端读取json文件传到前端

json文件:file.json
{
  "name": "Darker",
  "age": "18",
  "gender": "male"
}
前端:index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue与后端交互 - json</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
</head>
<body>
<div id="box">
    <button @click="handleClick">加载数据</button>
    <p>加载的数据:{{myText}}</p>
</div>
</body>
<script>
    let vm = new Vue({
        el: '#box',
        data: {
            myText: ''
        },
        methods: {
            handleClick() {
                $.ajax({
                    url: 'http://127.0.0.1:5000/',
                    method: 'get',
                    success: (data) => {
                        console.log(data)
                        this.myText = data
                    }
                })
            }
        }
    })
</script>
</html>
后端:main.py
import json

from flask import Flask, jsonify

app = Flask(__name__)


@app.route('/')
def index():
    print('请求来了')
    with open('file.json', mode='rt', encoding='utf-8') as f:
        dic = json.load(f)
    res = jsonify(dic)
    res.headers['Access-Control-Allow-Origin'] = '*'
    return res


if __name__ == '__main__':
    app.run()

img

fetch

1.简介

① fetch介绍

提供了一个 JavaScript 接口,用于访问和操纵 HTTP 管道的一些具体部分,例如请求和响应

它还提供了一个全局 fetch() 方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源

② fetch基本格式
fetch('http://example.com/movies.json')
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(myJson);
  });

2.实例

json文件:file.json
{
  "name": "Darker",
  "age": "18",
  "gender": "male"
}
后端:main.py
import json

from flask import Flask, jsonify

app = Flask(__name__)


@app.route('/')
def index():
    print('请求来了')
    with open('file.json', mode='rt', encoding='utf-8') as f:
        dic = json.load(f)
    res = jsonify(dic)
    res.headers['Access-Control-Allow-Origin'] = '*'
    return res


if __name__ == '__main__':
    app.run()
前端:index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue与后端交互 - fetch</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
</head>
<body>
<div id="box">
    <button @click="handleClick">加载数据</button>
    <p>加载的数据:</p>
    <ul>
        <li >姓名:{{name}}</li>
        <li >年龄:{{age}}</li>
        <li >性别:{{gender}}</li>
    </ul>
</div>
</body>
<script>
    let vm = new Vue({
        el: '#box',
        data: {
            name:'',
            age: '',
            gender: ''
        },
        methods: {
            handleClick() {
                fetch('http://127.0.0.1:5000/').then(response => {
                    return response.json()
                }).then(json => {
                    console.log('从后端获取的json数据', json)   // success 获取的数据
                    this.name = json.name
                    this.age = json.age
                    this.gender = json.gender
                }).catch(ex => {
                    console.log('出现了异常', ex)    // 抛出异常
                })
            }
        }
    })
</script>
</html>

img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/306731.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Real Fire Smoke

资产使用高分辨率的动画Spritesheet,并结合了Shuriken粒子系统。具有3种风格的火焰和爆炸。 效果分为7类。 主要特点: - 3种火 - 预制板共计80块 - 5种爆炸声 - 3个循环的火灾声音 - 7张火焰和烟雾的精灵图 - 8x8 帧的 spritesheet,分辨率在 2048 到 8192 像素之间 效果类别…

Spring cloud聚合父工程project

文章目录 本次微服务版本一. 新建父工程project1.1设置字符集utf-81.2注解生效激活1.3. Java8编译版本 二. 父工程 pom.xml 本次微服务版本 一. 新建父工程project 1.1设置字符集utf-8 1.2注解生效激活 1.3. Java8编译版本 二. 父工程 pom.xml <?xml version"1.0&quo…

【深度学习每日小知识】Logistic Loss 逻辑回归:损失和正则化

逻辑回归的损失函数 线性回归的损失函数是平方损失。逻辑回归的损失函数是对数损失&#xff0c;定义如下&#xff1a; L o g L o s s ∑ ( x , y ) ∈ D − y log ⁡ ( y ′ ) − ( 1 − y ) log ⁡ ( 1 − y ′ ) LogLoss\sum_{(x,y)\in D}-y\log(y)-(1-y)\log(1-y) LogLoss…

漫谈与人类智能相关数学知识的不足之处

客观地说&#xff0c;没有数学就没有当前的大语言模型、多模态大模型&#xff0c;甚至压根就没有人工智能。对人工智能而言&#xff0c;数学就是“天”&#xff01;但是&#xff0c;对于人类智能而言&#xff0c;数学虽然起到了很重要的作用&#xff0c;同样也起到了阻碍作用&a…

Application为啥不能作为Dialog的context?

大家好&#xff0c;相信大家在使用Dialog时&#xff0c;都有一个非常基本的认知&#xff1a;就是Dialog的context只能是Activity&#xff0c;而不能是Application&#xff0c;不然会导致弹窗崩溃&#xff1a; 这个Exception几乎属于是每个Android开发初学者都会碰到的&#xff…

FFmpeg获取音视频流信息

文章目录 前言一、需求二、源码三、运行结果 前言 本文记录用 FFmpeg 获取视频流音频流的信息&#xff08;编码格式、分辨率、帧率、播放时长…&#xff09;&#xff0c;所用的工程基于上个博客编译成功的工程&#xff1a;使用FFmpeg4.3.1的SDK官方开发包编译ffmpeg.c 一、需求…

扩展边界opencv

扩展图像的边缘&#xff08;如上边增加50像素&#xff09;通常是通过添加额外的像素行来实现的 使用cv2.copyMakeBorder函数 valueborder_color指定了边框的颜色 import cv2 import numpy as np# 读取图像 image cv2.imread(th.jpg)# 设置边框宽度 top_border_width 50 # …

序列模型(4)—— Scaling Laws

本文介绍 LLM 训练过程中重要的 Scaling Laws&#xff0c;这是一个经验规律&#xff0c;指出了固定训练成本&#xff08;总计算量FLOPs&#xff09; C C C 时&#xff0c;如何调配模型规模&#xff08;参数量&#xff09; N N N 和训练 Token 数据量 D D D&#xff0c;才能实现…

【Emgu.CV教程】4.3、无缝融合应用之SeamlessClone()

SeamlessClone()函数才是真正的无缝克隆&#xff0c;它可以将一张小一点的图片&#xff0c;复制到另一张大一点的图片中&#xff0c;并且复制的位置可以用户自己定义&#xff0c;先看一下它的函数介绍&#xff1a; public static void SeamlessClone(IInputArray src, // 输入…

【STM32】| 01——常用外设 | USART

系列文章目录 【STM32】| 01——常用外设 | USART 失败了也挺可爱&#xff0c;成功了就超帅。 文章目录 前言1. 基础理论1.1 并行通信和串行通信1.2 同步通信和异步通信1.3 单工/半双工/全双工1.4 电平信号(RS232/TTL)和差分信号(RS485)1.5 端口(COM) 2. 串口理论2.1 串口物理…

Android - CrashHandler 全局异常捕获器

官网介绍如下&#xff1a;Thread.UncaughtExceptionHandler (Java Platform SE 8 ) 用于线程因未捕获异常而突然终止时调用的处理程序接口。当线程由于未捕获异常而即将终止时&#xff0c;Java虚拟机将使用thread . getuncaughtexceptionhandler()查询该线程的UncaughtExceptio…

cisp难不难?cisp如何备考通过率高?

*CISP 全称为Certified Information Security Professional&#xff0c;是国际上广受欢迎的信息安全专业认证之一。 对于许多信息安全领域的从业者来说&#xff0c;CISP认证是他们职业生涯中的重要一步。那么&#xff0c;CISP难不难呢?如何备考通过率更高呢?接下来&#xf…

electron自定义窗口和右键菜单样式

前言 electron默认沿用系统UI&#xff0c;并没有提供很多接口供使用者定制样式&#xff0c;如果想要完全自定义的样式&#xff0c;目前我能想到的方案只能是通过前端自定义样式&#xff0c;然后通过进程通信来实现系统基础功能&#xff1a;最大/小化、关闭、拖动窗口等。 效果…

关于java的冒泡排序

关于java的冒泡排序 我们前面的文章中了解到了数组的方法类Arrays&#xff0c;我们本篇文章来了解一下最出名的排序算法之一&#xff0c;冒泡排序&#xff01;&#x1f600; 冒泡排序的代码还是非常简单的&#xff0c;两层循环&#xff0c;外层冒泡轮数&#xff0c;里层依次比…

伺服电机:编码器原理与分类

什么是编码器&#xff1f; 编码器是将旋转位置的改变转换为电气信号。 编码器是伺服系统闭环控制不可缺少的部件&#xff0c;编码器应用在轴的闭环控制和大多数的自动化控制中。编码器为闭环控制提供位置或速度的实际测量值。 一、编码器的分类 从编码器的原理和产生的信号类…

Cypress.io:快速简单可靠的浏览器测试工具 | 开源日报 No.142

cypress-io/cypress Stars: 45.5k License: MIT Cypress.io 是一个快速、简单和可靠的浏览器测试工具&#xff0c;可以用于任何在浏览器中运行的内容。它支持 Mac、Linux 和 Windows 系统&#xff0c;并提供了安装指南。 hrvach/deskhop Stars: 4.1k License: GPL-3.0 DeskH…

ansible基础概念

一、【写在前面】 前面断更了几天&#xff0c;笔者被流感给干倒了&#xff0c;去拍了个核磁&#xff0c;给我脑子干成脱髓鞘了&#xff0c;也不知道是之前新冠导致的还是如何&#xff0c;哎要变成愚蠢的低级动物了……稍微恢复一点体力&#xff0c;今天赶快来博客水一水文章。…

代码随想录-刷题第五十二天

300. 最长递增子序列 题目链接&#xff1a;300. 最长递增子序列 思路&#xff1a;动态规划五步曲&#xff1a; dp[i]表示从0到i&#xff0c;以nums[i]结尾的最长递增子序列的长度。 递推公式&#xff1a;if(nums[i]>nums[j]) dp[i] max(dp[i], dp[j] 1) 位置i的最长升序…

MFC 多文档视图架构

目录 多文档视图架构 模仿多文档视图架构 执行流程 多文档视图架构 一个多文档视图架构运行后会是下面的样子&#xff1a; 内部的子框架窗口就相当于一个单文档视图架构&#xff0c;多文档视图架构就相当于在外面套一层框架窗口。 特点&#xff1a;可以管理多个文档(可以有…

Armv8-R AArch32 architecture概念学习

提示 该博客主要为个人学习&#xff0c;通过阅读官网手册整理而来&#xff08;个人觉得阅读官网的英文文档非常有助于理解各个IP特性&#xff09;。若有不对之处请参考参考文档&#xff0c;以官网文档为准。阅读该文章&#xff0c;可以先查看AArch64 Exception Model学习&…
最新文章