首页 > 其他分享 >购物车案例&v-model进阶&与后端交互&vue生命周期&vue组件

购物车案例&v-model进阶&与后端交互&vue生命周期&vue组件

时间:2023-02-18 23:01:13浏览次数:44  
标签:el vue console 进阶 购物车 item 组件 data name

目录

购物车案例&v-model进阶&与后端交互&vue生命周期&vue组件

今日内容概要

  • 1 购物车案例

    • 1.1 基本购物车
    • 1.2 带全选全不选
    • 1.3 带加减
  • 2 v-model进阶

  • 3 与后端交互

    • 3.1 jq的ajax
    • 3.2 fetch发送ajax请求
    • 3.3 axios发送ajax请求
    • 3.4 小电影
  • 4 vue生命周期

  • 5 vue组件

    • 定义全局组件
    • 定义局部组件

今日内容详细

1 购物车案例

1.1 基本购物车

# js的变量只要发生变化 html页面中使用该变量的地方 就会重新渲染
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
          integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">

</head>
<body>
<div class="app">
<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <h1>购物车案例</h1>

            <table class="table table-bordered">
                <thead>
                <tr>
                    <th>商品编号</th>
                    <th>商品名字</th>
                    <th>商品价格</th>
                    <th>商品数量</th>
                    <th>选择</th>
                </tr>
                </thead>
                <tbody>
                <tr v-for="item in goodList">
                    <th scope="row">{{item.id}}</th>
                    <td>{{item.name}}</td>
                    <td>{{item.price}}</td>
                    <td>{{item.number}}</td>
                    <td>
                        <input type="checkbox" v-model="checkGroup" :value="item">
                    </td>
                </tr>
                </tbody>
            </table>
            <p>选中商品:{{checkGroup}}</p>
            <p>总价格:{{getPrice()}}</p>
        </div>
    </div>
</div>
</div>

</body>
<script>
    var vm = new Vue({
        el: '.app',
        data: {
            goodList: [
                {id: '1', name: '钢笔', price: 20.1, number: 2},
                {id: '2', name: '饼干', price: 4, number: 1},
                {id: '3', name: '辣条', price: 5, number: 5},
            ],
            checkGroup: []
        },
        methods: {
            getPrice(){
                // 通过checkGroup里面的对象 计算出总价格
                var price = 0
                for (item of this.checkGroup){
                    price += item.price * item.number
                }
                return price
            }


        }
    })
</script>
</html>

1.2 带全选全不选

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
          integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">

</head>
<body>
<div class="app">
<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <h1>购物车案例</h1>

            <table class="table table-bordered">
                <thead>
                <tr>
                    <th>商品编号</th>
                    <th>商品名字</th>
                    <th>商品价格</th>
                    <th>商品数量</th>
                    <th>全选<input type="checkbox" v-model="checkAll" @change="handlerCheckAll"></th>
                </tr>
                </thead>
                <tbody>
                <tr v-for="item in goodList">
                    <th scope="row">{{item.id}}</th>
                    <td>{{item.name}}</td>
                    <td>{{item.price}}</td>
                    <td>{{item.number}}</td>
                    <td>
                        <input type="checkbox" v-model="checkGroup" :value="item" @change="handlerCheckOne">
                    </td>
                </tr>
                </tbody>
            </table>
            <p>选中商品:{{checkGroup}}</p>
            <p>总价格:{{getPrice()}}</p>
        </div>
    </div>
</div>
</div>

</body>
<script>
    var vm = new Vue({
        el: '.app',
        data: {
            goodList: [
                {id: '1', name: '钢笔', price: 20.1, number: 2},
                {id: '2', name: '饼干', price: 4, number: 1},
                {id: '3', name: '辣条', price: 5, number: 5},
            ],
            checkGroup: [],
            checkAll: false
        },
        methods: {
            getPrice(){
                // 通过checkGroup里面的对象 计算出总价格
                var price = 0
                for (item of this.checkGroup){
                    price += item.price * item.number
                }
                return price
            },
            handlerCheckAll(){
                if (this.checkAll){
                    this.checkGroup = this.goodList
                }else {
                    this.checkGroup = []
                }
            },
            handlerCheckOne(){
                if (this.checkGroup.length==this.goodList.length){
                    this.checkAll = true
                }else {
                    this.checkAll = false
                }
            }


        }
    })
