表单控制

# 单选,多选的  v-model的绑定

# 1 checkbox的单选---》v-model绑定一个布尔值---》只要选中布尔就为true,反之亦然
# 2 radio的单选----》v-model绑定字符串----》选中字符串就是value对应的值
# 3 checkbox的多选---》v-model绑定一个数组---》多个选中,数组就有多个值
<!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>表单控制之checkbox单选</h1>

        <p>用户名:<input type="text" v-model="username"></p>
        <p>密码:<input type="password" v-model="password"></p>
        <p><input type="checkbox" v-model="isCheck">记住密码</p>
        <p>
            <input type="radio" v-model="gender" value="1">男
            <input type="radio" v-model="gender" value="2">女
            <input type="radio" v-model="gender" value="0">未知
        </p>
        <p>爱好(多选):</p>
        <p>
            <input type="checkbox" v-model="hobby" value="篮球"> 篮球
            <input type="checkbox" v-model="hobby" value="足球"> 足球
            <input type="checkbox" v-model="hobby" value="橄榄球"> 橄榄球
            <input type="checkbox" v-model="hobby" value="乒乓球"> 乒乓球
        </p>
<!--        <hr>-->
<!--        密码是否选中:{{isCheck}}-->
<!--        <hr>-->
<!--        性别是:{{gender}}-->
<!--        <hr>-->
<!--        爱好是:{{hobby}}-->

        <hr>
        <input type="submit" value="提交" @click="handleSubmit">



</div>

</body>
<script>
    var vm = new Vue({
        el: '.app',
        data: {
            username: '',
            password: '',
            isCheck: false,
            gender: '',
            hobby:[],
        },
        methods: {
            handleSubmit(){
                //假设发送ajax到后端了
                console.log(this.username)
                console.log(this.password)
                console.log(this.isCheck)
                console.log(this.gender)
                console.log(this.hobby)
            }
        },


    })
</script>
</html>

v-model进阶

# v-model 进阶之 
lazy:双向数据绑定,只要修改输入框的值,就再更新数据,耗费资源,加了lazy后,等不输入了,变量再变化
number:输入框,只接收数字部分,如果输入了  123asdfasd,只保留123 数字部分
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>v-model进阶</h1>
  <p><input type="text" v-model.lazy="a">{{a}}</p>
  <p><input type="text" v-model.number="b">{{b}}</p>
  <p><input type="text" v-model.trim="c">{{c}}</p>


</div>

</body>
<script>
    var vm = new Vue({
        el: '.app',
        data: {
          a:'',
          b:'',
          c:'',

        },



    })
</script>
</html>

Vue生命周期

# 组件化开发
	vue的实例:vm
  以及后面学的组件:vc
  它们有生命周期:从创建开始,到销毁
  vue中总共生命周期有8个钩子函数(4对),依次调用
  
  
  # 钩子的意思:aop的体现
  beforeCreate	创建Vue实例,组件实例对象创建 之前调用
  created	创建Vue实例成功后调用(咱们用的对,可以在此处发送ajax请求后端数据)
  
  beforeMount	渲染DOM之前调用
  mounted	渲染DOM之后调用
  ---初始化完成了----
  
  beforeUpdate	重新渲染之前调用(数据更新等操作时,控制DOM重新渲染)
  updated	重新渲染完成之后调用
  ---一直在转圈----
  
  ----销毁组件---
  beforeDestroy	销毁之前调用
  destroyed	销毁之后调用
  
  
  
  
  ##### 提前讲个组件的概念### 自己写的有html,有样式,有js的好看的可以复用的东西
  -完整看到组件的生命周期
  -vm实例的生命周期看不完整

  
  
  ###### 重点:
  	-created多一些:在这里面发送ajax请求,data的数据好了后,再发请求,去后端拿数据
    -updated:数据变化,页面更新完后,执行它
    -destroyed:组件销毁,会触发它,也会用
    		-组件创建了,起了个定时器,不停地打印hello world(每隔一段时间执行一个函数,延迟调用)
      	-如果组件销毁了,定时器没有被销毁,会出现定时器还在执行的情况,
        -所以要在destroyed中把定时器取消掉,资源清理工作
    -vm实例和组件实例都有8个生命周期钩子函数
    -只要写了钩子函数,就会执行,不写就不会执行
 
  
  
  # 面向过程编程
  # OOP编程:面向对象编程
  # AOP编程:面向切面编程(对面向对象编程的补充),java的spring框架大量的使用
  		-python中装饰器  AOP编程的体现
   		-drf源码,反序列化的源码,钩子函数,aop体现
  

