Vue基础入门(二)

1,262 阅读6分钟

表单基本操作

获取单选框的值

  • 通过V-model 同时必须要有value属性 ,value值不能一样

     	<!-- 
    		1、 两个单选框需要同时通过v-model 双向绑定 一个值 
            2、 每一个单选框必须要有value属性  且value 值不能一样 
    		3、 当某一个单选框选中的时候 v-model  会将当前的 value值 改变 data 中的 数据
    
    		gender 的值就是选中的值,我们只需要实时监控他的值就可以了
    	-->
       <input type="radio" id="male" value="1" v-model='gender'>
       <label for="male"></label>
    
       <input type="radio" id="female" value="2" v-model='gender'>
       <label for="female"></label>
    
    <script>
        new Vue({
             data: {
                 // 默认会让当前的 value 值为 2 的单选框选中
                    gender: 2,  
                },
        })
    
    </script>
    

获取复选框

  • 通过v-model
  • 同时必须要有value属性,value值不能一样
  • 复选框 checkbox 这种的组合时 data 中的 hobby 我们要定义成数组 否则无法实现多选
	<!-- 
		1、 复选框需要同时通过v-model 双向绑定 一个值 
        2、 每一个复选框必须要有value属性  且value 值不能一样 
		3、 当某一个单选框选中的时候 v-model  会将当前的 value值 改变 data 中的 数据

		hobby 的值就是选中的值,我们只需要实时监控他的值就可以了
	-->

<div>
   <span>爱好:</span>
   <input type="checkbox" id="ball" value="1" v-model='hobby'>
   <label for="ball">篮球</label>
   <input type="checkbox" id="sing" value="2" v-model='hobby'>
   <label for="sing">唱歌</label>
   <input type="checkbox" id="code" value="3" v-model='hobby'>
   <label for="code">写代码</label>
 </div>
<script>
    new Vue({
         data: {
                // 默认会让当前的 value 值为 2 和 3 的复选框选中
                hobby: ['2', '3'],
            },
    })
</script>

获取下拉框和文本框的值

  • 通过v-model

  • 下拉框(多选框) 中每一个option 必须要有value属性 且value 值不能一样

       <div>
          <span>职业:</span>
           <!--
    			1、 需要给select  通过v-model 双向绑定 一个值 
                2、 每一个option  必须要有value属性  且value 值不能一样 
    		    3、 当某一个option选中的时候 v-model  会将当前的 value值 改变 data 中的 数据
    		     occupation 的值就是选中的值,我们只需要实时监控他的值就可以了
    		-->
           <!-- multiple  多选 -->
          <select v-model='occupation' multiple>
              <option value="0">请选择职业...</option>
              <option value="1">教师</option>
              <option value="2">软件工程师</option>
              <option value="3">律师</option>
          </select>
             <!-- textarea 是 一个双标签   不需要绑定value 属性的  -->
            <textarea v-model='desc'></textarea>
      </div>
    <script>
        new Vue({
             data: {
                    // 默认会让当前的 value 值为 2 和 3 的下拉框选中
                     occupation: ['2', '3'],
                 	 desc: 'nihao'
                },
        })
    </script>
    

表单修饰符

.number转换为数值

  • 默认表单域中的值为字符串,如果进行数值运算则需要转换成number类型

    <!-- 自动将用户的输入值转为数值类型 -->
    <input v-model.number="age" type="number">
    

.trim去除首尾空白

  • 自动过滤用户输入的首尾空白字符

  • 只能去掉首尾空格,不能去除中间的空格

    <!--自动过滤用户输入的首尾空白字符   -->
    <input v-model.trim="msg">
    

.lazy 将input事件切换成change事件

  • input事件只有每次输入 时才会触发

  • change事件当失去焦点或按下回车时才会触发

    <!-- “change”延迟同步更新 -->
    <input v-model.lazy="msg" >
    

自定义指令

全局自定义指令(Vue.directive)

  • 内置指令不能满足我们的需求时 (一些DOM元素进行底层操作,如聚集输入框)
  • Vue允许我们自定义指令
  • 使用自定义指令会触发钩子函数
  • 自定指令官网 cn.vuejs.org/v2/guide/cu…

