目录

计算属性-computed

插值语法实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue初体验</title>
    <!-- 1.引入Vue -->
    <script src="../js/vue.js"></script>
</head>
<body>
  <!-- 2.准备一个容器 -->
  <div id="root">
        <p>姓:<input type="text" v-model="frontName"></p>
        <p>姓:<input type="text" v-model="afterName"></p>
        <p>全名:{{frontName}}-{{afterName}}</p>
        <p>全名:{{frontName + '-' + afterName}}</p>
  </div>
  <script>
    //3.创建Vue实例
    const vm = new Vue({
        el:'#root',
        data:{
            frontName:'张',
            afterName:'三',
        }
    });
  </script>
</body>
</html>

methods实现

  • 原理:每当数据发生变化,和其相关的模板函数要重新解析(无关的不会解析)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue初体验</title>
    <!-- 1.引入Vue -->
    <script src="../js/vue.js"></script>
</head>
<body>
  <!-- 2.准备一个容器 -->
  <div id="root">
        <p>姓:<input type="text" v-model="frontName"></p>
        <p>姓:<input type="text" v-model="afterName"></p>
        <p>全名:{{fullName()}}</p><!-- fullName()方法名带括号表示使用的是方法的返回值 -->
        <p>全名:{{fullName()}}</p><!-- fullName()方法名带括号表示使用的是方法的返回值 -->
        <p>全名:{{fullName()}}</p><!-- fullName()方法名带括号表示使用的是方法的返回值 -->
  </div>
  <script>
    //3.创建Vue实例
    const vm = new Vue({
        el:'#root',
        data:{
            frontName:'张',
            afterName:'三',
        },
        methods:{
            fullName(){
                console.log('fullName');
                return this.frontName + '-' +  this.afterName;
            }
        }
    });
  </script>
</body>
</html>
  • 缺点: 每次与fullName()相关的变量发生变动时,fullName()都会变化
    【Vue】Vue的核心-LMLPHP

计算属性实现

  • vue将data中的数据视为属性

使用

  1. 定义: 要用的属性不存在,要通过已有属性(Vue实例中的属性)计算得来, 使用let或者 var定义的变量无法被vue实例监听到

  2. 原理: 底层借助了Object.defineproperty方法提供的getter和setter

  3. get函数什么时候执行?

    初次读取时会执行一次
    当依赖的数据发生改变时会被再次调用

  4. 优势: 与methods实现相比,内部有缓存机制(复用),效率更高,调试方便

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue初体验</title>
    <!-- 1.引入Vue -->
    <script src="../js/vue.js"></script>
</head>
<body>
  <!-- 2.准备一个容器 -->
  <div id="root">
        <p>姓:<input type="text" v-model="frontName"></p>
        <p>姓:<input type="text" v-model="afterName"></p>
        <p>全名:{{fullName}}</p>
        <p>全名:{{fullName}}</p>
        <p>全名:{{fullName}}</p>
  </div>
  <script>
    //3.创建Vue实例
    const vm = new Vue({
        el:'#root',
        data:{
            frontName:'张',
            afterName:'三',
        },
        computed:{
            fullName:{
                get(){
                    console.log('get被调用了')
                    console.log(this)
                    return this.frontName + '-' + this.afterName;
                },
                set(value){
                    console.log('set被调用了:',value)
                    const arr = value.split('-');
                    this.frontName = arr[0];
                    this.afterName = arr[1];
                }
            }
        }
    });
  </script>
</body>
</html>

【Vue】Vue的核心-LMLPHP

  • 多数情况下计算属性只考虑读取,不考虑修改,因此可以把set部分去掉,直接以函数式写法使用即可
        computed:{
            fullName(){
                return this.frontName + '-' + this.afterName;
            }
        }

使用总结:

  1. 要显示的数据不存在,要通过计算得来。
  2. 在 computed 对象中定义计算属性。
  3. 在页面中使用{{方法名}}来显示计算的结果

监视属性-watch

  1. 通过通过vm对象的$watch()或watch配置来监视指定的属性
  2. 当属性变化时, 回调函数自动调用, 在函数内部进行计算
  3. 当被监视的属性变化时, 回调函数自动调用(watch中调用的handler函数), 进行相关操作
  4. 监视的属性必须存在,才能进行监视!!

