Vue基础

数据双向绑定

image

  • 表单单选控制checkbox选中
    image
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
        <div>
                用户名<input type="text" v-model="username">---->{{username}}
                <br>
                用户密码<input type="text" v-model="pwd">---->{{pwd}}
                <br>
                记住密码<input type="checkbox" v-model="radio">  <!--选择框让绑定一个变量变量的值是布尔值 成立则选择不成了则不选中-->
                <input type="text" v-model="name">----->{{name}}


        </div>
</div>
<script>
        var vm = new Vue({
                el:'#app',
                data:{username:'',
                        pwd:'',
                        radio:false,
                        name:'薛飞飞'

                }
        })

</script>
</body>
</html>
  • 单选
    • 单选通过value来控制radio的值控制显示
<!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>
</head>
<body>
<div id="box">
    <input type="radio" v-model="radio" value="男">男
    <input type="radio" v-model="radio" value="女">女
    <input type="radio" v-model="radio" value="保密">保密
    <br><br>您选择的性别:{{radio}}
</div>
</body>
<script>
    var vm = new Vue({
        el: '#box',
        data: {
            radio: '',
        },

    })
</script>
</html>

image

  • 多选
    image
    image
<!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>
</head>
<body>
<div id="box">

    <input type="checkbox" v-model="many" value="篮球">篮球
    <input type="checkbox" v-model="many" value="足球">足球
    <input type="checkbox" v-model="many" value="棒球">棒球
    <input type="checkbox" v-model="many" value="桌球">桌球
    <br><br>您喜欢的球类:{{many}}
</div>
</body>
<script>
    var vm = new Vue({
        el: '#box',
        data: {
            many: [],
        },
    })
</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">
</head>
<body>
<!--赶紧跑公司好坑-->
<div id="app">
    <div class="col-md-6 col-md-offset-3">
        <h1>购物车</h1>
        <table class="table table-striped">
            <thead>
            <tr>
                <th>商品名</th>
                <th>价格</th>
                <th>数量</th>
                <th>全选/全不选 <input type="checkbox" v-model="checkAll" @change="handleCheckAll"></th>
            </tr>
            </thead>
            <tbody>
            <tr v-for="item in dataList">
                <th scope="row">{{item.name}}</th>
                <td>{{item.price}}</td>
                <td><span @click="item.number++" class="btn">+</span>{{item.number}}<span class="btn"
                                                                                          @click="reduceNum(item)">-</span>
                </td>
                <td><input type="checkbox" v-model="checkGroup" :value="item" @change="handleOne"></td>
            </tr>
            </tbody>
        </table>
        价格:{{getPrice()}}
        <br>
        选中商品:{{checkGroup}}
        <br>

<!--        {{checkAll}}-->
    </div>
</div>


<script>
    new Vue({
        el: '#app',
        data: {
            dataList: [
                {name: '特斯拉', price: 3000000, number: 30},
                {name: '众横四海', price: 46000000, number: 2},
                {name: '苹果14pro', price: 8888, number: 14},
                {name: '水杯', price: 9.9, number: 33},

            ],
            checkGroup: [],
            checkAll: false
        },
        methods: {
            getPrice() {
                var total = 0
                for (i = 0; i < this.checkGroup.length; i++)
                    total += this.checkGroup[i].price * this.checkGroup[i].number
                return total
            },
            handleCheckAll() {
                if (this.checkAll) {
                    this.checkGroup = this.dataList
                } else {
                    this.checkGroup = []
                }
            }
            ,
            handleOne() {
                if (this.checkGroup.length === this.dataList.length) {
                    this.checkAll = true
                } else {
                    this.checkAll = false
                }
            }
            ,
            reduceNum(item) {
                if (item.number <= 1) {
                    alert('不能再减少了,亏本了')
                } else {
                    item.number--
                }
            }
        }


    })


</script>
</body>
</html>

image

v-model进阶(了解)

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

4 vue生命周期

官方原图
image
解析图
image

image

var vm=new Vue实例()

-1 实例创建,数据放到实例中
-2 挂在模板:el---》div
-3 改页面,改变量,都会相互影响 update
-4 销毁实例

4个过程,对应八个函数,依次执行(到某个过程就会执行某个函数)