</script>
</html>

1.3 带加减

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
          integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">

</head>
<body>
<div class="app">
<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <h1>购物车案例</h1>

            <table class="table table-bordered">
                <thead>
                <tr>
                    <th>商品编号</th>
                    <th>商品名字</th>
                    <th>商品价格</th>
                    <th>商品数量</th>
                    <th>全选<input type="checkbox" v-model="checkAll" @change="handlerCheckAll"></th>
                </tr>
                </thead>
                <tbody>
                <tr v-for="item in goodList">
                    <th scope="row">{{item.id}}</th>
                    <td>{{item.name}}</td>
                    <td>{{item.price}}</td>
                    <td>
                        <button @click="handlerDown(item)">-</button>
                        {{item.number}}
                        <button @click="item.number++">+</button>
                    </td>
                    <td>
                        <input type="checkbox" v-model="checkGroup" :value="item" @change="handlerCheckOne">
                    </td>
                </tr>
                </tbody>
            </table>
            <p>选中商品:{{checkGroup}}</p>
            <p>总价格:{{getPrice()}}</p>
        </div>
    </div>
</div>
</div>

</body>
<script>
    var vm = new Vue({
        el: '.app',
        data: {
            goodList: [
                {id: '1', name: '钢笔', price: 20.1, number: 2},
                {id: '2', name: '饼干', price: 4, number: 1},
                {id: '3', name: '辣条', price: 5, number: 5},
            ],
            checkGroup: [],
            checkAll: false
        },
        methods: {
            getPrice(){
                // 通过checkGroup里面的对象 计算出总价格
                var price = 0
                for (item of this.checkGroup){
                    price += item.price * item.number
                }
                return price
            },
            handlerCheckAll(){
                if (this.checkAll){
                    this.checkGroup = this.goodList
                }else {
                    this.checkGroup = []
                }
            },
            handlerCheckOne(){
                if (this.checkGroup.length==this.goodList.length){
                    this.checkAll = true
                }else {
                    this.checkAll = false
                }
            },
            handlerDown(item){
                if (item.number > 1){
                    item.number--
                }else {
                    alert('小于零,有钱没地方花?')
                }
            }


        }
    })
</script>
</html>
# python
	-不可变类型:数值 字符串 元组
    -可变类型:列表 字典 集合
    -python中没有值类型和引用类型的叫法---> 【因为python一切皆对象 duix都是地址都是引用】
    -可变类型当参数传到函数中 在函数中修改会影响原来的
    -不可变类型当参数传到函数中 在函数中修改不会影响原来的
    
# python 函数参数传递是值传递还是引用传递? 这个问题不应该有

# js 传入了item对象 在函数中修改 影响了原来的
	-js的对象是引用类型

2 v-model进阶

lazy:等待input框的数据绑定失去焦点之后再变化
number:数字开头 只保留数字 后面的字母不保留:字母开头都保留
trim:去除首位的空格
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>

<div class="app">
    <h1>lazy</h1>
    <input type="text" v-model.lazy="myText">----->{{myText}}

    <h1>number</h1>
    <input type="text" v-model.number="myNumber">----->{{myNumber}}

    <h1>trim</h1>
    <input type="text" v-model.trim="myTrim">----->{{myTrim}}

</div>

</body>

<script>
    var vm = new Vue({
        el: '.app',
        data: {
            myText: '',
            myNumber: '',
            myTrim: ''
        }

    })




</script>
</html>

3 与后端交互

# 跨域问题
	浏览器的原因 只要向不是地址栏中的【域:地址和端口】发送请求 拿的数据 浏览器就给拦截了
    
# 处理跨域问题
	后端代码处理---> 只需要在响应头中加入允许即可

3.1 jq的ajax

# flask轻量级,公司喜欢用,先写着,以后学
from flask import Flask, jsonify, make_response

app = Flask(__name__)


@app.route('/')
def index():
    # return jsonify({'name': 'zpf', 'age': 19, 'gender': 'male'})
    res = make_response(jsonify({'name': '郑鹏飞', 'age': 19, 'gender': '男'}))
    res.headers['Access-Control-Allow-Origin'] = '*'  # 把这个key和value加入到响应头 就没有跨域问题了
    return res


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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>

