2、Vue事件以及生命周期

学习内容

1、表单v-model

1、1变量取名命名问题

  • 绑定输入框数据的时候,尽量和后端要求的数据保持一致
 <!-- 定义挂载点 -->
   <div id="app">
       <!-- <p>账 号:<input type="text" v-model="name"></p>
       <p>密 码:<input type="text" v-model="pass"></p> -->
       <p>账 号:<input type="text" v-model="user.username"></p>
       <p>密 码:<input type="text" v-model="user.password"></p>
       <button @click="toReg">注册</button>
   </div>
<script>
       //实例化vue
       new Vue({
           //挂载点
           el: "#app",
           //data:model(数据模型)--页面所需的数据
           data: {
               //随便定义,后期需要处理成后端对应的数据格式
               name: "",
               pass: "",
               //定义对象,key一定要和后端保持一致,方便后期使用
               user: {
                   username: "",
                   password: ""
               }
           },
           //methods:方法  需要使用的函数
           methods: {
               toReg() {
                   /* 
                       /register
                       参数:
                           username:
                           password
                   */
                   //    $.ajax({
                   //     url:"/register",
                   //     data:{
                   //         username:this.name,
                   //         password:this.pass
                   //     }
                   //    })
                   console.log(this.user);
               }
           }
       })
   </script>

1、2 v-model数据绑定

  • 单选框:对应radio,需要给input一个value,使用v-model去进行数据绑定
<div class="form-group row">
  <label class="col-lg-1">性别</label>
  <!-- 对于radio单选框,需要给input设置value属性,再使用v-model去绑定数据 -->
     <div class="col-lg-11">
        <label class="radio-inline"><input type="radio" name="sex" :value="0" v-model="reg.sex"></label>
        <label class="radio-inline"><input type="radio" name="sex" :value="1" v-model="reg.sex"></label>
     </div>
</div>
  • 多选框:对于checkbox来说,初始值是数组,最后的结果就是数组,如果初始值不是数组,结果就是boolean
<div class="form-group row">
   <label class="col-lg-1">爱好</label>
   <!-- 对于checkbox多选框,初始值是数组,最后的结果就是数组,如果是其他,结果就是一个boolean -->
      <div class="col-lg-11">
        <label class="checkbox-inline"><input type="checkbox" :value="1" v-model="reg.hobby">唱歌</label>
        <label class="checkbox-inline"><input type="checkbox" :value="2" v-model="reg.hobby">跳舞</label>
        <label class="checkbox-inline"><input type="checkbox" :value="3" v-model="reg.hobby">看书</label>
        <label class="checkbox-inline"><input type="checkbox" :value="4" v-model="reg.hobby">写代码</label>
      </div>
</div>
  • 下拉菜单
  • 单选:对于下拉菜单,给select绑定v-model,option的内容给用户看,value才是我们想要取到
 <div class="form-group row">
   <label class="col-lg-1">职业</label>
  <!-- 对于下拉列表框, 给select绑定v-model-->
       <div class="col-lg-11">
           <select class="form-control" v-model="reg.job">
              <option value="">--请选择--</option>
              <option :value="1">web工程师</option>
              <option :value="2">java工程师</option>
              <option :value="3">php工程师</option>
              <option :value="4">软件测试</option>
              <option :value="5">ui设计</option>
           </select>
       </div>
</div>
  • 下拉菜单
  • 多选:对应多选下拉,添加multiple属性,初始值给数组
 <div class="form-group">
    <label>零食</label>
 <!-- 对于多选下拉列表框, 设置multiple属性-->
    <select class="form-control" multiple v-model="reg.lingshi">
       <option value="">--请选择--</option>
       <option :value="1">乐事薯片</option>
       <option :value="2">绝味鸭脖</option>
       <option :value="3">卫龙辣条</option>
       <option :value="4">蜜雪冰城</option>
       <option :value="5">AD钙奶</option>
    </select>
 </div>
  • 文本域
<div class="form-group">
      <label>备注</label>
      <textarea class="form-control" rows="3" v-model="reg.des"></textarea>