beforeCreate	创建Vue实例之前调用,data,el都没有
created	        创建Vue实例成功后调用(可以在此处发送异步请求后端数据),data有了,el没有的
beforeMount	    渲染DOM之前调用 ,data有了,el没有
mounted	        渲染DOM之后调用
beforeUpdate	重新渲染之前调用(数据更新等操作时,控制DOM重新渲染)
updated	        重新渲染完成之后调用
beforeDestroy	销毁之前调用
destroyed	    销毁之后调用
  • mount
    挂载,把div挂载到组件中
    image
  • update
    修改组件内容
    image
  • mounted(用得最多)
    • 这时候可以向后端发送数据了

5 钩子函数(hook) AOP的体现:面向切面编程--》装饰器实现aop

6 vm实例:看不到它销毁 组件vc

7 组件:组件化开发

8 学习生命周期重点掌握的

-1 组件向后端发送请求,获取数据,应该放在 created 写,此时data已经有数据了
-2 destroyed做一些资源清理性的工作

9 小案例:组件创建,开启定时器,不停的打印hello,在destroyed中对定时器进行销毁

-补充:js 定时任务和延时任务   
# 延时任务
setTimeout(()=>{
   console.log('3s后执行我')
},3000)
#定时任务

setInterval(()=>{
console.log('hello')
},3000)

10 什么场景下用定时任务?

1 实时跟后端交互  基于http+定时任务 (websocket协议:服务端主动推送消息,手机app的消息推送)
2 秒杀场景:先提交秒杀请求,每隔3s,查询是否秒到

测试代码

<!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>
</head>
<body>
<div id="box">
    <child v-if="isShow"></child>
    <br>
    <button @click="terminate">删除子组件</button>
    <button @click="reborn">显示子组件</button>
</div>
</body>
<script>
    Vue.component('child', {
        template: `
            <div>
                {{name}}
                <button @click="name='Darker1'">更新数据1</button>
                <button @click="name='Darker2'">更新数据2</button>
            </div>`,
        data() {
            return {
                name: 'Darker1',
            }
        },
        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)
          //用的最多,向后端加载数据,创建定时器等
            console.log("页面已被vue实例渲染, data, methods已更新");
            console.log('mounted')
            this.t = setInterval(function () {
                console.log('daada')
            }, 3000)
          
        },
        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)
        },
        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)
          //组件销毁,清理定时器
            clearInterval(this.t)
            this.t = null
            console.log('destoryed')
        },


    })
    let vm = new Vue({
        el: '#box',
        data: {
            isShow: true
        },
        methods: {
            terminate() {
                this.isShow = false
            },
            reborn() {
                this.isShow = true
            }
        }
    })
</script>
</html>

5与后端交互

与后端交互
-js原生发送ajax请求:new HMLHTTPRequest(),浏览器兼容性不好,于是jquery基于它封装出
了jquery的ajax的方法,XMLHTTPRequest很多漏洞

1-jquery的ajax Vue中很少使用

 handelclick() {
                alert('正在向后端要数据')
                $.ajax({
                    url: 'http://127.0.0.1:8000/index/',
                    type: 'get',
                    data: '',
                    success: data => {  //data就是后端传入的数据是对象
                        this.username = data.name
                        this.age = data.age 

                    }
                })

            },

image

2-js原生提供了fetch,官方主推,ie浏览器不支持

 handelclick1() {
                alert('正在向后端要数据')
                fetch('http://127.0.0.1:8000/index/').then(res1=>res1.json()).then(res=>{
                  console.log(res)  // 将数据传给res1 然后转换之后再次传给第二个res返回的是真实的数据对象
                    console.log('res1类型是',typeof (res1))
                    console.log('res类型是',typeof (res))
                    console.log(res.name,res.age)
                    this.username1=res.name
                    this.age1=res.age
                })


            }

image

3-axios:vue中常用方法,他也是封装HMLHTTPRequest

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>  <!--第三方axios模块-->
handelclick2() {
                alert('正在向后端要数据')
                axios.get('http://127.0.0.1:8000/index/').then(res => {
                    console.log(res)
                    this.username2 = res.data.name;
                    this.age2 = res.data.age
                }) 
// 倒入第三方模块 直接使用get请求.get post 请求.post即可括号内写个地址

            },

image

