【Vue】Vue的核心

目录

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

5/11后面部分:+顺序排序+元素交换+计算每门课程的各种成绩+存放规律的数据 注意:一味的复制肯定要出问题,第2个的最后一部分有修改,注意观察

目录 第一个已经输出过一次&#xff1a; 第二个: 编程实现&#xff1a;程序功能是用起泡法对数组中n个元素按从大到小的顺序进行排序。 ​编辑的确出现了一些问题哦&#xff1a; ​编辑目前是可以运行&#xff0c;但AI不给我们通过&#xff1a; 最后还是我的代码获胜&#x…

网络安全专业岗位详解+自学学习路线图

很多网安专业同学一到毕业就开始迷茫&#xff0c;不知道自己能去做哪些行业&#xff1f;其实网络安全岗位还是蛮多的&#xff0c;下面我会介绍一些网络安全岗位&#xff0c;大家可以根据自身能力与喜好决定放哪个方向发展。 渗透测试/Web安全工程师 主要是模拟黑客攻击&#…

vue3 antd-vue 超简单方式实现a-table跨页勾选

一、效果如下&#xff1a; 第一页勾选了2&#xff0c; 3&#xff0c; 4 翻到第三页勾选24&#xff0c; 25 回显&#xff0c;如比返回第一页的时候触发分页改变&#xff0c; 在映射中的第一页的数据给到a-table绑定的state.selectedRowKeys即可&#xff0c;如下方法 二、勾选思路…

初识多线程

1. 前置知识——进程 在学习多线程前需要了解操作系统中的基本知识&#xff0c;这里简单回顾下。 1.1 进程控制块 一个进程对应着一个进程控制块PCB&#xff0c;PCB是一个用于管理和维护进程信息的数据结构&#xff0c;这个数据结构中大致包含下面内容&#xff08;并不完整&…

头歌实践教学平台:CG1-v1.0-点和直线的绘制

第1关&#xff1a;OpenGL点的绘制 一. 任务描述 根据下面要求&#xff0c;在右侧修改代码&#xff0c;绘制出预期输出的图片。平台会对你编写的代码进行测试。 1.本关任务 熟悉编程环境&#xff1b; 了解光栅图形显示器的特点&#xff1b; 了解计算机绘图的特点&#xff1b…

Redis是单线程吗?为什么6.0之后引入了多线程?

Redis是单线程吗&#xff1f;为什么6.0之后引入了多线程&#xff1f; Redis 是单线程吗&#xff1f;Redis 单线程模式是怎样的&#xff1f;Redis 采用单线程为什么还这么快&#xff1f;Redis 6.0 之前为什么使用单线程&#xff1f;Redis 6.0 之后为什么引入了多线程&#xff1f…

geotrust dv通配符证书800

Geotrust是成立时间较久的正规CA认证机构&#xff0c;在过去的几十年间颁发了无数的SSL证书&#xff0c;这些SSL证书被各个开发者使用&#xff0c;受到大多数浏览器的信任。而Geotrust旗下的DV通配符证书因其广泛的应用范围受到了用户的青睐。今天就随SSL盾小编了解Geotrust旗下…

C语言(指针)2

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸各位能阅读我的文章&#xff0c;诚请评论指点&#xff0c;关注收藏&#xff0c;欢迎欢迎~~ &#x1f4a5;个人主页&#xff1a;小羊在奋斗 &#x1f4a5;所属专栏&#xff1a;C语言 本系列文章为个人学习笔记&#x…

XWiki 服务没有正确部署在tomcat中,如何尝试手动重新部署?

1. 停止 Tomcat 服务 首先&#xff0c;您需要停止正在运行的 Tomcat 服务器&#xff0c;以确保在操作文件时不会发生冲突或数据损坏&#xff1a; sudo systemctl stop tomcat2. 清空 webapps 下的 xwiki 目录和 work 目录中相关的缓存 删除 webapps 下的 xwiki 目录和 work …

