zoukankan      html  css  js  c++  java
  • VUE2中文文档:语法基础笔记

    声明式渲染

    Vue.js 的核心是,可以采用简洁的模板语法来声明式的将数据渲染为 DOM:

    <div id="app">
      {{ message }}         //模板语法
    </div>
    

      

    var app = new Vue({  //新建vue实例(响应式)
      el: '#app',      //挂载到#app
      data: {
        message: 'Hello Vue!'  //数据
      }
    })

    除了文本插值(text interpolation),我们还可以采用这样的方式绑定 DOM 元素属性:

    <div id="app-2">
      <span v-bind:title="message">     //v-bind:属性=“数据”
        鼠标悬停此处几秒,
        可以看到此处动态绑定的 title!
      </span>
    </div>
    var app2 = new Vue({
      el: '#app-2',
      data: {
        message: '页面加载于 ' + new Date().toLocaleString()
      }
    })  

    由组件组合而成的应用程序

    在 Vue 中,一个组件本质上是一个被预先定义选项的 Vue 实例,在 Vue 中注册组件很简单:

    // 定义一个被命名为 todo-item 的新组件
    Vue.component('todo-item', {
      template: '<li>这是一个 todo 项</li>'
    })

    现在你可以在另一个组件模板中组合使用它:

    <ol>
      <!-- 创建一个 todo-item 组件的实例 -->
      <todo-item></todo-item>
    </ol>

    将数据从父作用域传到子组件。让我们来修改下组件的定义,使它可以接受一个 prop

    var app7 = new Vue({                 //vue实例挂载到app-7
      el: '#app-7',
      data: {
        groceryList: [
          { id: 0, text: '蔬菜' },
          { id: 1, text: '奶酪' },
          { id: 2, text: '其他人类食物' }
        ]
      }
    })

    <div id="app-7">                    //组件模板app-7             <ol> <!-- 现在我们为每个 todo-item 提供了 todo 对象, 其中它的内容是动态的。 我们还需要为每个组件提供一个 "key", 这将在之后详细解释。 --> <todo-item v-for="item in groceryList" v-bind:todo="item"               //将遍历的每个item对象传递给todo v-bind:key="item.id">             //由于vue对组件渲染是可复用的,如果不给每一个添加不同的key,后面循环的组件不会重新渲染  </todo-item>                    //而是直接复用第一次渲染的结果 </ol> </div>



    Vue.component('todo-item', { props: ['todo'],                 //子组件用props接受todo template: '<li>{{ todo.text }}</li>'     //子组件模板 })

    下面正式开始:

    Vue 实例

    var vm = new Vue({    //创建
      // 选项
    })

    Vue 应用程序由「一个使用 new Vue 创建的 Vue 根实例」、「嵌套的树结构(可选)」和「可复用的组件」组成。

    data 和 methods

    在创建 Vue 实例时,会将所有在 data 对象中找到的属性,都添加到 Vue 的响应式系统中。每当这些属性的值发生变化时,视图都会“及时响应”,并更新相应的新值。

    每当 data 对象发生变化,都会触发视图重新渲染。值得注意的是,如果实例已经创建,那么只有那些 data 中的原本就已经存在的属性,才是响应式的。也就是说,如果在实例创建之后,添加一个新的属性,

    例如:vm.b = ' hide';

    然后,修改 b 不会触发任何视图更新。如果你已经提前知道,之后将会用到一个开始是空的或不存在的属性,你需要预先设置一些初始值。例如:

    data: {
      newTodoText: '',
      visitCount: 0,
      hideCompletedTodos: false,
      todos: [],
      error: null
    }

    唯一的例外是,使用 Object.freeze() 来防止已有属性被修改,这也意味着响应式系统无法追踪变化。

    除了 data 属性, Vue 实例还暴露了一些有用的实例属性和方法。这些属性与方法都具有前缀 $,以便与用户定义(user-defined)的属性有所区分。例如:

    var data = { a: 1 }
    var vm = new Vue({
      el: '#example',
      data: data
    })
    
    vm.$data === data                           // => true      实例属性,获取实例data
    vm.$el === document.getElementById('example')         // => true    获取挂载的DOM对象
    
    // $watch 是一个实例方法
    vm.$watch('a', function (newValue, oldValue) {
      // 此回调函数将在 `vm.a` 改变后调用
    })

     点击API文档,来获取实例属性(instance property)和方法(methods)的完整列表。

    实例生命周期钩子函数

    每个 Vue 实例在被创建之前,都要经过一系列的初始化过程 - 例如:

    Vue 实例需要设置数据观察(set up data observation)、

    编译模板(compile the template)、

    在 DOM 挂载实例(mount the instance to the DOM),

    数据变化时更新 DOM(update the DOM when data change)。

    在这个过程中,Vue 实例还会调用执行一些生命周期钩子函数,这样用户能够在特定阶段添加自己的代码。

    生命周期示意图

    模板语法

    所有 Vue.js 的模板都是有效的 HTML,能够被遵循规范的浏览器和 HTML 解析器解析。

    在底层的实现上,Vue 将模板编译为可以生成 Virtual DOM 的 render 函数。结合响应式系统,在应用程序状态改变时,Vue 能够智能地找出重新渲染的最小数量的组件,并应用最少量的 DOM 操作。

    如果你熟悉虚拟 DOM 的概念,并且倾向于使用原生 JavaScript,还可以不使用模板,而是直接编写 render 函数,具备可选的 JSX 语法支持。

    插值(Interpolations)

    文本(Text)

     使用 “mustache” 语法(双花括号)的文本插值(text interpolation),也可以通过使用 v-once 指令,执行一次性插值,也就是说,在数据改变时,插值内容不会随之更新。但是请牢记,这也将影响到同一节点上的其他所有绑定。

    原始 HTML(Raw HTML)        (不建议使用)

    属性(Attributes)

    使用 JavaScript 表达式

    有个限制是,每个绑定都只能包含单个表达式。

    computed 属性和 watcher

    你可以像绑定普通属性一样,将 computed 属性的数据,绑定(data-bind)到模板中的表达式上。Vue 能够意识到 computed属性依赖于 实例的数据,也会在 示例数据修改后,更新所有依赖于 computed属性 的数据绑定。最恰到好处的部分是,我们是通过声明式来创建这种依赖关系:computed 属性的 getter 函数并无副作用(side effect),因此也更加易于测试和理解。

    computed 缓存 vs method 方法

    computed 属性会基于它所依赖的数据进行缓存。每个 computed 属性,只有在它所依赖的数据发生变化时,才会重新取值(re-evaluate)。这就意味着,只要 computed属性函数依赖的实例数据 没有发生变化,多次访问 computed 属性,将会立刻返回之前计算过的结果,而不必每次都重新执行函数。

    为什么我们需要将依赖数据缓存起来?假设一种场景,我们有一个高性能开销(expensive)的 computed 属性 A,在 computed 属性的 getter 函数内部,需要遍历循环一个巨大数组,并进行大量计算。然后还有其他 computed 属性直接或间接依赖于 A。如果没有缓存,我们将不可避免地多次执行 A 的 getter 函数,这远多余实际需要执行的次数!然而在某些场景下,你可能不希望有缓存,请使用 method 方法替代。

    computed 属性和 watch 属性

    更推荐的方式是,使用 computed 属性,而不是命令式(imperative)的 watch 回调函数。例如:

    computed版本

    var vm = new Vue({
      el: '#demo',
      data: {
        firstName: 'Foo',
        lastName: 'Bar'
      },
      computed: {
        fullName: function () {
          return this.firstName + ' ' + this.lastName           //需要一个返回值加入到实例数据或者修改实例数据
        }                                     //computed属性会检测其依赖的实例数据       
      }
    })

     watch版本

    var vm = new Vue({
      el: '#demo',
      data: {
        firstName: 'Foo',
        lastName: 'Bar',
        fullName: 'Foo Bar'                //watch属性,检测已经存在的属性数据,不会自动返回为新实例属性数据,所以要先声明 
      },
      watch: {
        firstName: function (val) {                 //观测发生改变的属性对象,而不观测其依赖的实例数据,所以需要分为两个函数实现功能。 
          this.fullName = val + ' ' + this.lastName       
        },
        lastName: function (val) {
          this.fullName = this.firstName + ' ' + val
        }
      }
    })

     对比 computed 属性实现的版本,以上代码是命令式和重复的。

    computed 属性中设置 setter

    computed 属性默认只设置 getter 函数,不过在需要时,还可以提供 setter 函数:

    var vm = new Vue({
      el: '#demo',
      data: {
        firstName: 'Foo',
        lastName: 'Bar',
        fullName: 'Foo Bar'
      },
    computed: {
      fullName: {
        // getter 函数
        get: function () {                  //get函数观测对象依赖,并返回变化
          return this.firstName + ' ' + this.lastName
        },
        // setter 函数
        set: function (newValue) {            //set函数观测对象让你可以在computed中更改对象依赖的数据    
          var names = newValue.split(' ')
          this.firstName = names[0]
          this.lastName = names[names.length - 1]
        }
      }
    }
    })

     现在当你运行 vm.fullName = 'John Doe',将会调用 setter,然后会对应更新 vm.firstName 和 vm.lastName

    watcher

    虽然在大多数情况下,更适合使用 computed 属性,然而有些时候,还是需要一个自定义 watcher。当你需要在数据变化响应时,执行异步操作,或高性能消耗的操作,自定义 watcher 的方式就会很有帮助。

    <div id="watch-example">
      <p>
        问一个答案是 yes/no 的问题:
        <input v-model="question">          //v-modle会将input输入值传给question
      </p>
      <p>{{ answer }}</p>
    </div>
    <!-- 对于 ajax 库(ajax libraries)和通用工具方法的集合(collections of general-purpose utility methods)来说, -->
    <!-- 由于已经存在大量与其相关的生态系统, -->
    <!-- 这也可以使你自由随意地选择自己最熟悉的。 -->
    <script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
    <script>
    var watchExampleVM = new Vue({
      el: '#watch-example',
      data: {
        question: '',
        answer: '你要先提出问题,我才能给你答案!'
      },
      watch: {     //这种需求,不是更新观测对象(computed.get)或者更新其依赖(computed.set), 而是观测变化去做与数据无关的操作,computed无法实现       
        // 只要 question 发生改变,此函数就会执行              
        question: function (newQuestion, oldQuestion) {    //不是很懂两个参数,但我想可能这是watch能监测到的改变之前和之后的对象,
          this.answer = '等待输入停止……'
          this.getAnswer()
        }
      },
      methods: {
        // _.debounce 是由 lodash 提供的函数,
        // 在运行特别消耗性能的操作时,
        // 可以使用 _.debounce 来限制频率。
        // 在下面这种场景中,我们需要限制访问 yesno.wtf/api 的频率,
        // 等到用户输入完毕之后,ajax 请求才会发出。
        getAnswer: _.debounce(
          function () {
            if (this.question.indexOf('?') === -1) {
              this.answer = '问题通常需要包含一个中文问号。;-)'
              return
            }
            this.answer = '思考中……'
            var vm = this                    //ajax请求中的this可能没有指向实例,所以在请求之前先把实例对象this赋值给变量vm
            axios.get('https://yesno.wtf/api')
              .then(function (response) {
                vm.answer = _.capitalize(response.data.answer)
              })
              .catch(function (error) {
                vm.answer = '错误!API 无法处理。' + error
              })
          },
          // 这是用户停止输入操作后所等待的毫秒数。
          // (译者注:500毫秒之内,用户继续输入,则重新计时)
          500
        )
      }
    })
    </script>

    class 和 style 绑定

    与 HTML 的 class 绑定(Binding HTML Classes)

    (内联、外部引用)这两种方式的渲染结果相同。我们还可以将 class 和 style 与某个 computed 属性绑定在一起,此 computed 属性所对应的 getter 函数需要返回一个对象。这是一种常用且强大的用法

    <div v-bind:class="classObject"></div>    //简写 :class="classObject" 
    data: {
      isActive: true,
      error: null
    },
    computed: {                       //通过computed属性控制classObjecr对其它class的影响
      classObject: function () {                     //如果classObject属性去除了,先前computed return的样式会恢复吗?
        return {
          active: this.isActive && !this.error,
          'text-danger': this.error && this.error.type === 'fatal'
        }
      }
    }

    我们可以向 v-bind:class 传入一个数组,来与 class 列表对应:

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

    <div v-bind:class="[isActive ? activeClass : '', errorClass]"></div> 
    //这里会直接添加 errorClass,但是只有在 isActive 值是 truthy 时,才会添加 activeClass

    <div v-bind:class="[{ active: isActive }, errorClass]"></div>  //这里使用对象语法比三元运算更加简洁
     

    在组件中使用

     当你在自定义组件中使用 class 属性,这些 class 会被添加到组件的根元素上。根元素上已经存在的 class 不会被覆盖。

    与内联 style 绑定(Binding Inline Styles)

    <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

    v-bind:style 的对象语法,通常也会和 computed 属性结合使用,此 computed 属性所对应的 getter 函数需要返回一个对象。

    <div v-bind:style="[baseStyles, overridingStyles]"></div>

    从 2.3.0+ 起,你可以为每个 style 属性提供一个含有多个(前缀)值的数组,例如:

    <div v-bind:style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>

    根据条件进行渲染

     v-else 元素必须紧跟在 v-if 或 v-else-if 元素之后 - 否则无法识别它。

    使用 key 控制元素是否可复用

    Vue 会尽可能高效地渲染元素,通常会复用已渲染元素,而不是从头重新渲染。这样的实现方式,除了有助于使 Vue 变得非常快之外,还具有一些额外的优势。

    但是这样有时并不符合实际需求,所以 Vue 为如下所述的情况提供了一种方式:“这两个元素是完全独立的 - 请不要复用它们”。那就是为它们添加一个具有不同值的 key 属性。

    具有 v-show 的元素会始终渲染并保留在 DOM 中。v-show 只会切换元素的 display 这个 CSS 属性。

    v-if 是“真实”的条件渲染,因为它会确保条件块(conditional block)在切换的过程中,完整地销毁(destroy)和重新创建(re-create)条件块内的事件监听器和子组件。

    v-if 是惰性的(lazy):如果在初始渲染时条件为 false,它不会执行任何操作 - 在条件第一次变为 true 时,才开始渲染条件块。

    通常来说,v-if 在切换时有更高的性能开销,而 v-show 在初始渲染时有更高的性能开销。因此,如果需要频繁切换,推荐使用 v-show,如果条件在运行时改变的可能性较少,推荐使用 v-if

    列表渲染

    使用 v-for 遍历数组生成元素

    在 v-for 代码块中,我们可以完全地访问父级作用域下的属性。v-for 还支持可选的第二个参数,作为当前项的索引。

    使用 v-for 遍历对象

    还可以提供第二个参数,作为对象的键名(key,然后第三个参数作为索引(index):

    <div v-for="(value, key, index) in object">
      {{ index }}. {{ key }}: {{ value }}
    </div>

    遍历一个对象时,是按照 Object.keys() 得出 key 的枚举顺序来遍历,无法保证在所有 JavaScript 引擎实现中完全一致。

    推荐,在使用 v-for 时,尽可能提供一个 key,除非迭代的 DOM 内容足够简单,或者你是故意依赖于默认行为来获得性能提升。

    数组变化检测(Array Change Detection)

    变化数组方法(Mutation Methods)

    • push()
    • pop()
    • shift()
    • unshift()
    • splice()
    • sort()
    • reverse()

    替换一个数组(Replacing an Array)

    例如 filter()concat() 和 slice()

    你可能会认为这将导致 Vue 丢弃现有 DOM 并重新渲染(re-render)整个列表 - 幸运的是,情况并非如此。Vue 实现了一些智能启发式方法(smart heuristic)来最大化 DOM 元素重用(reuse),因此将一个数组替换为包含重叠对象的另一个数组,会是一种非常高效的操作。

    注意事项(Caveats)

    由于 JavaScript 的限制,Vue 无法检测到以下数组变动:

    1. 当你使用索引直接设置一项时,例如 vm.items[indexOfItem] = newValue
    2. 当你修改数组长度时,例如 vm.items.length = newLength

    为了解决第 1 个问题,以下方式都可以实现相同的效果,但是却可以通过响应式系统出发状态更新:

    // Vue.set
    Vue.set(vm.items, indexOfItem, newValue)
    
    // Array.prototype.splice
    vm.items.splice(indexOfItem, 1, newValue)
    
    //你还可以使用 vm.$set 实例方法,这也是全局 Vue.set 方法的别名:
    vm.$set(vm.items, indexOfItem, newValue)

    为了解决第 2 个问题,你可以使用 splice

    vm.items.splice(newLength)

    有时,你想要向已经存在的对象上添加一些新的属性,例如使用 Object.assign() 或 _.extend() 方法。在这种情况下,应该创建一个新的对象,这个对象同时具有两个对象的所有属性,因此,改为:                    //不是很理解

    Object.assign(vm.userProfile, {
      age: 27,
      favoriteColor: 'Vue Green'
    })
    
    //可以通过如下方式,添加新的响应式属性:
    vm.userProfile = Object.assign({}, vm.userProfile, {
      age: 27,
      favoriteColor: 'Vue Green'
    })

    显示过滤/排序结果(Displaying Filtered/Sorted Results)

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

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

    data: { numbers: [ 1, 2, 3, 4, 5 ] }, computed: { evenNumbers: function () { return this.numbers.filter(function (number) { return number % 2 === 0 }) } }

    在计算属性不适用的情况下(例如,在嵌套的 v-for 循环内),可以使用一个 method 方法:  //不是很理解红色部分,参考上面循环,思考如果外部再套一层循环的computed结果

    data: {
      numbers: [ 1, 2, 3, 4, 5 ]
    },
    methods: {
      even: function (numbers) {
        return numbers.filter(function (number) {
          return number % 2 === 0
        })
      }
    }

    使用 v-for 在整数值范围内迭代

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

    带有 v-if 的 v-for

    当它们都处于同一节点时,v-for 的优先级高于 v-if。这意味着,v-if 将分别在循环中的每次迭代上运行。当你只想将某些项渲染为节点时,这会非常有用,如下:

    <li v-for="todo in todos" v-if="!todo.isComplete">
      {{ todo }}
    </li>

    如果你的意图与此相反,是根据条件跳过执行循环,可以将 v-if 放置于包裹元素上(或放置于 <template> 上)。例如:

    <ul v-if="todos.length">
      <li v-for="todo in todos">
        {{ todo }}
      </li>
    </ul>
    <p v-else>No todos left!</p>

    使用 v-for 遍历组件

    现在,在 2.2.0+ 版本,当对组件使用 v-for 时,必须设置 key 属性。

    无法自动向组件中传入数据,这是因为组件有自己的独立作用域。为了将组件外部的迭代数据传入组件,我们还需要额外使用 props:

    <my-component
      v-for="(item, index) in items"
      v-bind:item="item"
      v-bind:index="index"
      v-bind:key="item.id"
    ></my-component>

    没有通过 v-for 将 item 自动注入到组件中的原因是,一旦自动注入,就会使得组件与 v-for 指令的运行方式紧密耦合(tightly coupled)在一起。通过显式声明组件数据来源,可以使得组件可重用于其他场景。

    <div id="todo-list-example">
      <input
        v-model="newTodoText"
        v-on:keyup.enter="addNewTodo"
        placeholder="Add a todo"
      >
      <ul>
        <li
          is="todo-item"       //注意 is="todo-item" 属性。这在 DOM 模板中是必需的,因为在 <ul> 中,只有 <li> 是有效元素。这与调用 <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)"
        ></li>
      </ul>
    </div>

    事件处理

    监听事件

     我们可以使用 v-on 指令监听 DOM 事件,并在事件被触发时执行一些 JavaScript 代码。

    由于许多事件处理器的逻辑很复杂,所以把 JavaScript 代码都保存在 v-on 属性的值中是不可行的做法。这就是为什么 v-on 还可以接收要调用的方法名。

    行内语句的事件处理器中,有时我们也需要访问原始 DOM 事件对象。可以使用特殊的 $event 变量将它传递给一个方法:

    <button v-on:click="warn('Form cannot be submitted yet.', $event)">
      Submit
    </button>
    // ...
    methods: {
      warn: function (message, event) {
        // 现在,我们可以访问原始事件对象
        if (event) event.preventDefault()
        alert(message)
      }
    }

    事件修饰符(Event Modifiers)

    尽管我们可以在 methods 中轻松实现这点,但更好的方式是:methods 只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。

    Vue.js 为 v-on 提供了事件修饰符。回想一下,修饰符是以点(.)开头的指令后缀来表示。

    <!-- 停止点击事件冒泡 -->
    <a v-on:click.stop="doThis"></a>
    
    <!-- 提交事件不再重新载入页面 -->
    <form v-on:submit.prevent="onSubmit"></form>
    
    <!-- 修饰符可以链式调用 -->
    <a v-on:click.stop.prevent="doThat"></a>
    
    <!-- 只有修饰符 -->
    <form v-on:submit.prevent></form>
    
    <!-- 添加事件监听器时,使用事件捕获模式 -->
    <!-- 也就是说,内部元素触发的事件先在此处处理,然后才交给内部元素进行处理 -->        //想不到实际运用场景
    <div v-on:click.capture="doThis">...</div>
    
    <!-- 只有在 event.target 是元素自身时,才触发处理函数。 -->
    <!-- 也就是说,event.target 是子元素时,不触发处理函数 -->
    <div v-on:click.self="doThat">...</div>

    <!-- 点击事件将只会触发一次 -->
    <a v-on:click.once="doThis"></a>



    <!-- 滚动事件的默认行为(滚动)将立即发生, -->
    <!-- 而不是等待 `onScroll` 完成后才发生, -->
    <!-- 以防在滚动事件的处理程序中含有 `event.preventDefault()` 调用 -->
    <div v-on:scroll.passive="onScroll">...</div>
                       //.passive 修饰符对于提高移动设备的性能尤其有用。       

    使用修饰符时的顺序会产生一些影响,因为相关的代码会以相同的顺序生成。所以,使用 v-on:click.prevent.self 会阻止所有点击,而 v-on:click.self.prevent 只阻止元素自身的点击。

    不要将 .passive 和 .prevent 放在一起使用,因为 .prevent 将被忽略,并且浏览器可能会显示一条警告。记住,.passive 会向浏览器传达的意思是,你并不希望阻止事件的默认行为。

    按键修饰符(Key Modifiers)

    <!-- 和上面的示例相同 -->
    <input v-on:keyup.enter="submit">
    
    <!-- 也可用于简写语法 -->
    <input @keyup.enter="submit">

    这里列出所有的按键修饰符别名:

    • .enter
    • .tab
    • .delete (捕获“删除”和“退格”按键)
    • .esc
    • .space
    • .up
    • .down
    • .left
    • .right

    还可以自定义按键修饰符别名,通过全局 config.keyCodes 对象设置:

    // 可以使用 `v-on:keyup.f1`
    Vue.config.keyCodes.f1 = 112

    自动对应按键修饰符(Automatic Key Modifers)

    也可以直接使用 KeyboardEvent.key 暴露出来的所有合法按键名作为修饰符,但是要将它们转换为串联式命名(kebab-case):

    <input @keyup.page-down="onPageDown">

    系统辅助按键(System Modifier Keys)

    仅在以下修饰符对应的按键被按下时,才会触发鼠标或键盘事件监听器:

    • .ctrl
    • .alt
    • .shift
    • .meta
    <!-- Alt + C -->
    <input @keyup.alt.67="clear">
    
    <!-- Ctrl + Click -->
    <div @click.ctrl="doSomething">做一些操作</div>

    .exact 修饰符(.exact Modifier)

    .exact 修饰符可以控制触发事件所需的系统辅助按键的准确组合。

    <!-- 如果 Alt 键或 Shift 键与  Ctrl 键同时按下,也会触发事件 -->
    <button @click.ctrl="onClick">A</button>
    
    <!-- 只在 Ctrl 按键按下,其他按键未按下时,触发事件 -->
    <button @click.ctrl.exact="onCtrlClick">A</button>
    
    <!-- 只在系统辅助按键按下时,触发事件 -->
    <button @click.exact="onClick">A</button>

    鼠标按键修饰符(Mouse Button Modifiers)

    • .left
    • .right
    • .middle

    这些修饰符会限制处理函数,仅响应特定的鼠标按键触发的事件。

    表单 input 绑定

    可以通过使用 v-model 指令,在表单 input 和 textarea 元素上创建双向数据绑定。v-model 指令可以根据 input 的 type 类型,自动地以正确的方式更新元素。虽然略显神奇,然而本质上 v-model 不过是「通过监听用户的 input 事件来更新数据」的语法糖,以及对一些边界情况做特殊处理。

    v-model 会忽略所有表单元素中 valuechecked 或 selected 属性上初始设置的值,而总是将 Vue 实例中的 data 作为真实数据来源。因此你应该在 JavaScript 端的组件 data 选项中声明这些初始值,而不是 HTML 端。

    与 value 属性绑定(待补充)

    修饰符(modifiers)

    .lazy

    默认情况下,v-model 会在每次 input 事件触发之后,将数据同步至 input 元素中(除了上述提到的输入法组合文字时不会)。可以添加 lazy 修饰符,从而转为在触发 change 事件后同步。

    .number

    如果想要将用户的输入,自动转换为 Number 类型(译注:如果转换结果为 NaN 则返回字符串类型的输入值),可以在 v-model 之后添加一个 number 修饰符,来处理输入值:


    这通常很有用,因为即使是在 type="number" 时,HTML 中 input 元素也总是返回一个字符串类型的值。

    .trim

    如果想要将用户的输入,自动过滤掉首尾空格,可以在 v-model 之后添加一个 trim 修饰符,来处理输入值:

  • 相关阅读:
    iaas,paas,saas理解
    July 06th. 2018, Week 27th. Friday
    July 05th. 2018, Week 27th. Thursday
    July 04th. 2018, Week 27th. Wednesday
    July 03rd. 2018, Week 27th. Tuesday
    July 02nd. 2018, Week 27th. Monday
    July 01st. 2018, Week 27th. Sunday
    June 30th. 2018, Week 26th. Saturday
    June 29th. 2018, Week 26th. Friday
    June 28th. 2018, Week 26th. Thursday
  • 原文地址:https://www.cnblogs.com/FunkyEric/p/8961572.html
Copyright © 2011-2022 走看看