初学Vue(2)

文章目录

  • 监视属性 watch
    • 深度监视
    • computed 和 watch 之间的区别
  • 绑定样式(class style)
  • 条件渲染
  • 列表渲染
    • 基本列表
    • key的原理
    • 列表过滤
    • 列表排序
    • 收集表单中的数据 v-model
    • 过滤器(Vue3已移除)

监视属性 watch

  1. 当被监视的属性变化时,回调函数自动调用,进行相关操作
  2. 监视的属性必须存在,才能进行监视
  3. 监视的两种写法:
    a. new Vue时传入watch配置
    b. 通过vm.$watch监视
<body>
  <div id="root">
    <h2>今天天气很{{info}}</h2>
    <button @click="changeWeather">切换天气</button>
  </div>


</body>
<script type="text/javascript">
  Vue.config.productionTip = false;

  const vm = new Vue({
    el: '#root',
    data: {
      isHot: true
    },
    computed: {
      info() {
        return this.isHot ? '炎热' : '凉爽'
      }
    },
    methods: {
      changeWeather() {
        this.isHot = !this.isHot
      }
    },

    // 方法一:
    watch:{
      // 正常写法
      isHot: {
        immediate: true,  // 初始化时让handler调用一下
        // handler什么时候调用?当isHot发生改变时、
        handler(newValue, oldValue){
          console.log('newValue:', newValue);
          console.log('oldValue:', oldValue);
        },
      }

      // 简写
      isHot(newValue,oldValue){
        console.log('isHot被修改了')
      }
    }
  })

  // 方法二:
  // 正常写法
  vm.$watch('isHot',{
    immediate: true,  // 初始化时让handler调用一下
    // handler什么时候调用?当isHot发生改变时、
    handler(newValue, oldValue){
      console.log('newValue:', newValue);
      console.log('oldValue:', oldValue);
    },
  })

  // 简写
  vm.$watch('isHot',(newValue,oldValue){
    console.log('isHot被修改了',newValue)
  })
</script>

深度监视

  1. Vue中的Watch默认不监测对象内部值的改变(一层)
  2. 配置deep:true可以监测对象内部值改变(多层)
  3. 备注:
    a. Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以
    b. 使用watch时数据的具体结构,决定是否采用深度监视
<body>
    <div id="root">
        <h2>今天天气很{{info}}</h2>
        <button @click="changeWeather">切换天气</button>
        <hr>
        <h3>a的值是:{{numbers.a}}</h3>
        <button @click="numbers.a++">点我让a+1</button>
        <br>
        <h3>b的值是:{{numbers.b}}</h3>
        <button @click="numbers.b++">点我让b+1</button>
    </div>
</body>
<script type="text/javascript">
    Vue.config.productionTip = false;

    const vm = new Vue({
        el: '#root',
        data: {
            isHot: true,
            numbers:{
                a: 1,
                b: 1
            }
        },
        computed: {
            info() {
                return this.isHot ? '炎热' : '凉爽'
            }
        },
        methods: {
            changeWeather() {
                this.isHot = !this.isHot
            }
        },
        watch:{
            isHot: {
                // immediate: true,  // 初始化时让handler调用一下
                // handler什么时候调用?当isHot发生改变时、
                handler(newValue, oldValue){
                    console.log('newValue:', newValue);
                    console.log('oldValue:', oldValue);
                },
            },
            // 监视多级结构中某个属性的变化
            'numbers.a':{
                // deep: true,
                handler(){
                    console.log('a被改变了');
                },
            },

            // 监视多级结构中所有属性的变化
            numbers: {
                deep: true,
                handler() {
                    console.log('a被改变了');
                },
            }

          // 简写
          vm.$watch('isHot',{
            
          })
        }
    })
</script>

computed 和 watch 之间的区别

  1. computed能完成的功能,watch都可以完成
  2. watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作
    两个重要的小原则:
  3. 所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象
  4. 所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象

绑定样式(class style)

  1. class样式
    写法:class=“xxx” xxx可以是字符串、对象、数组
    字符串写法适用于:类名不确定,要动态获取
    对象写法适用于:要绑定多个样式,个数不确定,名字也不确定
    数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用
  2. style样式
    :style=“{fontSize:xxx}” 其中xxx是动态值
    :style=“[a,b]” 其中a、b是样式对象
<div id="root">
  <!-- 绑定class样式--字符串写法,适用于:样式的类名不确定,需要动态绑定 -->
  <div class="basic" :class="mood" @click="changeMood">{{name}}</div><br><br>
  <!-- 绑定class样式--数组写法,适用于:样式个数不确定、类名也不确定 -->
  <div class="basic" :class="arr" @click="changeMood">{{name}}</div> <br><br>
  <!-- 绑定class样式--对象写法,适用于:要绑定的样式确定,类名也确定,但要动态决定用不用 -->
  <div class="basic" :class="arr" @click="changeMood">{{name}}</div><br><br>
  <!-- 绑定style样式,对象写法 -->
  <div class="basic" :style="styleObj">{{name}}</div><br><br>
  <!-- 绑定style样式,数组写法 -->
  <div class="basic" :style="styleArr">{{name}}</div>
</div>

<script type="text/javascript">
  Vue.config.productionTip = false;  // 阻止vue在启动时自动生产提示

  new Vue({
    el: '#root',
    data: {
      name: '檀健次',
      mood: 'normal',
      arr: ['attjc1', 'attjc2', 'attjc3'],
      classObj: {
        attjc1: false,
        attjc2: true,
        attjc3: true
      },
      styleObj: {
        color: 'white',
        backgroundColor: 'orange'
      },
      styleArr: [
        {
          fontSize: '30px'
        }
      ]
    },
    methods: {
      changeMood() {
        // this.mood = 'happy'
        const arr = ['happy', 'sad', 'normal']
        this.mood = arr[Math.floor(Math.random() * arr.length)]
      }
    }
  })