监视的两种写法:

  1. new Vue时传入watch配置

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Vue初体验</title>
        <!-- 1.引入Vue -->
        <script src="../js/vue.js"></script>
    </head>
    <body>
      <!-- 2.准备一个容器 -->
      <div id="root">
          <h1>今天天气很{{info}},{{x}}</h1>
          <button @click="isHot = !isHot,x++">切换</button>
          <button @click="change">+</button>
      </div>
      <script>
        //3.创建Vue实例
        const vm = new Vue({
            el:'#root',
            computed:{
                info(){
                    return this.isHot ? '炎热' : '寒冷';
                }
            },
            data:{
                isHot:true,
                x:0
            },
            methods:{
                change(){
                    this.isHot = !this.isHot;
                    this.x++;
                }
            },
            watch:{
                isHot(newValue,oldValue){
                    console.log(newValue,oldValue);
                }
            }
        });
      </script>
    </body>
    </html>
    
  2. 通过vm.$watch监视

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Vue初体验</title>
        <!-- 1.引入Vue -->
        <script src="../js/vue.js"></script>
    </head>
    <body>
      <!-- 2.准备一个容器 -->
      <div id="root">
          <h1>今天天气很{{info}},{{x}}</h1>
          <button @click="isHot = !isHot,x++">切换</button>
          <button @click="change">+</button>
      </div>
      <script>
        //3.创建Vue实例
        const vm = new Vue({
            el:'#root',
            computed:{
                info(){
                    return this.isHot ? '炎热' : '寒冷';
                }
            },
            data:{
                isHot:true,
                x:0
            },
            methods:{
                change(){
                    this.isHot = !this.isHot;
                    this.x++;
                }
            },
            /*watch:{
                isHot(newValue,oldValue){
                    console.log(newValue,oldValue);
                }
            }*/
        });
        vm.watch('isHot',function(newValue,oldValue){
            console.log(newValue,oldValue);
        })
      </script>
    </body>
    </html>
    

深度监视

  1. Vue中的watch默认不监测对象内部值的改变(针对引用值只监听一层)。
  2. 配置deep:true可以监测对象内部值改变(多层)。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue初体验</title>
    <!-- 1.引入Vue -->
    <script src="../js/vue.js"></script>
</head>
<body>
  <!-- 2.准备一个容器 -->
  <div id="root">
      <h1>a的值是:{{numbers.a}}</h1>
      <button @click="numbers.a++">a+1</button>
      <h1>b的值是:{{numbers.b}}</h1>
      <button @click="numbers.b++">b+1</button>
      <h1>e的值是:{{numbers.c.d.e}}</h1>
      <button @click="numbers.c.d.e++">e+1</button>
  </div>
  <script>
    //3.创建Vue实例
    const vm = new Vue({
        el:'#root',
        data:{
            numbers:{
                a:1,
                b:2,
                c:{
                    d:{
                        e: 100
                    }
                }
            }
        },
        watch:{
            numbers: {
                deep: true,// 开启深度监听
                handler(newValue, oldValue){
                    console.log('numbers改变啦!');
                }
            }
        }
    });
  </script>
</body>
</html>

备注:

  1. Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
  2. 使用watch时根据数据的具体结构,决定是否采用深度监视。

computed和watch之间的区别

  • computed能完成的功能,watch都可以完成。
  • watch能完成的功能,computed不一定能完成
    • 例如:watch可以进行异步操作,computed不可以。
      • 因为computed依赖返回值得到结果,而watch则是得到属性改变的结果
    • 例:让名字延迟1s再打印
      • watch能够实现:本质是watch无需通过一个返回值来实现任务,watch是通过让你自己执行代码来实现数据修改
      • couputed不能实现:本质计算属性的实现重要的是返回值,我们无法做到等一会儿再返回一个值(异步)

两个重要的小原则:

  • 所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。
  • 所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象。

绑定样式

  • 在应用界面中, 某个(些)元素的样式是变化的
  • class/style 绑定就是专门用来实现动态样式效果的技术
  • 绑定样式方式:
    • class样式绑定
    • sytle样式绑定

