【Vue】Vue的核心

news2024/10/5 13:02:30

目录

  • 计算属性-computed
    • 插值语法实现
    • methods实现
    • 计算属性实现
      • 使用
      • 使用总结:
  • 监视属性-watch
    • 监视的两种写法:
    • 深度监视
      • 备注:
    • computed和watch之间的区别
  • 绑定样式
    • class样式绑定
      • 字符串写法
      • 数组写法
      • 对象写法
  • style样式绑定
    • 对象式1
    • 对象式2
    • 数组式
  • 条件渲染
    • v-if 与 v-else
      • 写法:
      • 使用场景
      • 特点
      • 案例
    • v-show
      • 写法
      • 使用场景
      • 特点
      • 案例
    • 总结
      • 比较 v-if 与 v-show
  • 列表渲染
    • v-for的基本使用
      • 语法
      • 使用
      • 案例
    • key的原理
    • 面试题(key的内部原理)
      • 虚拟DOM中key的作用:
      • 对比规则:
      • 用index作为key可能会引发的问题
      • 开发中如何选择key?
      • 案例展示
  • 列表过滤
    • 用computed实现(推荐):
    • 用watch实现(比较麻烦)
  • 列表排序
    • 实现思路
    • 补充
  • 收集表单数据
  • 过滤器(filter)
    • 语法:
    • 备注:v-model的三个修饰符:

计算属性-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将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>

在这里插入图片描述

  • 多数情况下计算属性只考虑读取,不考虑修改,因此可以把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>

在这里插入图片描述

在这里插入图片描述

列表过滤

用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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1662425.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

探索GitHub上的GPTs项目:泄露和被破解的GPT提示

GPTs项目是一个在GitHub上由用户linexjlin发起的开源项目&#xff0c;专注于提供泄露的GPT&#xff08;生成式预训练转换器&#xff09;提示。这些提示用于指导和优化AI模型的输出&#xff0c;进而提升代码生成的质量和效率。项目页面提供了丰富的功能和资源&#xff0c;旨在帮…

【C++】CentOS环境搭建-升级CMAKE

【C】CentOS环境搭建-升级CMAKE CMAKE报错CMake 3.12 or higher is required. You are running version 2.8.12.2升级步骤1.移除当前的cmake2.安装必要的构建工具和库3.下载最新的cmake源码并解压5.编译和安装6.验证安装 CMAKE报错CMake 3.12 or higher is required. You are r…

hypack如何采集多波束数据?(上)

多波束设备有3种&#xff1a;多波束阵列&#xff0c;比如Seabat T50P&#xff1b;相干声纳&#xff0c;比如EdgeTeck 6205&#xff1b;多个单波束并列&#xff0c;比如Ross Sweep System&#xff0c;见下图。 辅助传感器主要有&#xff1a;罗经&#xff08;提供航向&#xff09…

Linux 进程间通信 System V系列: 共享内存,信号量,简单介绍消息队列

进程间通信 System V系列: 共享内存,初识信号量 一.共享内存1.引入2.原理3.系统调用接口1.shmget2.shmat和shmdt3.shmctl 4.边写代码边了解共享内存的特性1.ftok形成key,shmget创建与获取共享内存2.shm相关指令3.shmat和shmdt挂接和取消挂接4.shmctl获取共享内存信息,释放共享内…

org.hsqldb.jdbcDriver 类,导致 ClassNotFoundException 异常如何解决?

确保JDBC驱动包存在&#xff1a;检查系统是否已经安装了HSQLDB JDBC驱动。如果没有安装或驱动没有正确放置在类路径中&#xff0c;需要下载并添加它。你可以从 HSQLDB官网 下载JDBC驱动包。 添加JDBC驱动到类路径&#xff1a;将下载的HSQLDB JDBC驱动&#xff08;通常是一个JA…

【ArcGISProSDK】condition属性

示例 通过caption属性可以看出esri_mapping_openProjectCondition的条件是一个工程被打开 condition的作用 由此可知示例中的Tab实在工程被打开才能使用&#xff0c;否则他禁用显示灰色&#xff0c;在未禁用的时候说明条件满足。 参考文档 insertCondition 元素 (arcgis.com…

西门子PLC定时器使用与疑难杂症

一、简介 S7-200提供了256个定时器&#xff0c;依据分辨率分三种类型&#xff1a;1ms&#xff0c;10ms和100ms&#xff1b;依据功能分为接通延时定时器&#xff08;TON&#xff09;、有记忆的接通延时定时器&#xff08;TONR)和断开延时定时器&#xff08;TOF)。 接通延时定时…

Promise魔鬼面试题

