python71 前端框架之vue 购物车案例、v-model进阶、与后端交互ajax、vue生命周期、vue组件、可变不可变类型区别、跨域问题

基本购物车

基本购物车

<!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>
                <hr>
                <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,number:2},
                {id:'2',name:'饼干',price:8,number:10},
                {id:'3',name:'王子辣条',price:7,number:20},
                {id:'4',name:'巧克力',price:25,number:40},
            ],
            checkGroup:[]

        },
        methods: {
            getPrice(){
                // 通过checkGroup里面的对象计算出总价格
                var total = 0
                for (item of this.checkGroup){
                    total += item.price*item.number
                }
                return total
            }
        },

    })


</script>
</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>
                <hr>
                <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,number:2},
                {id:'2',name:'饼干',price:8,number:10},
                {id:'3',name:'王子辣条',price:7,number:20},
                {id:'4',name:'巧克力',price:25,number:40},
            ],
            checkGroup:[]

        },
        methods: {
            getPrice(){
                // 通过checkGroup里面的对象计算出总价格
                var total = 0
                for (item of this.checkGroup){
                    total += item.price*item.number
                }
                return total
            }
        },

    })


</script>
</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>全选/全不选 <input type="checkbox" v-model="checkAll" @change="handleCheckAll"></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="handleDown(item)">-</button>{{item.number}} <button @click="item.number++">+</button></td>
                                <td><input type="checkbox" v-model="checkGroup" :value="item" @change="handleCheckOne"></td>
                            </tr>
                        </tbody>
                    </table>
                <hr>
                <p>选中商品:{{checkGroup}}------{{checkAll}}</p>
                <p>总价格:{{getPrice()}}</p>

            </div>

        </div>

    </div>




</div>
</body>
<script>

    var vm = new Vue({
        el: '.app',
        data: {
            goodList:[
                {id:'1',name:'钢笔',price:20,number:2},
                {id:'2',name:'饼干',price:8,number:10},
                {id:'3',name:'王子辣条',price:7,number:20},
                {id:'4',name:'巧克力',price:25,number:40},
            ],
            checkGroup:[],
            checkAll:false,

        },
        methods: {
            getPrice(){
                // 通过checkGroup里面的对象计算出总价格
                var total = 0
                for (item of this.checkGroup){
                    total += item.price*item.number
                }
                return total
            },
            handleCheckAll(){
                if (this.checkAll){
                    this.checkGroup = this.goodList
                }else{
                    this.checkGroup = []
                }
            },
            handleCheckOne(){
                // console.log('一个被点了')
                if (this.checkGroup.length==this.goodList.length){
                    this.checkAll=true
                }else{
                    this.checkAll=false
                }
            },
            handleDown(item){
                if(item.number>1){
                    item.number--
                }else{
                    alert('还减呢????你小子行!!!!')
                }
            }
        },

    })


</script>
</html>

v-model进阶

lazy: 等待input框的数据绑点失去焦点之后再变化
number:数字开头,只保留数字,后面的字母不保留:字母开头,都保留
trim:去除首位的空格

image

<!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>

与后端交互

jq的ajax 用原生django写后端代码


from django.http import JsonResponse

def index(request):
    print('执行了')

    list = {'name': '彭预言', 'age': 19, 'gender': 'male'}

    # return JsonResponse(list,safe=False)

    obj = JsonResponse(list,json_dumps_params={'ensure_ascii':False}) # 配置前端文字解码
    obj['Access-Control-Allow-Origin'] = '*' # 请求头加数据  解决跨域问题
    return obj

    # res.headers['Access-Control-Allow-Origin'] = '*'

路由代码
from app01 import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/', views.index),
]
'''
不想那么麻烦就用fbv写了  cbv也是一样,Response返回数据时注意配置解码的参数
'''

前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
</head>
<body>
<div class="app">
    <h1>点击加载用户信息</h1>
    <button @click="handleClick">点击点击点击点击点击</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: {
            handleClick() {
                // 学过的jq的ajax
                $.ajax({
                    url: 'http://127.0.0.1:8000/books/',
                    type: 'get',
                     contentType:false,
                    processData: false,
                    success: data => {
                        this.name=data.name
                        this.age=data.age
                        this.gender=data.gender

                    }
                })
            }


        },


    })


</script>
</html>

fetch发送ajax请求