class样式绑定

  • 常规写法:class = ‘class1 class2’
  • v-bind 写法::class=“xxx” xxx可以是字符串、对象、数组
    • 字符串写法适用于:类名不确定,要动态获取,如 :class=“mood”
    • 数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用,如 :class=“[‘yk1’, ‘yk2’, ‘yk3’]”
    • 对象适用于:要绑定多个样式,个数确定,名字也确定,但是需要动态决定用不用,如 :class=“{ yk1: true,yk2: false,yk3: true}”

字符串写法

  • 表达式是字符串: ‘classA’ 适用于:类名不确定,要动态获取
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue初体验</title>
    <!-- 1.引入Vue -->
    <script src="../js/vue.js"></script>
    <style>
        .basic{
            width: 200px;
            height: 200px;
        }
        .normal{
            background-color: skyblue;
        }
        .happy{
            background-color: green;
        }
        .sad{
            background-color: gray;
        }
    </style>
</head>
<body>
  <!-- 2.准备一个容器 -->
  <div id="root">
      <div class="basic" :class="mood" @click="changeMood">{{name}}</div>
  </div>
  <script>
    //3.创建Vue实例
    const vm = new Vue({
        el:'#root',
        data:{
            name:'Vue',
            mood: 'normal'
        },
        methods:{
            changeMood(){
                const arr = ['normal', 'happy', 'sad'];
                const index = Math.floor(Math.random() * 3)//取0-3的随机数
                this.mood = arr[index];
            }
        }
    });
  </script>
</body>
</html>

数组写法

  • 表达式是数组: [‘classA’, ‘classB’] 适用于要绑定多个样式,个数确定,名字也确定,但不确定用不用
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue初体验</title>
    <!-- 1.引入Vue -->
    <script src="../js/vue.js"></script>
    <style>
        .basic{
            width: 200px;
            height: 200px;
        }
        .c1{
            background-color: yellowgreen;
        }
        .c2{
            font-size: 30px;
            color: blue;
        }
        .c3{
            border: 1px solid red;
            border-radius: 20px;
        }
    </style>
</head>
<body>
  <!-- 2.准备一个容器 -->
  <div id="root">
      <div class="basic" :class="classArr">{{name}}</div>
      <button @click="changeStyle">改变样式</button>
  </div>
  <script>
    //3.创建Vue实例
    const vm = new Vue({
        el:'#root',
        data:{
            name:'Vue',
            classArr: ['c1', 'c2']
        },
        methods:{
            changeStyle(){
                this.classArr.push('c3');
                this.classArr.splice(1, 1)//删除c2
            }
        }
    });
  </script>
</body>
</html>

对象写法

  • 表达式是对象: {classA:isA, classB: isB} 适用于要绑定多个样式,个数确定,名字也确定,但是需要动态决定用不用
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue初体验</title>
    <!-- 1.引入Vue -->
    <script src="../js/vue.js"></script>
    <style>
        .basic{
            width: 200px;
            height: 200px;
        }
        .c1{
            background-color: yellowgreen;
        }
        .c2{
            font-size: 30px;
            color: blue;
        }
        .c3{
            border: 1px solid red;
            border-radius: 20px;
        }
    </style>
</head>
<body>
  <!-- 2.准备一个容器 -->
  <div id="root">
      <div class="basic" :class="classObj">{{name}}</div>
      <button @click="changeStyle">改变样式</button>
  </div>
  <script>
    //3.创建Vue实例
    const vm = new Vue({
        el:'#root',
        data:{
            name:'Vue',
            classObj:{
                c1:true,
                c2:false,
                c3:true
            }
        },
        methods:{
            changeStyle(){
                this.classObj.c1 = !this.classObj.c1;
                this.classObj.c2 = !this.classObj.c2;
            }
        }
    });
  </script>
</body>
</html>

style样式绑定

  • 基础使用 style = ‘background:red’
  • v-bind使用 :
    • 对象:
      • :style = "{backgroundColor: 'orange'}"
      • :style="{ color: activeColor, fontSize: fontSize + 'px' }"
      • 其中 activeColor/fontSize 是 data 属性
    • 数组(用的很少): :style = '[{backgroundColor: 'orange'},{color: 'red'}]'