文章目录 题目解析难点分析分析输出step1step2step3step4step5step6 参考/致谢&#xff1a;渡一袁老师 题目 Promise.resolve().then(() > {console.log(0);return Promise.resolve(4);}).then((res) > {console.log(res);});Promise.resolve().then(() > {console.l…

MFC中关于CMutex类的学习

MFC中关于CMutex类的学习 最近在项目中要实现两个线程之间的同步&#xff0c;MFC中提供了4个类&#xff0c;分别是CMutex(互斥量)、CCriticalSection(临界区)、CEvent(事件对象)、CSemaphore(信号量)。有关这4个类的说明&#xff0c;大家可以参考微软官方文档&#xff1a; CM…

MySQL的表级锁

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;面经 ⛺️稳中求进&#xff0c;晒太阳 表级锁 介绍 对于表锁&#xff0c;分为两类&#xff1a; 表共享读锁表独占写锁 语法 1. 加锁&#xff1a;lock tables 表名... read/write 2.…

第十三届蓝桥杯决赛(国赛)真题 Java A 组【原卷】

文章目录 发现宝藏【考生须知】试题 A: 火柴棒数字试题 B: 小蓝与钥匙试题 C: 内存空间试题 D: 斐波那契数组试题 E: 交通信号试题 F: 数组个数试题 G: 六六大顺试题 H : \mathrm{H}: H: 选素数试题 I: 图书借阅试题 J \mathrm{J} J : 括号序列树 发现宝藏 前些天发现了一个…

代码随想录——二叉树的层序遍历Ⅱ(Leetcode107)

题目链接 层序遍历&#xff08;队列&#xff09; /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, Tre…

springboot整合redis多数据源(附带RedisUtil)

单数据源RedisUtil(静态) 单数据源RedisUtil,我这里implements ApplicationContextAware在setApplicationContext注入redisTemplate,工具类可以直接类RedisUtil.StringOps.get()使用 package com.vehicle.manager.core.util;import com.alibaba.fastjson.JSON; import lombok.e…

嵌入式学习70-复习(wireshark使用和http协议)

--------------------------------------------------------------------------------------------------------------------------------- wireshark 1.sudo wireshark 2.选择 any &#xff0c; 3.搜索 http/tcp 54 为 发送的数据包 58 回复的数据包 请求报文 请求报文…

【C++】CentOS环境搭建-安装log4cplus日志组件包及报错解决方案

log4cplus简介 log4cplus是C编写的开源的日志系统&#xff0c;前身是java编写的log4j系统&#xff0c;受Apache Software License保护&#xff0c;作者是Tad E. Smith。 log4cplus具有线程安全、灵活、以及多粒度控制的特点&#xff0c;通过将日志划分优先级使其可以面向程序…

IQOO Neo7/7SE/PAD2解BL+完美root权限+LSPosed框架-可虚拟定位

QOO Neo7/Neo7SE/Pad/Pad2搭配的是天玑8200系列芯片&#xff0c;继810/920以后再次支持解锁BL&#xff0c;这给我们的玩机带来了很多可能。解锁BL有什么用途呢&#xff1f;最常见的就是获取root权限&#xff0c;刷入各种各种的magisk模块&#xff0c;使用自己喜欢的插件等&…

【初阶数据结构】顺序表OJ题讲解

前言 &#x1f4da;作者简介&#xff1a;爱编程的小马&#xff0c;正在学习C/C&#xff0c;Linux及MySQL。 &#x1f4da;本文收录与初阶数据结构系列&#xff0c;本专栏主要是针对时间、空间复杂度&#xff0c;顺序表和链表、栈和队列、二叉树以及各类排序算法&#xff0c;持…

macOS Sonoma 无法打开分段式Dmg文件的解决办法

在macOS Sonoma 14.X及更高版本的系统中&#xff0c;用户可能会遇到一个棘手的问题&#xff1a;无法直接打开“分段式”DMG&#xff08;磁盘映像&#xff09;安装包文件。这种情况通常发生在尝试安装一些大型软件或游戏时&#xff0c;尤其是那些因为文件体积巨大而采用分段压缩…

(Java)心得:LeetCode——15.三数之和

一、原题 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元组。…

带有-i选项的sed命令在Linux上执行成功,但在MacOS上失败了

问题&#xff1a; 我已经成功地使用以下 sed 命令在Linux中搜索/替换文本&#xff1a; sed -i s/old_string/new_string/g /path/to/file然而&#xff0c;当我在Mac OS X上尝试时&#xff0c;我得到&#xff1a; command i expects \ followed by text我以为我的Mac运行的是…