</head>
<body>

<div class="app">
    <h1>点击加载用户信息</h1>
    <button @click="handlerClick">点我</button>
    <div v-if="age!=0">
        <p>用户名:{{name}}</p>
        <p>用户年龄:{{age}}</p>
        <p>用户性别:{{gender}}</p>
    </div>
    <div v-else>
        无用户信息
    </div>
</div>

</body>
<script>
    var vm = new Vue({
        el: '.app',
        data: {
            name: '',
            age:0,
            gender: ''
        },
        methods: {
            handlerClick(){
                // 1 学过的 jq的ajax
                $.ajax({
                    url: 'http://127.0.0.1:5000',
                    type: 'get',
                    success:data=>{
                        // console.log(data)
                        this.name=data.name
                        this.age=data.age
                        this.gender=data.gender
                    }
                })
            }
        }
    })
</script>
</html>

3.2 fetch发送ajax请求

# fetch提供了一个JavaScript接口 用于访问和操作HTTP管道的一些具体部分 例如请求和响应
	-新的发送ajax接口
    -用起来比较方便
    -支持promise写法【最新的异步写法】
    -解决了原生的XMLHttpRequest兼容性问题
    -不是所有浏览器都支持
    -主流现在是用axios【第三方】发送请求
    
# XMLHttpRequest:原生js提供的
	-比较老 不同浏览器需要做一些兼容性的处理 写起来比较麻烦
    -jq基于它做了封装
    
# 发送ajax请求
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>

</head>
<body>

<div class="app">
    <h1>点击加载用户信息</h1>
    <button @click="handlerClick">点我</button>
    <div v-if="age!=0">
        <p>用户名:{{name}}</p>
        <p>用户年龄:{{age}}</p>
        <p>用户性别:{{gender}}</p>
    </div>
    <div v-else>
        无用户信息
    </div>
</div>

</body>
<script>
    var vm = new Vue({
        el: '.app',
        data: {
            name: '',
            age:0,
            gender: ''
        },
        methods: {
            handlerClick(){
                // fetch 发送ajax请求
                fetch('http://127.0.0.1:5000').then(response => response.json()).then(res =>{
                    // 对象
                    this.name = res.name
                    this.age = res.age
                    this.gender = res.gender
                })
            }
        }
    })
</script>
</html>

3.3 axios发送ajax请求

# 以后用它 在vue上 第三方的模块
# axios 是一个基于promise的HTTP库 还是基于XMLHttpRequest封装的
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
    <script src="js/axios.js"></script>

</head>
<body>

<div class="app">
    <h1>点击加载用户信息</h1>
    <button @click="handlerClick">点我</button>
    <div v-if="age!=0">
        <p>用户名:{{name}}</p>
        <p>用户年龄:{{age}}</p>
        <p>用户性别:{{gender}}</p>
    </div>
    <div v-else>
        无用户信息
    </div>
</div>

</body>
<script>
    var vm = new Vue({
        el: '.app',
        data: {
            name: '',
            age:0,
            gender: ''
        },
        methods: {
            handlerClick(){
                // axios
                axios.get('http://127.0.0.1:5000/').then(res => {
                    // res是对象 有点特殊 真正的数据(想要body体内容) 在res.data中
                    this.name = res.data.data.name
                    this.age = res.data.data.age
                    this.gender = res.data.data.gender
                })
            }
        }
    })
</script>
</html>

3.4 小电影

# 首先需要去'偷'一些电影数据

# 然后后端处理数据
'''
import json

from flask import Flask, jsonify, make_response

app = Flask(__name__)


@app.route('/film')
def film():
    with open('./film.json', 'r', encoding='utf8') as f:
        res_dict = json.load(f)
        res = make_response(jsonify(res_dict))
        res.headers['Access-Control-Allow-Origin'] = '*'
        return res
    

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

# 最后前端用axios接收
'''
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
    <script src="./js/axios.js"></script>
</head>
<body>
<dvi class="app">
    <h1>热映电影</h1>
    <button @click="handleClick">点我</button>
    <ul>
        <li v-for="item in dataList">
            <h2>名字:{{item.name}}</h2>
            <h3>导演:{{item.director}}</h3>
            <h2>名字:{{item.category}}</h2>
            <p>简介:{{item.synopsis}}</p>
            <img :src="item.poster" alt="" height="200px" width="200px">
        </li>
    </ul>