对象式1

:style = "{backgroundColor: 'orange'}"

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue初体验</title>
    <!-- 1.引入Vue -->
    <script src="../js/vue.js"></script>
    <style>
        .basic{
            width: 200px;
            height: 200px;
        }
    </style>
</head>
<body>
  <!-- 2.准备一个容器 -->
  <div id="root">
      <div class="basic" :style="style1">{{name}}</div>
  </div>
  <script>
    //3.创建Vue实例
    const vm = new Vue({
        el:'#root',
        data:{
            name:'Vue',
            style1: {
                fontSize: '40px',
                color: 'red'
            },
            style2: {
                backgroundColor: 'orange',
            }
        },
    });
  </script>
</body>
</html>

对象式2

:style="{ color: activeColor, fontSize: fontSize + 'px' }"

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue初体验</title>
    <!-- 1.引入Vue -->
    <script src="../js/vue.js"></script>
    <style>
        .basic{
            width: 200px;
            height: 200px;
        }
    </style>
</head>
<body>
  <!-- 2.准备一个容器 -->
  <div id="root">
      <div class="basic" :style="{color:fontColor,fontSize:size + 'px'}">{{name}}</div>
  </div>
  <script>
    //3.创建Vue实例
    const vm = new Vue({
        el:'#root',
        data:{
            name:'Vue',
            fontColor: 'orange',
            size: 30
        },
    });
  </script>
</body>
</html>

数组式

:style = '[{backgroundColor: 'orange'},{color: 'red'}]'

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue初体验</title>
    <!-- 1.引入Vue -->
    <script src="../js/vue.js"></script>
    <style>
        .basic{
            width: 200px;
            height: 200px;
        }
    </style>
</head>
<body>
  <!-- 2.准备一个容器 -->
  <div id="root">
      <div class="basic" :style="styleArr">{{name}}</div>
  </div>
  <script>
    //3.创建Vue实例
    const vm = new Vue({
        el:'#root',
        data:{
            name:'Vue',
            styleArr:[
                {
                    width:'200px',
                    height:'200px',
                    background:'red',
                },
                {
                    fontSize:'20px',
                    color:'blue',
                }
            ]
        },
    });
  </script>
</body>
</html>

条件渲染

v-if 与 v-else

写法:

  1. v-if=“表达式”
  2. v-else-if=“表达式”
  3. v-else=“表达式”

使用场景

  • 切换频率较低的场景。

特点

  • 不展示的DOM元素直接被移除。

案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue初体验</title>
    <!-- 1.引入Vue -->
    <script src="../js/vue.js"></script>
</head>
<body>
  <!-- 2.准备一个容器 -->
  <div id="root">
        <h1>当前n的值是:{{n}}</h1>
      <button @click="n++">n+1</button>
      <button @click="n--">n-1</button>
      <!-- 浏览器F12查看源码 -->
      <p v-if="n === 1">百度</p>
      <p v-if="n === 2">360</p>
      <p v-if="n === 3">谷歌</p>
      <hr>
      <p v-if="n === 1">诺克萨斯</p>
      <p v-else-if="n === 2">艾欧尼亚</p>
      <p v-else-if="n === 3">皮尔特沃夫</p>
      <p v-else>德玛西亚</p>
  </div>
  <script>
    //3.创建Vue实例
    const vm = new Vue({
        el:'#root',
        data:{
            name:'百度',
            n:0,
        },
    });
  </script>
</body>
</html>

v-show

写法

  • v-show=“表达式”

使用场景

  • 切换频率较高的场景。

特点

  • 不展示的DOM元素会将display属性设置为none。

案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue初体验</title>
    <!-- 1.引入Vue -->
    <script src="../js/vue.js"></script>
</head>
<body>
  <!-- 2.准备一个容器 -->
  <div id="root">
      <h1 v-show="isShow">{{name}}</h1>
      <button @click="isShow = !isShow">切换</button>
  </div>
  <script>
    //3.创建Vue实例
    const vm = new Vue({
        el:'#root',
        data:{
            name:'百度',
            isShow: true
        },
    });
  </script>
