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> |
| <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.1, number: 2}, |
| {id: '2', name: '饼干', price: 4, number: 1}, |
| {id: '3', name: '辣条', price: 5, number: 5}, |
| ], |
| checkGroup: [] |
| }, |
| methods: { |
| getPrice() { |
| |
| 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>{{item.number}}</td> |
| <td><input type="checkbox" v-model="checkGroup" :value="item" @change="handelCheckOne"></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.1, number: 2}, |
| {id: '2', name: '饼干', price: 4, number: 1}, |
| {id: '3', name: '辣条', price: 5, number: 5}, |
| ], |
| checkGroup: [], |
| checkAll: false, |
| }, |
| methods: { |
| getPrice() { |
| |
| 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 = [] |
| } |
| }, |
| handelCheckOne() { |
| |
| if (this.checkGroup.length==this.goodList.length){ |
| this.checkAll=true |
| }else { |
| this.checkAll=false |
| } |
| } |
| } |
| |
| }) |
| </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="handelCheckOne"></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.1, number: 2}, |
| {id: '2', name: '饼干', price: 4, number: 1}, |
| {id: '3', name: '辣条', price: 5, number: 5}, |
| ], |
| checkGroup: [], |
| checkAll: false, |
| }, |
| methods: { |
| getPrice() { |
| |
| 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 = [] |
| } |
| }, |
| handelCheckOne() { |
| |
| 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> |
| |
| -不可变类型:数字,字符串,元组 |
| -可变类型:列表,字典,集合 |
| -python中没有值类型和引用类型的叫法---【因为python一切皆对象,对象都是地址都是引用】 |
| -可变类型当参数传到函数中,在函数中修改会影响原来的 |
| -不可变类型当参数传到函数中,在函数中修改不会影响原来的 |
| |
| |
| -这个问题不应该有【python中没有值类型和引用类型的叫法】 |
| |
| |
| -js的对象是引用类型 |
| -平时我们用的数组等数据类型,如果值会因为方法中的运行改变的就是值类型 |
- 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> |
当我们使用vue编写的前端给后端的drf项目发送请求,会出现报错,导致的结果就是请求的结果就是请求被浏览器给拦截了

拦截的原因:
从报错上看我们可以得知它是背一个叫CORS(跨域资源共享)的东西拦截了,因为没有'Access-Control-Allow-Origin'这个东西
这里我们不深入了解,我们只要知道在前后端分离的项目中,只要向不是地址栏中的[域:地址和端口]发送请求,拿的数据,浏览器就会拦截,需要加上'Access-Control-Allow-Origin'信息才能发送请求
处理跨域问题
后端代码中处理---》只需要在响应头中加入字段允许即可
这里的后端使用flask写的
点击查看代码
| from flask import Flask, jsonify, make_response |
| |
| app = Flask(__name__) |
| |
| |
| @app.route('/') |
| def index(): |
| print('执行了') |
| res = make_response(jsonify({'name': '彭于晏', 'age': 19, 'gender': 'male'})) |
| res.headers['Access-Control-Allow-Origin'] = '*' |
| return res |
| |
| |
| if __name__ == '__main__': |
| app.run() |
| |
ps:这里我们同时使用了vue和jquery两个前端js框架,以后并不建议这么用
点击查看代码
| <!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="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() { |
| |
| $.ajax({ |
| url: 'http://127.0.0.1:5000/', |
| type: 'get', |
| success: data => { |
| |
| this.name=data.name |
| this.age=data.age |
| this.gender=data.gender |
| } |
| |
| }) |
| |
| |
| } |
| } |
| |
| }) |
| </script> |
| </html> |
| |
| |
| |
| -新的发送ajax接口 |
| -用起来比较方便 |
| -支持promise写法[最新的异步写法] |
| -解决了原生的XMLHttpRequest兼容性的问题 |
| -不是所有浏览器都支持 |
| -主流现在使用axios[第三方]发送请求 |
| |
| |
| -比较老,不同浏览器需要做一些兼容性的处理,写起来比较麻烦 |
| -jq基于它做了封装 |
| |
| |
| fetch('http://examp;e.com/moves.json').then(function(response) { |
| return response.json(); |
| }).then(function(myJson) { |
| console.log(myJson) |
| }) |
| <!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>点击加载用户信息</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:5000/').then(response => response.json()).then(res => { |
| |
| console.log(res) |
| this.name = res.name |
| this.age = res.age |
| this.gender = res.gender |
| }) |
| |
| |
| } |
| } |
| |
| }) |
| </script> |
| </html> |
| Axios是一个基于promise的HTTP库,可以用在浏览器和node.js中 |
| axios官网:http://www.axios-js.com/ |
json文件:film.json(这里只是一部分,原代码太多)
ps:
- 以后都用axios,作用在vue上,第三方的模块
- Axios 是一个基于 promise 的 HTTP 库,还是基于XMLHttpRequest封装的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> |
| <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:5000/').then(res => { |
| |
| console.log(res) |
| this.name = res.data.data.name |
| this.age = res.data.data.age |
| this.gender = res.data.data.gender |
| |
| |
| }) |
| |
| |
| } |
| } |
| |
| }) |
| </script> |
| </html> |
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() { |
| |
| axios.get('http://127.0.0.1:8000/movies/').then(res => { |
| this.dataList = res.data.data.films |
| }) |
| |
| |
| } |
| } |
| |
| }) |
| </script> |
| </html> |
url.py
| from django.contrib import admin |
| from django.urls import path |
| from app01 import views |
| |
| urlpatterns = [ |
| path('admin/', admin.site.urls), |
| path('movies/', views.MovieView.as_view()), |
| ] |
view.py
| from django.shortcuts import render |
| from django import views |
| from django.http import JsonResponse |
| import json |
| |
| |
| |
| |
| |
| |
| class MovieView(views.View): |
| def get(self, request): |
| with open(r'D:\pythonproject\vue\day4\app01\film.json', 'r', encoding='utf-8') as f: |
| res_dict = json.load(f) |
| obj = JsonResponse(res_dict) |
| print(obj) |
| obj.headers['Access-Control-Allow-Origin'] = '*' |
| print(obj.headers) |
| return obj |

钩子函数名称 |
描述 |
beforeCreate |
创建Vue实例之前调用 |
created |
创建Vue实例成功后调用(可以在此处发送异步请求后端数据) |
beforeMount |
渲染DOM之前调用 |
mounted |
渲染DOM之后调用 |
beforeUpdate |
重新渲染之前调用(数据更新等操作是,控制DOM重新渲染) |
updated |
重新渲染完成之后调用 |
beforeDestroy |
销毁之前调用 |
destroyed |
销毁之后调用 |
| |
| -钩子:反序列化验证---》钩子函数 |
| -学名[专门名字]---》面向切面编程(AOP) |
| -OOP:面向对象编程 |
| |
| |
| -1 用的最多得到,create 发送ajax请求---》有的人放在mounted中加载 |
| -2 beforeDestroy |
| -组件一创建,created中启动一个定时器 |
| -组件被销毁,beforeDestroy销毁定时器 |
| |
| |
| -轮询:定时器+ajax http:http版本区别 |
| -长轮询:定时器+ajax http |
| -websocket协议:服务端主动推送消息 |
| https://zhuanlan.zhihu.com/p/371500343 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)