朝后端请求数据代码演示

后端

class IndexView(APIView):
    def get(self, request):
        # res = {'name': 'lqz', 'age': 18}
        res = Response({'name': 'lqz', 'age': 18})
        # res = JsonResponse({'name': 'lqz', 'age': 18})
        res['Access-Control-Allow-Origin'] = '*'  # 后端跨域请求需要在请求头中携带此参数 否则无法发送请求可以配置文件配置
        return res

前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ajax</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>  <!--第三方axios模块-->
</head>
<body>

<div id="app">
    <div>
        <h1>jquery阿贾克斯后端获取数据</h1>
        <button @click="handelclick">点我朝后端要数据</button>
        <br>
        <p>username----->: <span v-text="username"></span></p>
        <p>age----->:<span v-text="age"></span></p>
    </div>
    <div>
        <h1>js原生fetch朝后端获取数据</h1>
        <button @click="handelclick1">点我朝后端要数据</button>
        <br>
        <p>username1----->: <span v-text="username1"></span></p>
        <p>age1----->:<span v-text="age1"></span></p>
    </div>
    <div>
        <h1>axios第三方朝后端获取数据</h1>
        <button @click="handelclick2">点我朝后端要数据</button>
        <br>
        <p>username2----->: <span v-text="username2"></span></p>
        <p>age2----->:<span v-text="age2"></span></p>
    </div>
</div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            username: '',
            age: '',
            username1: '',
            age1: '',
            username2: '',
            age2: ''

        }, methods: {
            handelclick() {
                alert('正在向后端要数据')
                $.ajax({
                    url: 'http://127.0.0.1:8000/index/',
                    type: 'get',
                    data: '',
                    success: data => {
                        console.log('data类型是', typeof (data))
                        this.username = data.name
                        this.age = data.age

                    }
                })

            },
            handelclick1() {
                alert('正在向后端要数据')
                fetch('http://127.0.0.1:8000/index/').then(res1 => res1.json()).then(res => {
                    console.log(res)  // 将数据传给res1 然后转换之后再次传给第二个res返回的是真实的数据对象
                    console.log('res1类型是', typeof (res1))
                    console.log('res类型是', typeof (res))
                    console.log(res.name, res.age)
                    this.username1 = res.name
                    this.age1 = res.age
                })


            },
            handelclick2() {
                alert('正在向后端要数据')
                axios.get('http://127.0.0.1:8000/index/').then(res => {
                    console.log(res)
                    this.username2 = res.data.name;
                    this.age2 = res.data.age
                }) // 倒入第三方模块 直接使用get请求.get post 请求.post即可括号内写个地址


            },
        }
    })
</script>
</html>

image
image

跨域请求可在配置文件中配置需要下载第三方库

# 1、安装第三方库 django-cors-headers
# 2、在settings.py中添加'corsheaders.middleware.CorsMiddleware',在SessionMiddleware和CommonMiddleware的中间
# 3、在INSTALLED_APPS里添加“corsheaders”
INSTALLED_APPS = [
    'search.apps.SearchConfig',
    'data.apps.DataConfig',
    'record_data.apps.RecordDataConfig',
    'deleted_data.apps.DeletedDataConfig',
    'mgmt.apps.MgmtConfig',
    'c_test.apps.CTestConfig',
    'rest_framework',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'corsheaders',  # 新增
]
# 4、在中间件中添加corsheaders.middleware.CorsMiddleware,django.middleware.common.CommonMiddleware
MIDDLEWARE = [
    # 'utils.middleware.ExceptionMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',  # 新增/必须在common中间件上面
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# 5、在settings.py底部增加
CORS_ALLOW_CREDENTIALS = True  # 允许携带cookie
CORS_ORIGIN_ALLOW_ALL = True  # 放行所有
CORS_ORIGIN_WHITELIST = ('*')  # 白名单
# CORS_ALLOW_METHODS:字符串列表,允许用哪些HTTP请求方法。
CORS_ALLOW_METHODS = (
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
    'VIEW',
)
# CORS_ALLOW_HEADERS:字符串列表,允许使用哪些非标准HTTP请求头。
CORS_ALLOW_HEADERS = (
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
)
posted @ 2022-10-26 21:01  懒羊羊A  阅读(39)  评论(0)    收藏  举报