</body>
</html>

总结

  • v-if可以和:v-else-if、v-else一起使用,但要求结构不能被“打断”。
  • v-if可以搭配template使用,不影响页面布局(注意和v-show使用 v-show会失效)
  • 使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到

比较 v-if 与 v-show

  1. 如果需要频繁切换 v-show 较好
  2. 当条件不成立时, v-if 的所有子节点不会解析(项目中使用)

列表渲染

v-for的基本使用

  • 用于展示列表数据

语法

  • v-for="(item, index) in xxx" :key=“yyy”

使用

  • 可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
  • v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名(形参)。
  • v-for 还支持一个可选的第二个参数,即当前项的索引。
  • 可以用 of 替代 in 作为分隔符,因为它更接近 JavaScript 迭代器的语法:
    • 数组: (item, index)
    • 对象: (value, key)
    • 字符串:(char, index)
    • 数字:(number, index)

案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue初体验</title>
    <!-- 1.引入Vue -->
    <script src="../js/vue.js"></script>
</head>
<body>
  <!-- 2.准备一个容器 -->
  <div id="root">
      <h1>数组遍历</h1>
      <table cellpadding="0" cellspacing="0" border="1">
          <thead>
              <th width="100px">ID</th>
              <th width="100px">姓名</th>
              <th width="100px">年龄</th>
          </thead>
          <tr v-for="(p,index) in persons" :key="p.id" align="center">
              <td>{{p.id}}</td>
              <td>{{p.name}}</td>
              <td>{{p.age}}</td>
          </tr>
      </table>
      <h1>对象遍历</h1>
      <ul>
          <li v-for="(value,key) in cars" :key="key">
              {{key}}:{{value}}
          </li>
      </ul>
      <h1>字符串遍历</h1>
      <ul>
          <li v-for="(value,index) in words" :key="index">
              {{value}}
          </li>
      </ul>
      <h1>数字遍历</h1>
      <ul>
          <li v-for="(value,index) in 10" :key="index">
              {{value}}
          </li>
      </ul>
  </div>
  <script>
    //3.创建Vue实例
    const vm = new Vue({
        el:'#root',
        data:{
            persons:[
                {id:1,name:'张三',age:18},
                {id:2,name:'李四',age:19},
                {id:3,name:'王五',age:20},
            ],
            cars: {
                id:1,
                name:'奔驰',
                price:100000,
                color:'黑色'
            },
            words: 'Hello Vue'
        },
    });
  </script>
</body>
</html>

key的原理

  • 有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误

面试题(key的内部原理)

虚拟DOM中key的作用:

是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,
随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,

对比规则:

  • 旧虚拟DOM中找到了与新虚拟DOM相同的key:
    • 若虚拟DOM中内容没变, 直接使用之前的真实DOM!
    • 若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
  • 旧虚拟DOM中未找到与新虚拟DOM相同的key创建新的真实DOM,随后渲染到到页面。

用index作为key可能会引发的问题

  • 若对数据进行:逆序添加、逆序删除等破坏顺序操作:会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。
  • 如果结构中还包含输入类的DOM:会产生错误DOM更新 ==> 界面有问题。

开发中如何选择key?

  • 最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
  • 如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。
  • 如果不写key,则默认为index

案例展示

列表渲染, 若key指定为index,当在li前面插入一个新的li li右侧的input输入框会发生错乱,输入框的数据会对不上号:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue初体验</title>
    <!-- 1.引入Vue -->
    <script src="../js/vue.js"></script>
</head>
<body>
  <!-- 2.准备一个容器 -->
  <div id="root">
      <button @click="persons.unshift({id:4,name:'赵六',age:21})">往数组的前面添加一个对象</button>
      <p v-for="(item,index) in persons"><!-- 不写:key默认使用index渲染 -->
          <input type="checkbox"> {{item.id}}-{{item.name}} - {{item.age}}
      </p>
      <hr>
      <p v-for="(item,index) in persons" :key="item.id">
          <input type="checkbox"> {{item.id}}-{{item.name}} - {{item.age}}
      </p>
  </div>
  <script>
    //3.创建Vue实例
    const vm = new Vue({
        el:'#root',
        data:{
            persons:[
                {id:1,name:'张三',age:18},
                {id:2,name:'李四',age:19},
                {id:3,name:'王五',age:20},
            ]
        },
    });
  </script>