</script>

条件渲染

  1. v-if
    写法:
    (1) v-if=“表达式”
    (2) v-else-if=“表达式”
    (3) v-else=“表达式”
    适用于:切换频率较低的场景
    特点:不展示的DOM元素直接被移除
    注意:v-if可以和:v-else-is、v-else一起使用,但要求结构不能被打断
  2. v-show
    写法:v-show=“表达式”
    适用于:切换频率较高的场景
    特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
  3. 备注:使用v-if的时候,元素可能无法获取到,而使用v-show一定可以获取到
<div id="root">
  <h2>当前值是:{{n}}</h2>
  <button @click="n++">点我n+1</button>

  <!-- 使用v-show做条件渲染 -->
  <!-- <h2 v-show="true">要见{{name}}</h2>
  <h2 v-show="1 === 1">要见{{name}}</h2> -->

  <!-- 使用v-if做条件渲染 -->
  <!-- <h2 v-if="false">要见{{name}}</h2>
  <h2 v-if="1 === 1">要见{{name}}</h2> -->

  <!-- v-else-if 和 v-else -->
  <div v-if="n === 1">tjc</div>
  <div v-else-if="n === 2">txd</div>
  <div v-else-if="n === 3">tlq</div>
  <div v-else>哈哈</div>
</div>

<script type="text/javascript">
  Vue.config.productionTip = false;  // 阻止vue在启动时自动生产提示

  new Vue({
    el: '#root',
    data: {
      name: '檀健次',
      n: 1
    }
  })
</script>

列表渲染

基本列表

v-for指令

  1. 用于展示列表数据
  2. 语法:v-for=“(item,index) in xxx” :key=“yyy”
  3. 可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
<div id="root">
  <!-- 遍历数组 -->
  <h2>人员列表(遍历数组)</h2>
  <ul>
    <li v-for="(p,index) in persons" :key="index">
      {{p.name}}--{{p.age}}
    </li>
  </ul>
  <!-- 遍历对象 -->
  <h2>汽车信息</h2>
  <ul>
    <li v-for="(value,k) of car" :key="k">
      {{value}}--{{k}}
    </li>
  </ul>
  <!-- 遍历指定次数 -->
  <h2>循环指定次数</h2>
  <ul>
    <li v-for="n in 5" :key="n">
      {{n}}
    </li>
  </ul>
</div>

<script type="text/javascript">
  Vue.config.productionTip = false;  // 阻止vue在启动时自动生产提示

  new Vue({
    el: '#root',
    data: {
      persons:[
        {id: '001',name: '张三',age: 18}
        ,{id: '002',name: '李四',age: 19}
        ,{id: '003',name: '王五',age: 20}
      ],
      car:{
        name: '奔驰',
        price: '100万',
        color: '黑色'
      }
    }
  })
</script>

key的原理

样式

  1. 虚拟DOM中key的作用:
    key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】 ,随后Vue进行【新虚拟DOM】与【旧DOM】的差异比较,比较规则如下:
  2. 对比规则:
    a. 旧虚拟DOM中内容没变,直接使用之前的真实DOM
    ⅰ. 若虚拟DOM中内容没变,直接使用之前的真实DOM
    ⅱ. 若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM
    b. 旧虚拟DOM中未找到与新虚拟DOM相同key,创建新的真实DOM,随后渲染到页面
  3. 用index作为key可能会引发的问题:
    a. 若对数据进行:逆序添加、逆序删除等破坏顺序操作:
    b. 如果结构中还包含输入类DOM:会产生错误DOM更新==> 界面有问题
  4. 开发中如何选择key?:
    a. 最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值
    b. 如果不存在对数据的逆序添加、逆序删除等破坏顺序的操作,仅用于渲染列表用于展示,使用index作为key是没有问题的

列表过滤

<div id="root">
  <!-- 遍历数组 -->
  <h2>人员列表</h2>
  <input type="text" placeholder="请输入名字" name="" id="" v-model="keyWord">
  <ul>
    <li v-for="(p,index) in filPersons" :key="index">
      {{p.name}}--{{p.age}}
    </li>
  </ul>
</div>

<script type="text/javascript">
  Vue.config.productionTip = false;  // 阻止vue在启动时自动生产提示

  // 用watch实现
  new Vue({
    el: '#root',
    data: {
      keyWord: '',
      persons: [
        { id: '001', name: '檀健次', age: 18 }
        , { id: '002', name: '赵丽颖', age: 19 }
        , { id: '003', name: '成毅', age: 20 }
      ],
      filPersons: []
    },
    watch: {
      keyWord: {
        immediate: true,
        handler(val) {
          this.filPersons = this.persons.filter((p) => {
            return p.name.indexOf(val) !== -1
          })
        }
      }
    }
  })

  // 用computed实现
  new Vue({
    el: '#root',
    data: {
      keyWord: '',
      persons: [
        { id: '001', name: '檀健次', age: 18 }
        , { id: '002', name: '赵丽颖', age: 19 }
        , { id: '003', name: '成毅', age: 20 }
      ]
    },
    computed:{
      filPersons(){
        return this.persons.filter((p) => {
          return p.name.indexOf(this.keyWord) !== -1
        })
      }
    }
  })
</script>

列表排序

<div id="root">
  <!-- 遍历数组 -->
  <h2>人员列表</h2>
  <input type="text" placeholder="请输入名字" name="" id="" v-model
上一篇:性能测试学习2:常见的性能测试策略(基准测试/负载测试/稳定性测试/压力测试/并发测试)


下一篇:Qt之TCP收发图片的例子-二.实现