fetch 提供了一个JavaScript接口,用于访问和操纵HTTP管道的一些具体部分,例如请求和响应
    新的发送ajax 接口
    用起来比较方便
    支持promise写法【最新的异步写法】
    解决了原生的XMLHttpRequest兼容性的问题
    不是所有浏览器都支持
    主流现在是用axios【第三方】发送请求
  XMLHttpRequest: 原生js提供的
    比较老,不同的浏览器需要做一些兼容性的处理,写起来比较麻烦
    jq基于它做了封装
    
    
    发送ajax请求

fetch是JavaScript内置的一个工具 所以直接写就行了

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
{#    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>#}
</head>
<body>
<div class="app">
    <h1>点击加载用户信息</h1>
    <button @click="handleClick">点击点击点击点击点击</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:{
            handleClick(){
                fetch('http://127.0.0.1:8000/books/').then(response=>response.json().then(res=>{
                    //对象
                    console.log(res)
                    this.name = res.name
                    this.age = res.age
                    this.gender = res.gender

                }))
            }
        }




    })


</script>
</html>

axios发送ajax请求

以后都用它,在vue上,第三方的模块
Axios 是一个基于promise的HTTP库,还是基于XMLHttpRequest封装的

<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.min.js"></script>
   <script src="js/axios.js"></script>  //  这里引入的是下载的 可以用网络的 还有就是下面发送ajax的地址


</head>
<body>
<div class="app">
    <h1>点击加载用户信息</h1>
    <button @click="handleClick">点击点击点击点击点击</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:{
            handleClick(){
                axios.get('http://127.0.0.1:8000/books/').then(res=>{

                    this.name = res.data.name
                    this.age = res.data.age
                    this.gender = res.data.gender

                })
            }
        }




    })


</script>
</html>

小电影案例

<!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="handleClick">点我</button>
    <ul>
        <li v-for="item in dataList">
            <h2>名字:{{item.name}}</h2>
            <h3>导演:{{item.director}}</h3>
            <h3>类型:{{item.category}}</h3>
            <p>简介:{{item.synopsis}}</p>
            <img :src="item.poster" alt="" height="300px" width="200px">

        </li>
    </ul>

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


            }
        }

    })
</script>
</html>
from flask import Flask, jsonify, make_response
import json

app = Flask(__name__)


@app.route('/')
def index():
    print('执行了')
    # res = make_response(jsonify({'name': '彭于晏', 'age': 19, 'gender': 'male'}))
    res = make_response(jsonify({'code': 100, 'msg': '成功', 'data': {'name': '彭于晏', 'age': 19, 'gender': 'male'}}))
    res.headers['Access-Control-Allow-Origin'] = '*'  # 把这个key和value加入到响应头,就没有跨域问题了
    return res


@app.route('/film')
def film():
    with open('./film.json', 'r', encoding='utf-8') as f:
        res_dict = json.load(f)
        res = make_response(jsonify(res_dict))
        res.headers['Access-Control-Allow-Origin'] = '*'  # 把这个key和value加入到响应头,就没有跨域问题了
        return res


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

vue生命周期

从vue实例创建开始 到实例被销毁 总共经历了8个生命周期钩子【只要写了就会执行】函数
    钩子:反序列化验证----》钩子函数
    学名【专门名字】----》面向切面编程(AOP)
    OOP:面向对象编程

8个生命周期钩子函数
   beforeCreate   创建Vue实例之前调用
   created        创建Vue实例成功后调用(可以在此处发送异步请求后端数据)
   bdforeMount    渲染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

http://photo.liuqingzheng.top/2023 02 15 18 52 56 /life1-1608077936951.jpg

组件

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

定义全局组件

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

    }


})

定义局部组件

var foo={
                template: `
                  <div>
                  <h1>局部组件---{{ age }}</h1>
                  </div>`,
                data() {
                    return {
                        age: 19
                    }
                }
            }



    var vm = new Vue({
          ...
        components: {
            foo

        }


    })

补充:

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


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

跨域问题
    浏览器的原因,只要向不是地址栏中的【域:地址和端口】发送请求,拿的数据,浏览器就给拦截了


处理跨域问题
   后端代码处理------》只需要在响应头中加入允许即可

1.装模块
  pip3.8 install django-cors-headers -i https://pypi.tuna.tsinghua.edu.cn/simple/

2.注册app
  'corsheaders'

3 中间件修改
'corsheaders.middleware.CorsMiddleware',
4 修改配置文件
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)

CORS_ALLOW_HEADERS = (
'XMLHttpRequest',
'X_FILENAME',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
'Pragma',
'token'
)


什么是跨域请求,以及如何解决这个问题,请参考下方博客链接:
   https://www.cnblogs.com/zaking/p/16532324.html
posted @ 2023-02-16 21:20  缀月  阅读(273)  评论(0编辑  收藏  举报