</body>
</html>

【Vue】Vue的核心-LMLPHP

【Vue】Vue的核心-LMLPHP

列表过滤

用computed实现(推荐):

实现思路:计算属性fillPersons的值受keyWord的值变化而变化

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue初体验</title>
    <!-- 1.引入Vue -->
    <script src="../js/vue.js"></script>
</head>
<body>
  <!-- 2.准备一个容器 -->
  <div id="root">
      <input type="text" v-model="keyWord">
      <ul>
          <li v-for="(p,index) of filPersons" :key="index">
              {{p.name}} - {{p.age}}
          </li>
      </ul>
  </div>
  <script>
    //3.创建Vue实例
    const vm = new Vue({
        el:'#root',
        computed:{
            filPersons(){
                return this.persons.filter((p)=>{
                    return p.name.indexOf(this.keyWord) !== -1
                })
            }
        },
        data:{
            keyWord:'',
            persons:[
                {id:1,name:'张三',age:18,sex:'男'},
                {id:2,name:'李四',age:19,sex:'女'},
                {id:3,name:'王五',age:20,sex:'女'},
                {id:3,name:'赵六',age:22,sex:'男'},
            ]
        },
    });
  </script>
</body>
</html>

用watch实现(比较麻烦)

实现思路:监听输入框的数据变化,使用过滤方法迭代数据,筛选数据后重新渲染li
注意indexOf()方法搜索空串会返回0,所以任何数据都会通过筛选,设置watch初始调用可解决数据第一次更新为控问题

列表排序

  • 在之前的列表的基础上添加年龄升序、降序、原序功能:

实现思路

  • 对之前过滤剩下的数据进行判断操作,
  • 计算属性的强大之处在于其内部每一个数据的改变都会触发计算属性
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue初体验</title>
    <!-- 1.引入Vue -->
    <script src="../js/vue.js"></script>
</head>
<body>
  <!-- 2.准备一个容器 -->
  <div id="root">
      <input type="text" v-model="keyWord">
      <button @click="sortType = 2 ">年龄升序</button>
      <button @click="sortType = 1 ">年龄降序</button>
      <button @click="sortType = 0 ">复原</button>
      <ul>
          <li v-for="(p,index) of filPersons" :key="index">
              {{p.name}} - {{p.age}}
          </li>
      </ul>
  </div>
  <script>
    //3.创建Vue实例
    const vm = new Vue({
        el:'#root',
        computed:{
            filPersons(){
                const arr = this.persons.filter(p=>{
                    return p.name.indexOf(this.keyWord) !== -1;
                });
                //判断是否排序
                if (this.sortType !== 0){
                    arr.sort((p1,p2)=>{
                        if(p1.age - p2.age < 0){
                            console.log(p1.age + "小于" + p2.age + "调换位置")
                        }else if(p1.age - p2.age > 0){
                            console.log(p1.age + "大于" + p2.age + "位置不变")
                        }else {
                            console.log(p1.age + "等于" + p2.age + "位置不变")
                        }
                        return this.sortType === 1 ? p2.age - p1.age : p1.age - p2.age;
                    });
                }
                return arr;
            }
        },
        data:{
            keyWord:'',
            sortType:0,
            persons:[
                {id:1,name:'张三',age:20,sex:'男'},
                {id:2,name:'李四',age:18,sex:'女'},
                {id:3,name:'王五',age:19,sex:'女'},
                {id:3,name:'赵六',age:22,sex:'男'},
            ]
        },
    });
  </script>
</body>
</html>

补充

  • sort函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。
  • 比较函数应该具有两个参数 a 和 b,其返回值如下:
    • 若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。
    • 若 a 等于 b,则返回 0。
    • 若 a 大于 b,则返回一个大于 0 的值。