当页面加载时,该元素将获得焦点 (注意:autofocus 在移动版 Safari 上不工作)。事实上,只要你在打开这个页面后还没点击过任何内容,这个输入框就应当还是处于聚焦状态。

<!-- 
  使用自定义的指令,只需在对用的元素中,加上'v-'的前缀形成类似于内部指令'v-if','v-text'的形式。 
-->
<input type="text" v-focus>
<script>
// 注意点: 
//   1、 在自定义指令中  如果以驼峰命名的方式定义 如  Vue.directive('focusA',function(){}) 
//   2、 在HTML中使用的时候 只能通过 v-focus-a 来使用 
    
// 注册一个全局自定义指令 v-focus
Vue.directive('focus', {
  	// 当绑定元素插入到 DOM 中。 其中 el为dom元素   inserted为钩子函数
  	inserted: function (el) {
    		// 聚焦元素el:指令所绑定的元素,可以用来直接操作 DOM。
    		el.focus(); 
 	}
});
new Vue({
  el:'#app'
});
</script>

全局自定义指令 (带参)

  • binding.value表示的是data数据项
  • el:指令所绑定的元素,可以用来直接操作 DOM。
  <input type="text" v-color='msg'>
 <script type="text/javascript">
    /*
      自定义指令-带参数
      bind - 只调用一次,在指令第一次绑定到元素上时候调用

    */
    Vue.directive('color', {
      // bind声明周期, 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
      // el 为当前自定义指令的DOM元素  
      // binding 为自定义的函数形参   通过自定义属性传递过来的值 存在 binding.value 里面
      bind: function(el, binding){
        // 根据指令的参数设置背景色
        // console.log(binding.value.color)
        el.style.backgroundColor = binding.value.color;
      }
    });
    var vm = new Vue({
      el: '#app',
      data: {
        msg: {
          color: 'blue'
        }
      }
    });
  </script>

局部自定义指令

  • 局部指令,需要在vue实例中添加directives 选项, 用法和全局用法一样

  • 局部指令只能在当前组件里面使用

  • 当全局指令和局部指令同名时以局部指令为准

    <input type="text" v-color='msg'>
     <input type="text" v-focus>
     <script type="text/javascript">
        /*
          自定义指令-局部指令
        */
        var vm = new Vue({
          el: '#app',
          data: {
            msg: {
              color: 'red'
            }
          },
       	  //局部指令,需要定义在  directives 的选项
          directives: {
            color: {
              bind: function(el, binding){
                el.style.backgroundColor = binding.value.color;
              }
            },
            focus: {
              inserted: function(el) {
                el.focus();
              }
            }
          }
        });
      </script>
    

钩子函数

Vue实例从创建到销毁的过程中,会自动调用一些函数,我们称这些函数为钩子函数

一个自定义指令对象可以提供如下几个钩子函数

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。

钩子函数参数

指令钩子函数会被传入以下参数:

  • el:指令所绑定的元素,可以用来直接操作 DOM。
  • binding:一个对象,包含以下 property:
    • name:指令名,不包括 v- 前缀。
    • value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
    • oldValue:指令绑定的前一个值,仅在 updatecomponentUpdated 钩子中可用。无论值是否改变都可用。
    • expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"
    • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"
    • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }
  • vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
  • oldVnode:上一个虚拟节点,仅在 updatecomponentUpdated 钩子中可用。
  • 详细说明:参照 cn.vuejs.org/v2/guide/cu…