</div>
<div class="form-group row">
      <label class="col-lg-1">同意协议</label>
      <div class="col-lg-11">
          <input type="checkbox" v-model="reg.isAgree">
      </div>
</div>
<button type="button" class="btn btn-primary" :disabled="!reg.isAgree">注册</button>
 <script>
        //实例化vue
        new Vue({
            //挂载点
            el: "#app",
            //data:model(数据模型)--页面所需的数据
            data: {
                reg:{
                    name:"",
                    pass:"",
                    tel:"",
                    sex:0,
                    hobby:[],
                    job:"",
                    lingshi:[],
                    des:"",
                    isAgree:false
                }
            },
            //methods:方法  需要使用的函数
            methods: {}
        })
    </script>

1、3表单修饰符

  • 修饰符就是起修饰作用,通过 . 来调用,都是加在指令的后面
  • 注意点:修饰符可以连续调用,如:.self.once
    .lazy
    语法:指令 .lazy
    作用:失去光标才去修改模型中的数据
<!-- .lazy 失去光标才去修改模型中的数据 -->
<input type="text" v-model.lazy="name"><br>

.number
语法:指令 .number
作用:将输入的内容自动转换为number类型,可以配合type="number"使用,约束用户的输入

<!-- .number 将输入的内容自动转换为number类型,可以配合type='number'使用,约束用户的输入 -->
<input type="text" v-model.number="num1"> +
<input type="text" v-model.number="num2"> =
<p>{{num1 + num2 }}</p>

.trim
语法:指令 .trim
作用:失去光标,自动去除前后空格

 <!-- .trim : 失去光标的时候,自动去除前后空格 -->
 <input type="text" v-model.trim="text">
 <p>|+{{text}}+|</p>
 <script>
       //实例化vue
       new Vue({
           //挂载点
           el:"#app",
           //data:model(数据模型)--页面所需的数据
           data:{
               name:"",
               num1:"",
               num2:"",
               text:""
           },
           //methods:方法  需要使用的函数
           methods:{}
       })
   </script>

2、事件绑定v-on

2.1 事件绑定及传参

 <!-- 定义挂载点 -->
 <div id="app">
   <!-- v-on:事件名 = ‘h函数’ 简写@ -->
   <button @click="study()">明天自学</button>
   <!-- ()可加可不加 -->
   <button @click="study">明天自学</button>
   <!-- 如果需要传参,必须要加() -->
   <button @click="delItem(1)">删除某一项</button>
 </div>
<script>
     //实例化vue
     new Vue({
         //挂载点
         el:"#app",
         //data:model(数据模型)--页面所需的数据
         data:{},
         //methods:方法  需要使用的函数
          methods:{
            study(){
              console.log("明天学习vue第三天");
                },
             delItem(n){
              console.log("删除"+n+"项");
                }
            }
        })
</script>

2.2 获取事件对象

  • 获取事件对象 -event
 <!-- 定义挂载点 -->
 <div id="app">
   <!-- 隐式传递事件对象,函数不加括号的情况下,第一个参数就是event事件对象 -->
   <!-- <div @click="clickFun"></div> -->

    <!-- 显示传递事件对象,加括号就必须传递event对象 -->
    <div @click="clickFun($event,10,20)"></div>
 </div>
 <script>
      //实例化vue
     new Vue({
        //挂载点
        el:"#app",
        //data:model(数据模型)--页面所需的数据
        data:{},
        //methods:方法  需要使用的函数
        methods:{
          clickFun(event,a,b){
             console.log(event);
             console.log(a,b);
           }
        }
     })
 </script>

2.3 阻止默认事件,阻止事件传播

  • 阻止
 <!-- 定义挂载点 -->
<div id="app">
    <a  @click="default1"  href="https://www.520xgg.com/?01081720apc-105821611jq&sdclkid=ALf_15fGbSDlA6DN"><img src="https://img2.baidu.com/it/u=1258968720,105769531&fm=253&fmt=auto&app=120&f=JPEG?w=736&h=500" alt=""></a>
    <div class="outer" @click="outer">
      <div class="inner" @click="inner"></div>
    </div>