与后端交互(ajax,fetch和axios)

# 跨域问题: 前后端分离的项目会出现
	-浏览器有个安全策略:不允许向不同域(地址+端口号)发送请求获取数据,浏览器的 同源策略
  -解决跨域:
  	-后端的cors(跨域资源共享)技术:就是在响应头中加入允许即可
    -nginx做代理。。。
    
    
 # 原生js发送ajax请求,jq发送ajax请求,fetch发送ajax请求,axios发送ajax请求
	-原生:new XMLHttpRequest()   老api,坑很多
  -jq基于它封装,封装出了$.ajax ,屏蔽了很多问题
  -官方觉得XMLHttpRequest坑很多,搞了个fetch,跟XMLHttpRequest是平级的,比它好用,但是不支持ie
  -axios继续基于XMLHttpRequest封装了,一个发送ajax请求的模块

一:使用jq的ajax方法

# 原生js写ajax,jq帮咱们写好了,处理好了浏览器版本间的不兼容,可以直接用

$.ajax({
                    url: 'http://127.0.0.1:8000/test/',
                    type: 'get',
                    success: data => {
                        // 后端返回json格式字符串,$.ajax拿到字符串,转成了js的对象,给了data
                        this.name = data.name
                        this.age = data.age
                    }
                })

二:使用fetch

 fetch('http://127.0.0.1:8000/test/').then(res => res.json()).then(res => {
                console.log(res)
                this.name = res.name
                this.age = res.age
            })

三:使用第三方,axios(js模块

   <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
 
  
  axios.get('http://127.0.0.1:8000/test/').then(res=>{
            console.log(res.data) // 真正后端给的数据(res.data 才是真正的数据)
            this.name=res.data.name
            this.age=res.data.age
          })

计算属性

<!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>
    <!--    最简单方式-->
    <h2>最简单方法首字母变大写</h2>
    <!--    <input type="text" v-model="name">-&ndash;&gt;{{name.slice(0, 1).toUpperCase() + name.slice(1)}}-->
    <h2>使用函数实现,页面只要更新,这个函数就会重新执行,比较耗费资源</h2>
    <!--    <input type="text" v-model="name">-&ndash;&gt;{{getUpper()}}-->

    <input type="text" v-model="age">--->{{age}}

    <h3>通过计算属性实现:计算属性只有在它的相关依赖发生改变时才会重新求值</h3>
    <input type="text" v-model="name">--->{{upperName}}

</div>

</body>
<script>
    var vm = new Vue({
        el: '.app',
        data: {
            name: '',
            age: 0
        },
        methods: {
            getUpper() {
                console.log('我执行了')
                return this.name.slice(0, 1).toUpperCase() + this.name.slice(1)
            }
        },
        computed: {
            upperName() {
                console.log('我是计算属性,我执行了')
                return this.name.slice(0, 1).toUpperCase() + this.name.slice(1)
            }
        }


    })
</script>
</html>

监听属性

 watch: {
            categoryType: function (val) {
                console.log('name发生了变化')
                console.log(val)
                // 向后端发送请求,请求回相应分类的数据,展示
            }
        }
  
 # 只要categoryType发送变化,就会执行对应的函数

组件化开发基础

# 作用:扩展 HTML 元素,封装可重用的代码,目的是复用
	-例如:有一个轮播,可以在很多页面中使用,一个轮播有js,css,html
	-组件把js,css,html放到一起,有逻辑,有样式,有html
  
# 多组件页面和单组件页面
	-官方推荐,以后一个组件是一个 xx.vue 文件 ---》编译
  
# Single-Page application,缩写为 SPA:以后vue项目只有一个页面,看到的页面变化都是组件间的切换


# 全局组件和局部组件

全局组件

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




</div>

</body>
<script>
    // 定义一个全局组件,在任意组件中都可以使用
    var obj = {
        template: `
          <div>
          <button @click="handleBack">后退</button>
          我是一个组件-->{{name}}
          <button>前进</button>
          </div>
        `,
        data() {
            return {
                name:'lqz'
            }
        }, // 重点,data必须是个函数,返回一个对象,组件可以在多个地方重复使用,如果就是对象,导致多个组件共用同一个对象的数据,出现错乱
        methods: {
            handleBack(){
                alert('后退了')
            }
        },
        // 学的所有放在vm对象中的,都可以用
    }
    Vue.component('navbar', obj)


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


    })