计算属性 ( computed)

  • 插值表达式中放入太多的逻辑会让模板过重难以维护,使用计算属性可以使用模板更简洁

    <--!插值表达式中放太多逻辑-->
    <div id="example">
      {{ message.split('').reverse().join('') }}
    </div>
    
  • 计算属性是基于data的数据实现的,同时也依赖于响应式进行缓存

  • 计算属性经常用来处理和模板相关的数据

  • 使用computed计算属性需要有return返回结果

     <div id="app">
         <!--  
            当多次调用 reverseString  的时候 
            只要里面的 num 值不改变 他会把第一次计算的结果直接返回
    		直到data 中的num值改变 计算属性才会重新发生计算
         -->
        <div>{{reverseString}}</div>
        <div>{{reverseString}}</div>
         <!-- 调用methods中的方法的时候  他每次会重新调用 -->
        <div>{{reverseMessage()}}</div>
        <div>{{reverseMessage()}}</div>
      </div>
      <script type="text/javascript">
        /*
          计算属性与方法的区别:计算属性是基于依赖进行缓存的,而方法不缓存
        */
        var vm = new Vue({
          el: '#app',
          data: {
            msg: 'Nihao',
            num: 100
          },
          methods: {
            reverseMessage: function(){
              console.log('methods')
              return this.msg.split('').reverse().join('');
            }
          },
          //computed  属性 定义 和 data 已经 methods 平级 
          computed: {
            //  reverseString   这个是我们自己定义的名字 
            reverseString: function(){
              console.log('computed')
              var total = 0;
              //  当data 中的 num 的值改变的时候  reverseString  会自动发生计算  
              for(var i=0;i<=this.num;i++){
                total += i;
              }
              // 这里一定要有return 否则 调用 reverseString 的 时候无法拿到结果    
              return total;
            }
          }
        });
      </script>
    

计算属性与methods方法的区别

  • computed计算属性是基于data的响应式依赖进行缓存的,只有相关响应式依赖发生改变时它才会重新求值
  • computed
  • methods方法没有缓存,访问多少次就执行多少次
  • 为什么需要计算属性, 减少性能的开销

侦听器 watch

  • 侦听器 侦听data数据的变化

  • 监听文本输入框绑定的值变化而执行接口请求

  • 一般使用在开销比较大或异步任务 比如ajax请求

  • watch中的属性一定是data中已经存在的数据

  • image-20210212173148869

     <div id="app">
            <div>
                <span>名:</span>
                <span>
            <input type="text" v-model='firstName'>
          </span>
            </div>
            <div>
                <span>姓:</span>
                <span>
            <input type="text" v-model='lastName'>
          </span>
            </div>
            <div>{{fullName}}</div>
        </div>
    
      <script type="text/javascript">
            /*
                  侦听器
                */
            var vm = new Vue({
                el: '#app',
                data: {
                    firstName: 'Jim',
                    lastName: 'Green',
                    // fullName: 'Jim Green'
                },
                 //watch  属性 定义 和 data 已经 methods 平级 
                watch: {
                    //   注意:  这里firstName  对应着data 中的 firstName 
                    //   当 firstName 值 改变的时候  会自动触发 watch
                    firstName: function(val) {
                        this.fullName = val + ' ' + this.lastName;
                    },
                    //   注意:  这里 lastName 对应着data 中的 lastName 
                    lastName: function(val) {
                        this.fullName = this.firstName + ' ' + val;
                    }
                }
            });
        </script>
    

过滤器

  • 格式化数据,比如字符串的首字母大写,将日期格式化成指定格式

  • 过滤器可以使用的两个地方,插值表达式和v-bind属性表达式

  • 支持多个过滤器一起使用 (执行顺序是 从左向右)

  • 每一个过滤器的功能保持单一 如果有多个过滤需求 申明多个过滤器

  • 过滤器应该被添加在JavaScript表达式的尾部

  • 过滤器不改变真正的data,而只是改变渲染的结果,并由return返回结果

  • 当全局过滤器和局部过滤器重名时,会采用局部过滤器

  • 全局注册时是filter,不需要加s的。

  • 局部注册时是filters,需要加s

    Vue3.0已经删除过滤器,不在支持过滤器 使用计算属性或者methods方法代替

    扩展阅读⚠️:vue3js.cn/docs/zh/gui…