</dvi>

</body>
<script>
    var vm = new Vue({
        el: '.app',
        data: {
            dataList: []
        },
        methods: {
            handleClick(){
                // axios
                axios.get('http://127.0.0.1:5000/film').then(res => {
                    this.dataList = res.data.data.films
                })
            }
        }
    })
</script>
</html>
'''
# 在created插入

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
    <script src="./js/axios.js"></script>
</head>
<body>
<dvi class="app">
    <h1>热映电影</h1>
    <ul>
        <li v-for="item in dataList">
            <h2>名字:{{item.name}}</h2>
            <h3>导演:{{item.director}}</h3>
            <h2>名字:{{item.category}}</h2>
            <p>简介:{{item.synopsis}}</p>
            <img :src="item.poster" alt="" height="200px" width="200px">
        </li>
    </ul>
</dvi>

</body>
<script>
    var vm = new Vue({
        el: '.app',
        data: {
            dataList: []
        },
        methods: {
            handleClick(){
                // axios
                axios.get('http://127.0.0.1:5000/film').then(res => {
                    this.dataList = res.data.data.films
                })
            }
        },
        created(){
            axios.get('http://127.0.0.1:5000/film').then(res => {
                this.dataList = res.data.data.films
            })
        }
    })
</script>
</html>

4 vue生命周期

# 从vue实例创建开始 到实例被销毁 总共经历了8个生命周期钩子【只要写了就会执行】函数
	-钩子:反序列化验证---> 钩子函数
    -学名【专门名字】---> 面向切面编程
    -OOP:面向对象编程
    
# 8个生命周期钩子函数
	beforeCreate		创建Vue实例之前调用
    create				创建Vue实例成功之后调用(可以在此处发送异步请求后端数据)
    beforeMount			渲染DOM之前调用
    mounted				渲染DOM之后调用
    beforeUpdate		重新渲染之前调用(数据更新等操作时 控制DOM重新渲染)
    updated				重新渲染完成之后调用
    beforeDestroy		销毁之前调用
    destroyed			销毁之后调用
    
    
# 重点:
	-1 用的最多的 created 发送ajax请求---> 有的人放在mounted中加载
    -2 beforeDestroy
    	-组件一创建 created中启动一个定时器
        -组件被销毁 beforeDestroy销毁定时器
        
        
# 实现实时聊天效果(在线聊天室)
	-轮询:定时器+ajax  http:http版本区别
    -长轮询:定时器+ajax  http
    -websocket协议:服务端主动推送消息
    https://zhuanlan.zhihu.com/p/371500343
# 显示生命周期钩子演示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
    <script src="./js/axios.js"></script>


</head>
<body>
<div class="app">
    <h1>热映电影</h1>
    {{name}}

</div>
</body>
<script>
    var vm = new Vue({
        el: '.app',
        data: {
            name: 'sss'
        },
        methods: {},


        beforeCreate() {
            console.group('当前状态:beforeCreate')
            console.log('当前el状态:', this.$el)
            console.log('当前data状态:', this.$data)
            console.log('当前name状态:', this.name)
        },
        created() {
            console.group('当前状态:created')
            console.log('当前el状态:', this.$el)
            console.log('当前data状态:', this.$data)
            console.log('当前name状态:', this.name)
        },
        beforeMount() {
            console.group('当前状态:beforeMount')
            console.log('当前el状态:', this.$el)
            console.log('当前data状态:', this.$data)
            console.log('当前name状态:', this.name)
        },
        mounted() {
            console.group('当前状态:mounted')
            console.log('当前el状态:', this.$el)
            console.log('当前data状态:', this.$data)
            console.log('当前name状态:', this.name)
        },
        beforeUpdate() {
            console.group('当前状态:beforeUpdate')
            console.log('当前el状态:', this.$el)
            console.log('当前data状态:', this.$data)
            console.log('当前name状态:', this.name)
        },
        updated() {
            console.group('当前状态:updated')
            console.log('当前el状态:', this.$el)
            console.log('当前data状态:', this.$data)
            console.log('当前name状态:', this.name)
        },

        // 如果写在Vue实例上,后面这俩是看不到的----》使用组件演示8个生命周期
        beforeDestroy() {
            console.group('当前状态:beforeDestroy')
            console.log('当前el状态:', this.$el)
            console.log('当前data状态:', this.$data)
            console.log('当前name状态:', this.name)
        },
        destroyed() {
            console.group('当前状态:destroyed')
            console.log('当前el状态:', this.$el)
            console.log('当前data状态:', this.$data)
            console.log('当前name状态:', this.name)
        },

    })
</script>
</html>

5 vue组件

# 组件化开发的好处:重用代码
# 组件分类
	-全局组件:在任意组件中都可以使用
    -局部组件:只能在当前组件中使用

定义全局组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
    <script src="js/axios.js"></script>

</head>
<body>
<div class="app">
    <h1>组件</h1>

    <child></child>

</div>

</body>
<script>
    // 全局组件---> 在任意组件中都可以使用
    // 跟之前学的没有区别
    // 然后全局组件
    Vue.component('child', {
        template: `
          <div>
          <botton>后退</botton>
          <span style="font-size: 40px">首页--{{ name }}</span>
          <button @click="handleFor">前进</button>
          </div>`,// 里面写html内容 必须包在一个标签中
        data() {  // data必须是方法 返回对象
            return {
                name: '彭于晏',
                t: null
            }
        },
        methods: {
            handleFor() {
                this.name = 'zpf'
            }
        }
    })
	// 先要有根组件
    var vm = new Vue({
        el: '.app',
        data: {}
    })


</script>
</html>

定义局部组件

<script>
    // 全局组件---> 在任意组件中都可以使用
    // 跟之前学的没有区别
    Vue.component('child', {
        template: `
          <div>
          <botton>后退</botton>
          <span style="font-size: 40px">首页--{{ name }}</span>
          <button @click="handleFor">前进</button>
          <zpf></zpf>
          </div>`,// 里面写html内容 必须包在一个标签中
        data() {  // data必须是方法 返回对象
            return {
                name: '彭于晏',
                t: null
            }
        },
        methods: {
            handleFor() {
                this.name = 'zpf'
            }
        },
        components: {
            'zpf': {
                template: `
                    <div>
                        <h2>局部组件--->{{age}}</h2>
                    </div>
                `,
                data() {
                    return{
                        age: 19
                    }
                }
            }
        },

    })

    var vm = new Vue({
        el: '.app',
        data: {}
    })


</script>

// 可以写在全局组件内
<script>
    // 全局组件-----》在任意组件中都可以使用
    // 跟之前学的没有区别
    Vue.component('child', {
        template: `
          <div>
          <button>后退</button>
          <span style="font-size: 40px">首页--{{ name }}</span>
          <button @click="handleFor">前进</button>
          <lqz1></lqz1>
          </div>`,// 里面写html内容,必须包在一个标签中
        data() {              // data必须是方法,返回对象
            return {
                name: '彭于晏',
                t: null
            }
        },
        methods: {
            handleFor() {
                this.name = 'lqz'
            }
        },
        // 写在全局组件内
        components: {
            'lqz1': {
                template: `
                  <div>
                  <h1>局部组件---{{ age }}</h1>
                  </div>`,
                data() {
                    return {
                        age: 19
                    }
                }
            },

        }


    })
    Vue.component('child3', {
        template: `
          <div>
          <button>后退</button>
          </div>`,


    })

  // 写在根组件内
  var foo={
                template: `
                  <div>
                  <h1>局部组件---{{ age }}</h1>
                  </div>`,
                data() {
                    return {
                        age: 19
                    }
                }
            }
    var vm = new Vue({
        el: '.app',
        data: {
            show: false
        },
        methods: {
            handleShow() {
                this.show = !this.show
            }
        },
        components: {
            foo

        }


    })
</script>

// 也可以写在根组件内

补充

# 1 之前前后端交互 使用xml格式
# 2 后来json格式出现 前后端交互 主流都是json格式
	-可能觉得不安全
    -前后端加密解密方式
    
# 3 目前有些比json更安全 高效 节约空间的编码格式 后期可能前后端交互使用

标签:el,vue,console,进阶,购物车,item,组件,data,name
From: https://www.cnblogs.com/zpf1107/p/17133895.html

相关文章