美文网首页
vue重新起航(三)

vue重新起航(三)

作者: 阿龙哟 | 来源:发表于2018-10-26 11:27 被阅读0次

    class与style绑定

    用v-bind来绑定class和style

    对象语法

    1.class active是否存在取决于vue实例中的isActive变量,true则存在,false则无

    <div id="app" v-bind:class={active:isActive}></div>
    

    2.可与普通类名共存

     <div id="app" class='new' v-bind:class={active:isActive}></div>
    

    3.绑定数据对象不一定要内联在模板里

     <div id="app" :class="classObject"></div>
    
    data: {
            classObject: {
              isActive: true,
              textDanger:true
            }
          }
    

    4.可以绑定一个返回对象的计算属性

    <div id="app" :class="classObject"></div>
    
    computed: {
            classObject: function () {
              return {
                active: this.isActive && !this.error,
                'text-danger': this.error && this.error.type === 'fatal'
              }
            }
          }
    

    5.数组语法,v-bind+一个数组,数组里也可以使用对象语法

    <div id="app" :class="[activeClass,errorClass]"></div>
      <script>
        var vm = new Vue({
          el: '#app',
          data: {
            activeClass: 'active',
            errorClass:'text-danger'
          },
        })
      </script>
    

    三元表达式用于切换

    <div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
    

    绑定类名的语法同样可以用在组件上

    <my-component v-bind:class="{ active: isActive }"></my-component>
    

    绑定内联样式

    1.对象语法,将样式的值放到data里

    <div id="app" :style="{color:activeColor,fontSize:fontSize+'px'}"></div>
      <script>
        var vm = new Vue({
          el: '#app',
          data: {
            activeColor:'red',
            fontSize:20
          },
        })
      </script>
    

    当然也可以直接绑定一个对象

    <div id="app" :style="activeCss"></div>
      <script>
        var vm = new Vue({
          el: '#app',
          data: {
            activeCss: {
              color: 'red',
              fontSize: '20px'
            }
          },
        })
    

    2.也可以使用数组语法

     <div id="app" :style="[activeClass]"></div>
    

    条件渲染

    v-if

    <h1 v-if="ok">Yes</h1>
    <h1 v-else>No</h1>
    

    ok=true => Yes ok=false => No

    在<template>元素上使用v-if条件渲染分组,渲染结果不包括template

    <template v-if="ok">
      <h1>Title</h1>
      <p>Paragraph 1</p>
      <p>Paragraph 2</p>
    </template>
    

    v-else 紧跟v-if或v-else-if

    v-else-if


    用key管理可复用的元素

    vue会尽可能高效的渲染元素呢,通常会复用已有元素而不是重新渲染元素

     <template v-if="loginType === 'username'">
          <label>Username</label>
          <input placeholder="Enter your username">
        </template>
        <template v-else>
          <label>Email</label>
          <input placeholder="Enter your email address" >
        </template>
    

    发现切换template后,input不会被替换


    复用组件.gif

    但是给每个组件添加一个key加以区分,就可以替换了


    key管理复用组件.gif

    v-show

    <h1 v-show="ok">Hello!</h1>
    

    使用v-show的元素会始终被渲染并保留在DOM中,v-show只是简单地切换元素的CSS属性display
    v-show不支持template,也不支持v-else


    v-if和v-show的区别

    v-if,是惰性的,是真正的‘条件渲染’,只要条件为假,则什么也不做,知道条件为真时才开始渲染
    v-show不管初始条件是什么,元素始终会被渲染,单纯的切换css

    v-if有更高的切换开销,v-show有更高的初始渲染开销,频繁切换用v-show,运行条件很少改变,用v-if

    tip v-for 和v-if一起使用时,v-for比v-if具有更高的优先级


    列表渲染 v-for

    用v-for来进行条件渲染

    item in items 形式的特殊语法,items 是源数据数组并且 item 是数组元素迭代的别名。
    也接受index这个参数用来表示下标
    也可以使用item of items

     <div id="app">
        <li v-for='(item,index) in items'>
          {{index}}-{{item.text}}
        </li>
      </div>
    
      var vm = new Vue({
          el:'#app',
          data:{
            items: [
              {text:'你好'},
              {text:'中国'}
            ]
          }
        })
    
    image.png

    v-for 遍历对象 index 索引 key键名 item

    <div id="app">
        <li v-for='(value,key,index) in object'>
          {{index}}-{{key}}-{{value}}
        </li>
      </div>
    
    var vm = new Vue({
          el: '#app',
          data: {
            object: {
              firstName: 'John',
              lastName: 'Doe',
              age: 30
            }
          }
        })
    

    v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。所以用v-for时要提供一个key,key值是每项都有的唯一id

    <div v-for="item in items" :key="item.id">
      <!-- 内容 -->
    </div>
    

    变异方法

    push()
    pop()
    shift()
    unshift()
    splice()
    sort()
    reverse()
    一组观察数组的变异方法,所以它们也将会触发视图更新


    image.png

    数组发生变化,页面会检测到,重新渲染

    替换数组

    filter(), concat() 和 slice() 。这些不会改变原始数组,但总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组

    vm.items = vm.items.filter(function (item) {
      return item.message.match(/Foo/)
    })
    

    vue不会丢弃掉所有dom重新渲染,会智能重用,因此用含有相同元素去替换原来数组会很高效


    image.png

    注意

    vue不能检测以下数组的变动

    1.当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue


    image.png

    解决办法:
    // Vue.set
    Vue.set(vm.items, indexOfItem, newValue)


    image.png

    2.当你修改数组的长度时,例如:vm.items.length = newLength


    image.png

    解决办法
    vm.items.splice(indexOfItem, 1, newValue)


    image.png

    vue不能检测到对象属性的添加和删除

    image.png

    解决方法:Vue.set(vm.userProfile, 'age', 27)
    或者vm.set(vm.userProfile,'weight','90kg')set 只是 Vue.set的别名

    image.png

    使用 Object.assign() 或 _.extend()添加多条属性

    Object.assign(vm.userProfile, {
      age: 27,
      favoriteColor: 'Vue Green'
    })
    这种添加多条属性的方式并不是响应式的
    
    image.png
    响应式的应该写成这样
    vm.userProfile=Object.assign({},vm.userProfile, {
      age: 27,
      favoriteColor: 'Vue Green'
    })
    
    image.png

    显示过滤/排序结果

    我们想要显示一个数组的过滤或排序副本,而不实际改变或重置原始数据。在这种情况下,可以创建返回过滤或排序数组的计算属性。

     <li v-for="n in evenNumbers">{{n}}</li>
    
     computed:{
            evenNumbers: function(){
              return this.numbers.filter(function(n){
                return n%2 === 0
              })
            }
          }
    

    当计算属性不适合时,我们可以使用方法methods

    <li v-for="n in odd(numbers)">{{n}}</li>
     methods:{
            odd: function(numbers){
              return numbers.filter(function(item){
                return item%2 === 1
              })
            }
          }
    

    v-for 也可以取整数

    <div>
          <li v-for="n in 10">{{ n }} </li>
    </div>
    

    v-for 也可以用在template上

    v-for和v-if同时使用 可以先判断后循环 也可以先循环后判断




    组件的v-for 使用---简单的例子todoList

      <div id="todo-list-demo">
        <form v-on:submit.prevent='addNewTodo'>
        阻止表单触发默认事件刷新转而调用addNewTodo
          <input id='new-todo' 
                 placeholder="E.g. Feed the cat"
                 v-model="newTodoText">
          实现数据双向绑定,输入什么,就在下方添加什么
          <button>Add</button>
        </form>
    
        <ul>
          <li is='todo-item'  组件用is来表明身份,相当于<todo-item><todo-item>
              v-for="(todo,index) in todos"
              循环遍历
              v-bind:key="todo.id"
              接收父组件传值
              v-bind:title="todo.title"
              v-on:remove="todos.splice(index,1)"
              监听到了触发remove函数就执行remove函数
          >
          </li>
    
        </ul>
      </div>
    
      <script>
    
        Vue.component('todo-item',{
          template:`<li>{{title}}
            <button v-on:click="$emit('remove')">
            子组件监听click事件,如果click了就触发remove函数
              remove
            </button>
            </li>`,
          props:['title']
        })
        
        new Vue({
          el: '#todo-list-demo',
          data: {
            newTodoText: '',
            todos: [{
                id: 1,
                title: 'Do the dishes',
              },
              {
                id: 2,
                title: 'Take out the trash',
              },
              {
                id: 3,
                title: 'Mow the lawn'
              }
            ],
            nextTodoId: 4
          },
          methods:{
            addNewTodo:function(){
              this.todos.push({
                id:this.nextTodoId++,
                title:this.newTodoText
              })
              添加新的数据,赋予id,同时再利用双向绑定清空input框
              this.newTodoText=''
            }
          }
        })
      </script>
    

    相关文章

      网友评论

          本文标题:vue重新起航(三)

          本文链接:https://www.haomeiwen.com/subject/kpohtqtx.html