全局过滤器

 <div id="app">
    <input type="text" v-model='msg'>
      <!-- upper 被定义为接收单个参数的过滤器函数,表达式  msg  的值将作为参数传入到函数中 -->
    <div>{{msg | upper}}</div>
    <!--  
      支持级联操作
      upper  被定义为接收单个参数的过滤器函数,表达式msg 的值将作为参数传入到函数中。
	  然后继续调用同样被定义为接收单个参数的过滤器 lower ,将upper 的结果传递到lower中
 	-->
    <div>{{msg | upper | lower}}</div>
    <div :abc='msg | upper'>测试数据</div>
  </div>

<script type="text/javascript">
   //  lower  为全局过滤器 名称    
   Vue.filter('lower', function(val) {
       //过滤器逻辑代码
      return val.charAt(0).toLowerCase() + val.slice(1);
    });
    var vm = new Vue({
      el: '#app',
      data: {
        msg: ''
      }
         });
  </script>

部分过滤器

  <div id="app">
    <input type="text" v-model='msg'>
      <!-- upper 被定义为接收单个参数的过滤器函数,表达式  msg  的值将作为参数传入到函数中 -->
    <div>{{msg | upper}}</div>
    <!--  
      支持级联操作
      upper  被定义为接收单个参数的过滤器函数,表达式msg 的值将作为参数传入到函数中。
	  然后继续调用同样被定义为接收单个参数的过滤器 lower ,将upper 的结果传递到lower中
 	-->
    <div>{{msg | upper | lower}}</div>
    <div :abc='msg | upper'>测试数据</div>
  </div>

<script type="text/javascript">
    var vm = new Vue({
      el: '#app',
      data: {
        msg: ''
      },
       //filters  属性 定义 和 data 已经 methods 平级 
       //  定义filters 中的过滤器为局部过滤器 
      filters: {
        //   upper  自定义的过滤器名字 
        //    upper 被定义为接收单个参数的过滤器函数,表达式  msg  的值将作为参数传入到函数中
        upper: function(val) {
         //  过滤器中一定要有返回值 这样外界使用过滤器的时候才能拿到结果
          return val.charAt(0).toUpperCase() + val.slice(1);
        }
      }
    });
  </script>

过滤器中传递参数

  • 使用过滤器时在括号中传递参数
  • 从第二个参数开始接过滤器参数
    <div id="box">
        <!--
			filterA 被定义为接收三个参数的过滤器函数。
  			其中 message 的值作为第一个参数,
			普通字符串 'arg1' 作为第二个参数,表达式 arg2 的值作为第三个参数。
		-->
        {{ message | filterA('arg1', 'arg2') }}
    </div>
    <script>
        // 在过滤器中 第一个参数 对应的是  管道符前面的数据   n  此时对应 message
        // 第2个参数  a 对应 实参  arg1 字符串
        // 第3个参数  b 对应 实参  arg2 字符串
        Vue.filter('filterA',function(n,a,b){
            if(n<10){
                return n+a;
            }else{
                return n+b;
            }
        });
        
        new Vue({
            el:"#box",
            data:{
                message: "哈哈哈"
            }
        })

    </script>

日期格式化规则

image-20210212194647831

  <div id="app">
    <div>{{date | format('yyyy-MM-dd hh:mm:ss')}}</div>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*
      过滤器案例:格式化日期
      
    */
    // Vue.filter('format', function(value, arg) {
      //  缺点是日期格式单一
    //   if(arg == 'yyyy-MM-dd') {
    //     var ret = '';
    //     ret += value.getFullYear() + '-' + (value.getMonth() + 1) + '-' + value.getDate();
    //     return ret;
    //   }
    //   return value;
    // })
    Vue.filter('format', function(value, arg) {
        //这是一个日期格式化规则
      function dateFormat(date, format) {
          if (typeof date === "string") {
              var mts = date.match(/(\/Date\((\d+)\)\/)/);
              if (mts && mts.length >= 3) {
                  date = parseInt(mts[2]);
              }
          }
          date = new Date(date);
          if (!date || date.toUTCString() == "Invalid Date") {
              return "";
          }
          var map = {
              "M": date.getMonth() + 1, //月份 
              "d": date.getDate(), //日 
              "h": date.getHours(), //小时 
              "m": date.getMinutes(), //分 
              "s": date.getSeconds(), //秒 
              "q": Math.floor((date.getMonth() + 3) / 3), //季度 
              "S": date.getMilliseconds() //毫秒 
          };

          format = format.replace(/([yMdhmsqS])+/g, function(all, t) {
              var v = map[t];
              if (v !== undefined) {
                  if (all.length > 1) {
                      v = '0' + v;
                      v = v.substr(v.length - 2);
                  }
                  return v;
              } else if (t === 'y') {
                  return (date.getFullYear() + '').substr(4 - all.length);
              }
              return all;
          });
          return format;
      }  
     //调用日期格式化函数
      return dateFormat(value, arg);
    })
    var vm = new Vue({
      el: '#app',
      data: {
        date: new Date()
      }
    });
  </script>

