Vue(二)

189 阅读6分钟

表单

V-model实现双向绑定,常用于表单元素。

单选框

如果要让多个单选框成为一组,必须保证 v-model的值必须相等(利用数据互斥实现:当data中的数据发送变化时,对应的单选框就会被选中 选中单选框的时候,data中的数据也会跟着变化,变成单选框中value的属性值)

 <div id="app">
    选择一个你最喜欢的明星:<br>
    <!--input的值由它的value属性来决定,值是啥在这里不重要,不要过分在意 -->
   <input type="radio" v-model="inputData" value="迪丽热巴">成龙<br>
   <input type="radio" v-model="inputData" value="古力娜扎">吴彦祖<br>
   <input type="radio" v-model="inputData" value="三上悠亚">李小龙<br>
  </div>
  <script src="vue.js"></script>
  new Vue({
      el:"#app",
      data:{
        inputData:""
      },
      methods: {
      },
    })

多选框

我们一般用V-modelValue一起使用,同时绑定的数据必须是一个数组。同一组的多选框必须绑定同一个数据。

 <p>选择您喜欢的电视剧</p>
 <!--注意:这里的input的类型要设置为checkbox  -->
    <input type="checkbox" v-model="checkData" value="雪中悍刀行">雪中悍刀行<br>
    <input type="checkbox" v-model="checkData" value="风起洛阳">风起洛阳<br>
    <input type="checkbox" v-model="checkData" value="小敏家">小敏家<br>
    <input type="checkbox" v-model="checkData" value="谁是凶手">谁是凶手<br>
    <input type="checkbox" v-model="checkData" value="对手">对手<br>
  <!-- 这句话是提示语可以不要 -->
    <p>您选择的是:{{checkData}}</p>
 var vm = new Vue({
      el: '#app',
      data: {
      //当在这里边的值为true(可以查找到)就会被选中;此处默认是“对手”和“风起洛阳”两部电视剧被选中
        checkData:['对手','风起洛阳']
      },
      methods: {}
    });

下拉框

下拉框的数据绑定是绑定在select标签上的,如果要想实现下拉框也多选,只需要给select标签加一个multipe属性即可。

  <div id ="app">
    请选择您喜欢的电视剧:
   <!--多选之后用这个: <select v-model="selectData" multiple> -->
   <select v-model="selectData" >
      <!-- option中的value有值时,数据会优先匹配value中的值,否则匹配的是option中的文本 -->
      <option value="">---请选择---</option>
      <option value="雪中悍刀行">雪中悍刀行</option>
      <option value="风起洛阳">风起洛阳</option>
      <option value="小敏家">小敏家</option>
      <option value="谁是凶手">谁是凶手</option>
      <option value="对手">对手</option>
    </select>
    <p>{{selectData}}</p>
  </div>
   var vm = new Vue({
    el: '#app',
    data: {
      //如果想要让下拉框有一个默认选中的值,只需要给数据添加一个默认值就可以了。
      selectData:""
    },
    methods: {}
   });

表单修饰符

格式:V-model:修饰符,常用的有.number转为数字,.trim去除空格。

  <div id ="app">
    用户名:<input type="text" v-model.trim="username"><br>
    年龄:<input type="text" v-model.number="age">
    <!-- inp格式为数字,最小值为0,有且只能输入数字,不是数字格式无法输入  -->
    <!-- 年龄:<input type="number" v-model.number="age" min="0">  -->
  </div>
   var vm = new Vue({
    el: '#app',
    data: {
      username:"lisi",
      age:20
    },
    methods: { 
    }
   });

计算属性

有时候我们需要在模板中绑定表达式来做简单的数据处理,但是如果表达式太长逻辑太复杂,就会显得代码非常臃肿而且难以维护。这时我们就可以使用计算属性来解决问题。我们的计算属性都是写在computed中,里面写的都是函数,需要注意的是调用的时候并不需要在后边加上()

计算属性的特点:

  • 计算属性中任意一个实例数据发生变化,计算属性就会重新计算,视图也会更新。
  • 每一个计算属性都包含一个getter和setter。每调用一次计算属性,就相当于调用一次属性的getter,每当计算属性的值发生变化时,会默认调用setter。
  • 计算属性可以依赖多个vue实例中的数据。