</div>
<script>
      //实例化vue
      new Vue({
      //挂载点
           el:"#app",
           //data:model(数据模型)--页面所需的数据
           data:{},
           //methods:方法  需要使用的函数
           methods:{
               default1(event){ //隐式传递,默认第一个参数就是事件对象
            //阻止默认行为: event.preventDefault() / event.returnValue=false -- 原生js
                   console.log("阻止默认行为");
                   event.preventDefault();
               },
               outer(){
                   console.log("大盒子被点击了");
               },
               inner(event){
               //阻止事件冒泡:event.stopPropagation() / event.cancelBubble=true -- 原生js
                   console.log("小盒子被点击了");
                   event.stopPropagation();
               }
           }
       })
</script>

2.4 事件修饰符

  • 事件后面 @事件名 . 修饰符
  • 修饰符
.prevent     阻止事件默认行为
.stop        阻止事件冒泡
.self        只触发自己,任何其他的如冒泡都不能触发,只能自己触发自己
.once        只触发一次
.capture     事件捕获
  • 案例
 <!-- 定义挂载点 -->
    <div id="app">
        <!-- .prevent   阻止事件默认新闻 -->
        <a href="http://www.baidu.com" @click.prevent="default1">百度</a>
        <!-- .stop 阻止事件冒泡 -->
        <div class="outer" @click="outer">
            <div class="inner" @click.stop="inner"></div>
        </div>
        <!-- .self 只触发自己的事件 -->
        <div class="box">
            <button @click = 'isShow = true'>显示弹框</button>
            <div class="content" v-show="isShow" @click.self="isShow=false">
                <input type="text">
                <button>确定</button>
                <button>取消</button>
            </div>
        </div>
        <!-- .once : 一次性事件 -->
        <button @click.once="home">抽奖</button>
        <!-- .capture:事件捕获(一般不用) -->
        <div class="outer" @click.capture="outer">
            <div class="inner" @click.capture="inner"></div>
        </div>     
    </div>

  <script>
        //实例化vue
        new Vue({
            //挂载点
            el:"#app",
            //data:model(数据模型)--页面所需的数据
            data:{
                isShow:false
            },
            //methods:方法  需要使用的函数
            methods:{
                default1(){
                    console.log("点击了a,但是不想让他跳转");
                },
                outer(){
                    console.log("大盒子被点击了");
                },
                inner(){
                    console.log("小盒子被点击了"); 
                },
                home(){
                    console.log("10个");
                }
            }
        })
</script>

2.5 键盘修饰符

  • 键盘修饰符:@键盘事件名.修饰符=“函数”
  除了按键名key之外,你可以利用keyCode码作为修饰符,但是不推荐keyCode码,因为不同的键盘keyCode可能不同 (vue3中移除了keyCode码)
     .enter 		回车
     .left 		    左箭头
     .right         右箭头
     .up 		    上箭头
     .down 		    下箭头
     .space 		空格
     .delete 	    删除 (捕获删除和退格键)
     .esc    	    退出
     .tab    	    换行(必须配合keydown使用)
     .shift
     .alt
     .ctrl
      65
 <input type="text" @keydown.65="enterFun" @keydown.space="spaceFun">
        -->

3、$set的用法

(1) 一个json属性,如果是在data中声明了这个属性,vue会自动给它加上set和get方法,如果属性改变会引起页面的重新渲染
(2) 刚开始没有在data中定义height属性,height属性没有set和get,数据改变页面不会发生变化

  • 说明
this.obj.age=19;
如上这种添加属性的方法无法实现响应式的数据变化,所以要添加响应式的数据不能这样写。

vue是响应式的数据变化,数据改变视图就会改变。
底层原理:因为每一个对象的属性本身都有get(取值)和set(赋值),
这样底层的数据劫持就会根据set方法的执行,发现变化就更新视图

我们在向对象添加属性的时候,如果用以上直接添加,这个属性是不会被vue响应式管理的,
因为没有使用对象的get(取值)和set(赋值)。必须用$set来添加,这样这个属性在底层会用到get set,
这样这个属性就会是响应式的。

以下两个方法其实是同一个方法
this.$set(对象,key,value)
Vue.set(对象,key,value)