生命周期

  • 事物从出生到死亡的过程
  • Vue实例从创建到销毁的过程,这些过程中会伴随着一些函数的自调用,我们称这些函数为钩子函数

主要阶段

  • 挂载(初始化相关属性)
    1. beforeCreate
    2. created
    3. beforeMount
    4. mounted
  • 更新
    1. beforeUpdate
    2. updated
  • 销毁
    1. beforeDestroy
    2. destroyed

常用的钩子函数

beforeCreate在实例初始化之后,数据观测和事件配置之前被调用 此时data 和 methods 以及页面的DOM结构都没有初始化 什么都做不了
created在实例创建完成后被立即调用此时data 和 methods已经可以使用 但是页面还没有渲染出来
beforeMount在挂载开始之前被调用 此时页面上还看不到真实数据 只是一个模板页面而已
mountedel被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。 数据已经真实渲染到页面上 在这个钩子函数里面我们可以使用一些第三方的 插件
beforeUpdate数据更新时调用,发生在虚拟DOM打补丁之前。 页面上数据还是旧的
updated由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。 页面上数据已经替换成最新的
beforeDestroy实例销毁之前调用
destroyed实例销毁后调用

注意 初始化操作 Dom 一定要写在mounted钩子函数中 created钩子函数中一般初始化操作数据

lifecycle

数组变异方法

  • 在 Vue 中,直接修改对象属性的值无法触发响应式。当你直接修改了对象属性的值,你会发现,只有数据改了,但是页面内容并没有改变
  • 变异数组方法即保持数组方法原有功能不变的前提下对其进行功能拓展
  • 这些方法都会影响到原始数据 并且会被Vue处理成响应式数据
push()往数组最后面添加一个元素,成功返回当前数组的长度
pop()删除数组的最后一个元素,成功返回删除元素的值
shift()删除数组的第一个元素,成功返回删除元素的值
unshift()往数组最前面添加一个元素,成功返回当前数组的长度
splice()有三个参数,第一个是想要删除的元素的下标(必选),第二个是想要删除的个数(必选),第三个是删除 后想要在原位置替换的值
sort()sort() 使数组按照字符编码默认从小到大排序,成功返回排序后的数组
reverse()reverse() 将数组倒序,成功返回倒序后的数组

替换数组

  • 不会改变原始数组,但总是返回一个新数组
  • 这些方法不会改变原始数组,所以不会改变模板中的数据
filterfilter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
concatconcat() 方法用于连接两个或多个数组。该方法不会改变现有的数组
sliceslice() 方法可从已有的数组中返回选定的元素。该方法并不会修改数组,而是返回一个子数组

动态数组响应式数据

  • Vue.set(vm.items,index,newValue)
  • vm.$set(vm.items,index,newValue)
  1. 参数一表示要处理数组名称
  2. 参数二表示处理数组的索引
  3. 参数三表示处理数组后的值

动态对象响应式数据

  • Vue.set(vm.items,index,newValue)
  • vm.$set(vm.items,index,newValue)
    1. 参数一表示要处理的对象名称
    2. 参数二表示要处理对象的属性名
    3. 参数三表示处理对象后的值

Vue基础入门(一)

「点赞、收藏和评论」

❤️关注+点赞+收藏+评论+转发❤️,鼓励笔者创作更好的文章,谢谢🙏大家。