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 修饰符,来处理输入值:

  • 相关阅读:
    事件的记忆碎片
    委托的记忆碎片
    Jquery的集合方法EACH()
    sql server中的 SET NOCOUNT ON 的含义
    nyist 299 Matrix Power Series
    poj 1061 青蛙约会
    nyist 488 素数环
    nyist 301 递推求值
    nyist 95 众数问题
    nyist 640 Geometric sum
  • 原文地址:https://www.cnblogs.com/FunkyEric/p/8961572.html
Copyright © 2011-2022 走看看