</script>
</html>

局部组件-->只能在某个组件中使用

<!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>
    <navbar></navbar>
    <hr>
    <lqz></lqz>


</div>

</body>
<script>
    // 定义一个全局组件,在任意组件中都可以使用
    var obj = {
        template: `
          <div>

          <button @click="handleBack">后退</button>
          我是一个组件-->{{ name }}
          <button>前进</button>
          </div>
        `,
        data() {
            return {
                name: 'lqz'
            }
        }, // 重点,data必须是个函数,返回一个对象,组件可以在多个地方重复使用,如果就是对象,导致多个组件共用同一个对象的数据,出现错乱
        methods: {
            handleBack() {
                alert('后退了')
            }
        },
        // 学的所有放在vm对象中的,都可以用
        components: {} // 知道就可以了
    }
    Vue.component('navbar', obj)


    var vm = new Vue({
        el: '.app',
        data: {},
        components: {
            lqz: {
                template: `
                  <div>
                  <h3>我是局部组件</h3>
                  <button>点我看美女</button>
                  </div>`,
                data() {
                    return {}
                },
                methods: {}
            }
        }


    })
</script>
</html>

父子通信之父传子(自定义属性)

<!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>
    <h3>父组件中name:{{name}}</h3>
    <hr>
    <navbar :myname="name" :age="age"></navbar>
    <hr>

</div>

</body>
<script>
    // 定义一个全局组件,在任意组件中都可以使用

    Vue.component('navbar', {
        template: `
        <div>
        <button>前进</button>
        名字是:{{myname}}--->年龄是:{{age}}
        <button>后退</button>
        </div>`,
        props:['myname','age']
    })


    var vm = new Vue({
        el: '.app',
        data: {
            name:'彭于晏',
            age:99
        },


    })
</script>
</html>

ref属性

# 组件间通信---》通过ref属性,vue提供了一个ref属性,可以放在任意标签
	-放在普通标签,通过  this.$refs.ref对应的名字    就能拿到原生dom对象,使用原生操作该dom
  -放在自定义组件上,通过 this.$refs.ref对应的名字 就能拿到 组件对象,就可以调用对象的函数,使用对象的变量
  	-父组件中,拿到了子组件对象,对象中的属性,方法可以直接用,直接改
  
 	
  
# 通过ref,子传父
	-因为在父中,可以拿到子的对象,子对象中的所有变量,方法,都可以直接用
# 通过ref,实现父传子
	-因为在父中,可以拿到子的对象, 子对象.变量=父的变量
  

# vuex---》实现跨组件间通信
<!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>ref实现组件间通信</h1>
    {{name}}<br>
    <input type="text" v-model="name" ref="myinput">
    <button @click="handleClick">点我打印</button>
    <hr>
    <navbar ref="mynavbar"></navbar>
    <hr>
    <button @click="handleClick1">点我</button>


</div>

</body>
<script>
    Vue.component('navbar', {
        template: `
          <div>
          <input type="text" v-model="iname">---》{{ iname }}
          <br>
          </div>`,
        data() {
            return {
                iname: ''
            }
        },
        methods: {
            handleClick() {
                console.log('执行了')
                return 'xxx'
            }
        }
    })
    var vm = new Vue({
        el: '.app',
        data: {
            name: '',
        },
        methods: {
            handleClick() {
                console.log(this.$refs.myinput)
                console.log(this.$refs.myinput.value)
                this.$refs.myinput.value = 'lqz is big'
                alert(this.name)
            },
            handleClick1(){
                console.log(this.$refs.mynavbar) // 相当于拿到了再组件中的this(组件对象)
                console.log(this.$refs.mynavbar.iname)
                // this.name=this.$refs.mynavbar.iname
                // 父组件中直接执行子组件的方法
                // this.$refs.mynavbar.handleClick() // 调用子组件的方法
                this.$refs.mynavbar.iname='sssss'


            }
        }


    })

</script>
</html>