例子:计算三科成绩总分

 <style>
    .container{
      width: 800px;
      margin-top: 50px;
    }
    td input{
      width: 50px;
      height: 30px;
    }
  </style>
 <table class="table container" id="app">
    <thead>
      <tr>
        <th scope="col">序号</th>
        <th scope="col">科目</th>
        <th scope="col">成绩</th>
      </tr>
    </thead>
    <tbody v-show="performance.length>0">
      <tr v-for="(item,index) in performance" :key="item.id">
        <th scope="row">{{item.id}}</th>
        <td>{{item.subject}}</td>
        <td>
          <input type="number" v-model.number="item.score" min="0">
        </td>
      </tr>
      <thead>
        <tr>
          <th scope="col">总分:{{totalscore}}</th>
        </tr>
      </thead>
    </tbody>
  </table>
 new Vue({
      el:"#app",
      data:{
        performance:[
          {
            id:1,
            subject:"语文",
            score:"0"
          },
          {
            id:2,
            subject:"数学",
            score:"0"
          },
          {
            id:3,
            subject:"英语",
            score:"0"
          }
        ],
      },
      methods:{},
      computed:{
        totalscore(){
          let sum=null;
          for (var i = 0; i <this.performance.length ; i++) {
             sum += parseInt(this.performance[i].score);
          }
          return sum;
        }
      }
    })

input框输入各科的成绩,自动计算出结果 2.png

computedmethods比较:

methods方法和computed计算属性,最终结果是完全相同,不同的是计算属性是依赖缓存的;methods方法,每当触发重新渲染时,调用方法将所有methods都执行一遍。绑定事件使用methods,逻辑运算使用计算属性。

watch监听

可以监听data中数据的变化,只有变化,就能执行相应的逻辑。

  <div id="app">
    名:<input type="text" v-model="firstName"><br>
    姓:<input type="text" v-model="lastName"><br>
    全名:{{fullName}}
  </div>
  var vm = new Vue({
      el: '#app',
      data: {
        firstName: "尼古拉斯",
        lastName: "赵四",
        fullName: ""
      },
      methods: {
        joinName(newValue, oldValue) {
          this.fullName = this.firstName + "·" + this.lastName
        }
      },
      watch: {
      firstName: {
 //handler是一个固定写法  当监听的数据发送变化时,handler方法就会执行。 
 //第一个参数是改变后的值,第二个参数是改变前的值。
          handler(newValue, oldValue) {
            this.joinName(newValue, oldValue);
          },
          //立刻执行
          immediate: true
        },
        lastName: {
          handler(newValue, oldValue) {
            this.joinName(newValue, oldValue);
          }
        }
      }
    });

深度监听

如果我们data中存储的数据是一个对象或者是比较复杂的数据结构,我们要想监听到对象中或者复杂数据结构中的一个属性,则用以上方法没有办法实现。

 //如果要对对象的某个特点属性进行监听,则格式为:
    watch:{
      ...
      "对象.属性名":{
        handler(newVal,oldVal){

        },
        deep:true
      }
      ...
    }

例子

 <div id="app">
    <input type="text" v-model="person.name">
  </div>
    //创建Vue实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        person: {
          id: "1",
          name: "张三"
        }
      },
      methods: {},
      watch: {
        //需要监听的对象的属性
        "person.name": {
          handler(newValue, oldValue) {
            console.log("修改前的值:" + oldValue);
            console.log("修改后的值:" + newValue);
          },
           //深度监听,对复杂数据类型中的属性也能起到监听的效果
          deep:true
        }
      }
    });

效果如下:

22.gif

异步操作

前面我们学了computed计算属性,但是对于有些的异步操作,计算属性确不能够实现。遇到这种情况我们就可以考虑使用watch监听。

例子

 <div id ="app">
    <input type="text" v-model="age">
    <p>3秒后后,他的年龄是:{{afterAge}}</p>
  </div>
 var vm = new Vue({
    el: '#app',
    data: {
      age:10,
      afterAge:10
    },
    methods: {},
   //这里如果我们用计算属性的话,他就会立即执行,所以对于异步的操作不是很合适
    watch:{
      age:{
        handler(){
          setTimeout(()=>{
            this.afterAge = this.age + 1;
          },3000)
        },
        immediate:true
      }
    }
 });

效果如下:

2.gif

过滤器

过滤:将一个数据经过一个过滤器,进行加工,得到我们想要的结果。

过滤器的分类:

全局过滤器:全部的Vue实例都可以用

定义Vue.filter("过滤器名称",过滤器处理函数)

使用

 数据 | 过滤器名称  
 
 插值:{{数据 | 过滤器名称}}}  
 
 数据绑定  :class="数据 | 过滤器名称"

局部过滤器: 只能在定义的那一个vue实例中使用

定义: 定义在new Vue中的配置对象filters属性中

  filters:{
    过滤器名称(){
    }
  }