游戏行业被攻击的原因、攻击种类及合适的服务器

很多游戏刚上线没多久就频繁遭到同行恶意攻击。在相关数据报告中&#xff0c;2023年上半年遭受DDoS攻击的行业中&#xff0c;游戏行业占到40%&#xff0c;而且攻击方式、攻击频率、攻击峰值呈明显上升趋势。很多充满创意的游戏开发公司刚才开发上线一个很有特色的产品&#xff…

Electron学习笔记(三)

文章目录 相关笔记笔记说明 五、界面1、获取 webContents 实例&#xff08;1&#xff09;通过窗口对象的 webContent 属性获取 webContent 实例&#xff1a;&#xff08;2&#xff09;获取当前激活窗口的 webContents 实例&#xff1a;&#xff08;3&#xff09;在渲染进程中获…

IDEA 好用的插件

图标插件&#xff1a;Atom Material Icons 此插件的作用就是更好的显示各种文件的类别&#xff0c;使之一目了然 汉化包 Chinese ​(Simplified)​ Language Pack / 中文语言包 作用就是 汉化 AI编码助手 GitHub Copilot AI编码助手&#xff1a;提示代码很好用 缺点&#xff1a…

H5 云商城 file.php 文件上传致RCE漏洞复现

0x01 产品简介 H5 云商城是一个基于 H5 技术的电子商务平台,旨在为用户提供方便快捷的在线购物体验。多平台适配:H5 云商城采用 H5 技术开发,具有良好的跨平台适配性。无论是在电脑、手机还是平板等设备上,用户都可以通过网页浏览器访问和使用云商城,无需安装额外的应用程…

CH340 RTS DTR引脚编程驱动OLED

运行结果 硬件连接&#xff08;在连接线上串接300R电阻&#xff09; 下面是c#实现代码 using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks;using uint8 System.Byt…

2024年数维杯B题完整代码和思路论文讲解与分析

2024数维杯数学建模完整代码和成品论文已更新&#xff0c;获取↓↓↓↓↓ https://www.yuque.com/u42168770/qv6z0d/bgic2nbxs2h41pvt?singleDoc# 2024数维杯数学建模B题45页论文和代码已完成&#xff0c;代码为全部问题的代码 论文包括摘要、问题重述、问题分析、模型假设、…

QT--2

Qt界面设计 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {//窗口相关设置this->resize(680,520);this->setFixedSize(680,520);this->setWindowTitle("Tim");this->setWindowFla…

【零基础】system generator①设置卡解析

1.在matlab中我们输入的是双精度浮点型数据&#xff0c;经过gateway后变成定点型。十六位十四个小数位&#xff0c;整个数据有十六位&#xff0c;其中十四位给了小数 2.fixed-point定点型&#xff1b;signed有符号&#xff1b;2’s comp补码 3.量化误差 truncate&#xff0c;舍…

Windows Server 2012 R2 新增D盘分区

我们经常搭建windows版本的游戏时会要在D盘上操作&#xff0c;今天就介绍下新的服务器如何新增一个D盘。 在"开始"图标右边有个”服务器管理器“&#xff0c;单击点开 点开服务器管理器后&#xff0c;点击“工具”打开“计算机管理” 打开计算机管理后点击“存储”-…

【c++】string深度刨析以及实现

#pragma once #include<iostream> using namespace std; #include<assert.h> namespace bite {class string{public://迭代器 //像指针 底层不一定是指针 typedef char* iterator;iterator begin(){return _str;}iterator end(){return _str _size;}//const 版本…

RERCS系统-WDA+BOPF框架实战例子 PART 2-新建Root的子节点Node Element

1、通过事务码 BOBF进入Business Object Browser&#xff08;业务对象浏览&#xff09;页面&#xff1b; 2、输入debug 进入编辑模式&#xff1b; 3、双击对应的业务对象进入Business Object Detail Browser即业务对象数据浏览器 在Node Structure的Root中新建需要的SubNode子…