总结:未来在给对象添加属性的时候,如果遇到新增属性或者数组元素,无论是对象或者数组都要
利用这个方法去添加(主要是对象)

vue对数组的一些方法进行了重新封装,因此这些数组的方法可以进行响应式变化:
push(),pop(),shift(),unshift(),sort(),reverse(),splice()
  • 使用
<!-- 定义挂载点 -->
<div id="app">
  <p>{{user}}</p>
  <button @click="addAge">添加age</button>
  <button @click="changeName">修改名字</button>
  <button @click="changeAge">修改年龄</button>
  <ul>
     <li v-for="item in students" :key="item.id">
       <p>今天吃什么:{{item.name}}</p>
       <p>价格:{{item.price}}</p>
     </li>
  </ul>
  <button @click="addPrice">添加价格</button>
</div>
<script>
 new Vue({
   el: "#app",
   data: {
      user: {
         name: "迪丽热巴",
      },
      students: [
                { id: 1,name:"红烧牛肉面" },
                { id: 2,name:"烧烤" },
                { id: 3,name:"螺蛳粉" },
                { id: 4,name:"螺蛳粉" }]
       },
       methods: {
        //1.修改名字
        changeName() {
         this.user.name = "古力娜扎"
         },
        //2.添加属性
        addAge() {
        /*如果在data声明了这个属性,vue会自动给他添加上set和get方法,通过set能监听到数据的改变,如果数据变了,会引起页面的重新渲染 -- vue3已经解决*/
        // this.user.age = 18; 不会重新渲染,因为没有get和set
        //解决办法
        //1.Vue.set(target,key,value)
       //Vue.set(this.user,"age",18);
       //2.vue.$set(target,key,value) -- 推荐使用
       // this.$set(this.user,"age",18);
       //3.整体给user重新赋值
       this.user = {
       ...this.user,
          age: 20
       }
       console.log(this.user);
       },
       changeAge() {
          this.user.age = 19;
        },
       addPrice(){
       //问题:先没有在data中定义,没有set和get
         this.students.forEach((value,index)=>{
          this.$set(value,"price","7")
         });
          console.log(this.students);
         }
       }
  })
</script>

4、生命周期

4.1生命周期钩子函数

  • 八大生命周期
创建之前  beforeCreate(){}
创建完成  created(){}
挂载之前  beforeMount(){}
挂载完成  mounted(){}
更新之前  beforeUpdate(){}
更新完成  updated(){}
销毁之前  beforeDestroy(){}
销毁完成  destroyed(){}
  • 如何理解生命周期流程图(重点)
vue实例化开始:
 1、进入到创建之前,这个时候没有el元素,也没有data数据,但是含有一些内置事件和生命周期函数。
 2、生命周期走到创建完成,这个时候依然没有el元素,但是出现了数据data,(可以发起ajax请求)
 (只要有data就可以发起ajax请求)
 3、生命周期走到挂载之前,这个时候出现了大量的逻辑,判断是否有el元素和模板
   (1)首先要判断是否含有el元素
    如果有,生命周期继续执行;
    如果没有,判断是否调用了原型上的$mount(),如果有,生命周期继续执行;如果都没有,生命周期结束。
   (这里要注意:$mount('html选择器')是手动挂载,是vue原型上的方法)
   (2)然后,我们要判断是否含有template(模板)配置项(对应的是html片段)
    如果有,就将它编译到render函数中进行渲染
    如果没有,就渲染外部HTML。
      这里,我们也可以自己写render函数,render函数的参数也是一个函数,该函数接收两个参数
    第一个参数为标签,第二个参数为内容,即将内容放入到这个标签中并调用,返回调用的结果,这个结果会渲染到视图上,代替模板
    例:
    render(createElement){
    // createElement调用,参数2放入到参数1中,代替el元素渲染到页面
      return createElement('h1', 'render函数渲染内容');
     },
     
    渲染的优先级是:render(){}>template>外部的HTML
  这个时候视图并没有渲染,用的仍然是未渲染的html内容,数据data依然存在