注意:

//1.当全局过滤器和局部过滤器重名时,会采用局部过滤器。
//2.过滤器可以调用多个
//3.过滤器可以接受参数(过滤器的第一个参数默认是 过滤的数据,传递的参数从第二个开始接收)
      {{data | filterA(arg1,arg2) }}
      //value的值就是data的值。
      filterA(value,arg1,arg2){
      }

例子1:

  <div id="app">
    请输入一个年份:<input type="number" v-model.number="inp"><br>
    <p>{{inp | screen}}</p>
  </div>
  <script src="./vue.js"></script>
 var vm = new Vue({
      el: '#app',
      data: {
        inp:""
      },
      filters: {
        screen(i) {
          if (i<0) {
            return "公元前"+Math.abs(i)+"年"
          } else {
            return "公元"+ i +"年"
          }
        }
      }
    })

效果如下:

下载.gif 例子2:

 <div id ="app">
    {{date | formater}}
  </div>
 var vm = new Vue({
    el: '#app',
    data: {
      //参照的时间点
      date:new Date("2022-01-05 17:00:00")
    },
    filters:{
      formater(value){
        //获取要过滤的时间与当前时间的时间差。(单位秒)
        const d = Math.floor((Date.now()-value.getTime())/1000);
        const arr = [0,60,60*60,60*60*24,60*60*24*30,60*60*24*30*12];
        const _arr = ["刚刚","分钟前","小时前","天前","月前","年前"];
        for (var i = arr.length-1; i >=0; i--) {
           if (d>arr[i]) {
             return i==0?_arr[i]:Math.floor(d/arr[i]) + _arr[i]
           }
        }
        return value
      }
    }
   });

绑定Css的classstyle

绑定Class

直接绑定的方式、对象绑定的方式、数组绑定的方式、数组+对象绑定的方式。

例子

<style>
    .big {
      font-size: 50px;
    }
    .green {
      color: green;
    }
    .red {
      color: red;
    }
    .bc_yellow{
      background-color: yellow;
    }
    .bc_yellow{
      background-color: blue;
    }
  </style>
  <div id="app">
    <!--这是直接绑定的方式-->
    <div :class="activesClass" class="big">这是直接绑定的方式</div>
    <!--对象的方式 -->
    <div :class="{green:isGreen}">这是利用对象绑定的方式1</div>
    <div :class="obj">这是利用对象绑定的方式2</div>
    <!--这是利用数组的方式-->
    <div :class="[mySize]">这是利用数组绑定的方式</div>
    <!--数组+对象的方式-->
    <div :class="[obj,bc_Color]">这是利用数组+对象的方式</div>
    <!--利用计算属性返回一个对象-->
    <p :class="bb">利用计算属性返回一个对象</p>
  </div>
  <script>
    var vm = new Vue({
      el: '#app',
      data: {
        isGreen: true,
        //利用对象绑定时候可以写多个样式,通过设置样式的布尔值来决定哪个生效
        obj: {
          "red": true,
          "big": true,
        },
        bc_Color:"bc_yellow",
        mySize:"big"
      },
       computed: {
        bb() {
          return {
            // 当data中的num大于18生效
            "green": this.num >= 18,
            "big": true
          }
        }
      }
    })
 </script>

image.png Tips:

  • 使用对象绑定的方式的时候也可以通过一个计算属性返回一个对象
  • 绑定的类名比较少,可以直接绑定对象,如果比较多,建议将对象写在data中,如果涉及到逻辑运算,可以用计算属性返回一个对象

绑定Style

对象语法、计算属性、数组语法

 <style>
    .red {
      color: red;
    }
    .green {
      color: green;
    }
    .big {
      font-size: 48px;
    }
  </style>
  <div id="app">
    <p :style="{color:'red',backgroundColor:'skyblue'}">对象的方式</p>
    <p :style="myStyle">计算属性</p>
    <p :style="[aa,bb]">数组语法</p>
  </div>
  <script>
    //创建Vue实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        activeColor:"green",
        aa: {
          color: 'red', backgroundColor: 'skyblue'
        },
        bb:{
          fontSize:"30px"
        }
      },
      computed:{
        myStyle(){
          return {
            color: 'green', backgroundColor: 'skyblue'
          }
        }
      }
    });
  </script>

Tips

  • 对象语法如果样式的名字带有-则改为驼峰式命名:style={样式名:'样式值'} :style="obj" 样式值可以是data中的一个变量
  • 数组语法可以将多个样式对象写在同一个人数组中;计算属性需要返回一个样式对象。