收集表单数据

  • 若:type=text、password、number,则v-model默认收集的是value值,用户输入的就是value值。
  • 若:type=radio,则v-model默认收集的是value值,因为此类型无法输入内容,则无法通过输入得到value值,所以要给标签手动添加value值。
  • 若:type=checkbox
    • 没有配置input的value属性,那么默认读取的的就是checked是否被勾选(勾选 or 未勾选,是布尔值)
    • 配置input的value属性:
      • v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)
      • v-model的初始值是数组,那么收集的的就是value组成的数组
  • 备注:v-model的三个修饰符:
    • lazy:失去焦点再收集数据
    • number:输入字符串转为有效的数字
    • trim:输入首尾空格过滤
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>初识VUE</title>
		<!-- 1.引入VUE.js -->
		<script src="../js/vue.js"></script>
	</head>
	<body>
		<!-- 2.准备一个容器 -->
		<div id="root">
			<form @submit.prevent="tijiao">
				<p>
					 账号:<input type="text" v-model="userInfo.userCode">
				</p>
				<p>
					 姓名:<input type="text" v-model="userInfo.userName">
				</p>
				<p>
					 密码:<input type="password" v-model="userInfo.userPassword">
				</p>
				<p>
					 性别:
					 <input type="radio" name="sex" v-model="userInfo.sex" value="0"><input type="radio" name="sex" v-model="userInfo.sex" value="1"></p>
				<p>
					 生日:<input type="date" v-model="userInfo.birthday">
				</p>
				<p>
					 爱好:
					 <input type="checkbox" name="hobby" v-model="userInfo.hobby" value="c">唱歌
					 <input type="checkbox" name="hobby" v-model="userInfo.hobby" value="t">跳舞
					 <input type="checkbox" name="hobby" v-model="userInfo.hobby" value="r">rap
					 <input type="checkbox" name="hobby" v-model="userInfo.hobby" value="l">打篮球
				</p>
				<p>
					 住址:
					 <select  v-model="userInfo.address">
						 <option value="0">--请选择--</option>
						 <option value="1">--金水区--</option>
						 <option value="2">--惠济区--</option>
						 <option value="3">--二七区--</option>
					 </select>
				</p>
				<p>
					 介绍:<textarea v-model="userInfo.desc"></textarea>
				</p>
				<p>
					 <input type="submit" value="提交">
				</p>
			</form>
			
			<p v-for="(value,name) in userInfo">
				{{name}}:{{value}}
			</p>
		</div>
	</body>
	
	<script>
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
		//3.创建VUE实例
		var vm = new Vue({
			el: "#root",//指定容器名称
			
			data(){ //页面数据模板
				return{
					userInfo:{
						userCode:'',
						userName:'',
						userPassword:'',
						sex:0,
						birthday:'',
						hobby:[],
						address:0,
						desc:''
					}
				}
			},
			methods:{
				tijiao(){
					console.info(JSON.stringify(this.userInfo))
				}
			}
		});
	</script>
</html>

过滤器(filter)

对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)

语法:

  1. 注册过滤器:Vue.filter(name,callback) new Vue{filters:{}}
  2. 使用过滤器:{{ xxx | 过滤器名}} v-bind:属性 = "xxx | 过滤器名",所以要给标签手动添加value值。

备注:v-model的三个修饰符:

  1. 过滤器也可以接收额外参数、多个过滤器也可以串联
  2. 并没有改变原本的数据, 是产生新的对应的数据
  3. 不是必须的属性,完全可以用methods和computed实现下面代码中的过滤功能
  4. 当全局过滤器和局部过滤器重名时,会采用局部过滤器。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Vue初体验</title>
    <!-- 1.引入Vue -->
    <script src="../js/vue.js"></script>
</head>
<body>
  <!-- 2.准备一个容器 -->
  <div id="root">
      <h1>未过滤:{{name}}</h1>
      <h1>过滤:{{name | myFilter}}</h1>
  </div>
  <script>
      Vue.filter('myFilter',function (value) {
          return value.slice(0,4)
      })
    //3.创建Vue实例
    const vm = new Vue({
        el:'#root',
        data:{
            name:'Hello Vue',
        },
    });
  </script>
</body>
</html>
05-11 13:07