4、生命周期走到挂载完成,视图进行了重新渲染(用编译后的html替换了挂载点的内容),数据依然存在,这个时候就可以使用DOM节点了
5、当数据发生变化的时候,会触发更新之前和更新完成;(更新完成之后,可以获取最新的DOM节点)
6、手动调用$destroy()这个方法,会执行销毁之前和销毁完成
($destroy()是vue原型上的方法)销毁之前要卸载监听,否则会容易导致内存泄漏
  <div id="app">
       <p>姓名:{{name}}</p>
       <p>{{user}}</p>
       <button id="guzai">手动挂载</button>
       <button id="xiezai">手动卸载</button>
       <button @click="update">更新</button>
       <button @click="add">添加身高</button>
   </div>
   <script>
       /* 自己触发的函数:钩子函数
        1.创建vue实例:创建之前(beforeCreate),创建完成(created)
        2.挂载期:挂载之前(beforeMount),挂载完成(mounted)
        3.更新期:更新之前(beforeUpdate),更新完成(updated)
        4.卸载期:卸载之前(beforeDestroy),卸载完成(destroyed)

        一般在什么地方发ajax请求
        可以在created,beforeMount,mounted都可以发起ajax,我一般在mounted
       */
       let vue = new Vue({
           el:"#app",
           //template:模板,如果有template,会优先加载template,替换el的挂载点
           // template:"<div class='box'><h1>我是template111</h1></div>",
           // render(h){
           //     return h("div",'我是template222')
           // },
           data: {
               name: "妲己",
               user:{
                   weight:180
               }
           },
           methods: {
               update(){
                   // this.name = "姜子牙";
                   this.user.weight = 170;
               },
               add(){
                   this.user.height = 180
               }
           },

           //1.创建之前(beforeCreate),所有的都是undefined
           beforeCreate() {
               console.group("创建之前");
               console.log("el", this.$el);
               console.log("data", this.$data);
               console.log("name", this.name);
               console.groupEnd();
           },

           //2.创建完成(created),vue实例中的data数据已经初始化完成,但是el还是undefined,最早能发ajax的地方
           created() {
               console.group("创建完成");
               console.log("el", this.$el); //undefined
               console.log("data", this.$data); //{}
               console.log("name", this.name); //妲己
               console.groupEnd();
           },

           //有el属性 或者 执行 vue.$mount()  才会进入挂载期
           //3.挂载之前(beforeMount),找到了挂载点,但是{{name}}
           beforeMount() {
               console.group("挂载之前");
               console.log("el", this.$el);
               console.log("data", this.$data);
               console.log("name", this.name);
               console.groupEnd();
           },

           //4.挂载完成(mounted):数据解析完成,页面渲染好
           //ajax,DOM操作,window|document添加事件,开启定时器
           mounted() {
               console.group("挂载完成");
               console.log("el", this.$el);
               console.log("data", this.$data);
               console.log("name", this.name);
               console.groupEnd();
           },
           //5.更新之前(beforeUpdate),页面更新之前,数据就已经是最新了
           beforeUpdate(){
               console.group("更新之前");
               console.log("el", this.$el);
               console.log("data", this.$data);
               console.log("name", this.name);
               console.groupEnd();
           },
           //6.更新完成(updated)
           updated(){
               console.group("更新完成");
               console.log("el", this.$el);
               console.log("data", this.$data);
               console.log("name", this.name);
               console.groupEnd();
           },
           //7.卸载之前(beforeDestroy)
           //善后工作:取消window|document事件,关闭定时器
           beforeDestroy(){
               console.group("卸载之前");
               console.log("el", this.$el);
               console.log("data", this.$data);
               console.log("name", this.name);
               console.groupEnd();
           },

           //8.卸载完成(destroyed)
           //DOM处于卸载前最后一个状态,vue不再控制这个节点了
           destroyed(){
               console.group("卸载完成");
               console.log("el", this.$el);
               console.log("data", this.$data);
               console.log("name", this.name);
               console.groupEnd();
           },
       })



       //手动挂载
       document.querySelector("#guzai").onclick = function () {
           //vue.$mount("挂载点")
           vue.$mount("#app");
       }

       //手动卸载
       document.querySelector("#xiezai").onclick = function () {
           vue.$destroy();
       }
   </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值