• 【Vue】模板语法,事件处理器及综合案例、自定义组件、组件通信


    一、事件处理器

    我们之前事件监听可以使用v-on 指令

    1、事件修饰符

    Vue中我们通过由点(.)表示的指令后缀来调用修饰符,比如:

    1.   .stop:阻止事件冒泡。当事件触发时,该修饰符将停止事件进一步冒泡到父元素。相当于调用了 event.stopPropagation()
    2.   .prevent:阻止默认事件。默认情况下,某些元素会有默认的事件行为,比如标签的点击跳转,使用.prevent 可以阻止默认事件的触发。相当于调用了 event.preventDefault()
    3.   .capture:使用事件捕获模式。默认情况下,事件是在冒泡阶段处理的(即从子元素到父元素)。使用 .capture 修饰符将事件处理移到事件捕获阶段(即从父元素到子元素)。
    4.   .self:只触发当前元素本身的事件。当事件绑定在子元素上时,该修饰符只允许事件在子元素上触发,而不会触发父元素上相同事件。
    5.   .once::只触发一次事件。使用 .once 修饰符可以确保事件只被触发一次,之后该事件监听器会自动被移除。
    1. <a v-on:click.stop="doThis">a>
    2. <form v-on:submit.prevent="onSubmit">form>
    3. <a v-on:click.stop.prevent="doThat">a>
    4. <form v-on:submit.prevent>form>
    5. <div v-on:click.capture="doThis">...div>
    6. <div v-on:click.self="doThat">...div>
    7. <a v-on:click.once="doThis">a>

    2、冒泡案例(.stop)

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>事件处理器title>
    6. <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js">script>
    7. <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js">script>
    8. head>
    9. <style>
    10. .red {
    11. width: 400px;
    12. height: 400px;
    13. background-color: red;
    14. }
    15. .orange {
    16. width: 300px;
    17. height: 300px;
    18. background-color: orange;
    19. }
    20. .blue {
    21. width: 200px;
    22. height: 200px;
    23. background-color: blue;
    24. }
    25. .black {
    26. width: 500px;
    27. height: 500px;
    28. background-color: black;
    29. }
    30. style>
    31. <body>
    32. <div id="app">
    33. <p>冒泡事件p>
    34. <div class="black" @click="black">
    35. <div class="red" @click="red">
    36. <div class="orange" @click="orange">
    37. <div class="blue" @click="blue">
    38. div>
    39. div>
    40. div>
    41. div>
    42. div>
    43. body>
    44. <script type="text/javascript">
    45. // 绑定边界 ES6具体体现
    46. new Vue({
    47. el: '#app',
    48. data() {
    49. return {
    50. f200: 'f200'
    51. };
    52. },
    53. methods: {
    54. red() {
    55. alert("red(红色)");
    56. },
    57. orange() {
    58. alert("orange(橙色)");
    59. },
    60. blue() {
    61. alert("blue(蓝色)");
    62. },
    63. black() {
    64. alert("black(黑色)");
    65. }
    66. }
    67. })
    68. script>
    69. html>

    当我们加上了.stop修饰符

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>事件处理器title>
    6. <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js">script>
    7. <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js">script>
    8. head>
    9. <style>
    10. .red {
    11. width: 400px;
    12. height: 400px;
    13. background-color: red;
    14. }
    15. .orange {
    16. width: 300px;
    17. height: 300px;
    18. background-color: orange;
    19. }
    20. .blue {
    21. width: 200px;
    22. height: 200px;
    23. background-color: blue;
    24. }
    25. .black {
    26. width: 500px;
    27. height: 500px;
    28. background-color: black;
    29. }
    30. style>
    31. <body>
    32. <div id="app">
    33. <p>冒泡事件p>
    34. <div class="black" @click.stop="black">
    35. <div class="red" @click.stop="red">
    36. <div class="orange" @click.stop="orange">
    37. <div class="blue" @click.stop="blue">
    38. div>
    39. div>
    40. div>
    41. div>
    42. div>
    43. body>
    44. <script type="text/javascript">
    45. // 绑定边界 ES6具体体现
    46. new Vue({
    47. el: '#app',
    48. data() {
    49. return {
    50. f200: 'f200'
    51. };
    52. },
    53. methods: {
    54. red() {
    55. alert("red(红色)");
    56. },
    57. orange() {
    58. alert("orange(橙色)");
    59. },
    60. blue() {
    61. alert("blue(蓝色)");
    62. },
    63. black() {
    64. alert("black(黑色)");
    65. }
    66. }
    67. })
    68. script>
    69. html>

    3、触发案例(.once)

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>事件处理器title>
    6. <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js">script>
    7. <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js">script>
    8. head>
    9. <body>
    10. <div id="app">
    11. <p>点击p>
    12. <input :value="msg"/>
    13. <button @click="dosub">提交button>
    14. div>
    15. body>
    16. <script type="text/javascript">
    17. // 绑定边界 ES6具体体现
    18. new Vue({
    19. el: '#app',
    20. data() {
    21. return {
    22. msg: '偶买噶'
    23. };
    24. },
    25. methods: {
    26. dosub() {
    27. alert(this.msg);
    28. }
    29. }
    30. })
    31. script>
    32. html>

    添加.once之后只能点击一次

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>事件处理器title>
    6. <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js">script>
    7. <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js">script>
    8. head>
    9. <body>
    10. <div id="app">
    11. <p>点击p>
    12. <input :value="msg"/>
    13. <button @click.once="dosub">提交button>
    14. div>
    15. body>
    16. <script type="text/javascript">
    17. // 绑定边界 ES6具体体现
    18. new Vue({
    19. el: '#app',
    20. data() {
    21. return {
    22. msg: '偶买噶'
    23. };
    24. },
    25. methods: {
    26. dosub() {
    27. alert(this.msg);
    28. }
    29. }
    30. })
    31. script>
    32. html>

    4、综合案例(表单)

    需要注意的是复选框v-model="hobbyMax"中的hobbyMax使用数组来接收

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>表单title>
    6. <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js">script>
    7. <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js">script>
    8. head>
    9. <body>
    10. <div id="app">
    11. <label>姓名:label><input v-model="username"/><br/>
    12. <label>密码:label><input v-model="pwd" type="password"/><br/>
    13. <label>年龄:label><input v-model.number="age" type="number"/><br/>
    14. <label>性别:label>
    15. <div v-for="s in sexMax">
    16. <input type="radio" v-model="sex" name="sex" v-bind:value="s.id"/>{{s.name}}<br/>
    17. div>
    18. <label>爱好:label>
    19. <div v-for="h in hobby">
    20. <input type="checkbox" v-model="hobbyMax" v-bind:value="h.id"/>{{h.name}}
    21. div>
    22. <label>类别:label>
    23. <select v-model="type">
    24. <option v-for="t in types" v-bind:value="t.id">{{t.name}}option>
    25. select><br/>
    26. <label>备注:label>
    27. <textarea v-model="info">textarea><br/>
    28. 确认<input type="checkbox" v-model="flag"/>
    29. <input type="submit" v-bind:disabled="show" v-on:click="doSubmit"/>
    30. div>
    31. body>
    32. <script type="text/javascript">
    33. new Vue({
    34. el: '#app',
    35. data() {
    36. return {
    37. username: null,
    38. pwd: null,
    39. age: 10,
    40. sex: 1,
    41. sexMax: [{id: 1, name: "男"}, {id: 2, name: "女"}, {id: 3, name: "其他"}],
    42. hobby: [
    43. {
    44. id: 1,
    45. name: '篮球'
    46. },
    47. {
    48. id: 2,
    49. name: '唱'
    50. },
    51. {
    52. id: 3,
    53. name: '跳'
    54. },
    55. {
    56. id: 4,
    57. name: 'rap'
    58. }],
    59. hobbyMax: [],
    60. types: [
    61. {
    62. id: 1,
    63. name: '职业人'
    64. },
    65. {
    66. id: 2,
    67. name: '学生'
    68. },
    69. {
    70. id: 3,
    71. name: '社会人'
    72. }],
    73. type: null,
    74. info: '请输入你的个性签名',
    75. flag: false
    76. }
    77. },
    78. computed: {
    79. show: function () {
    80. return !this.flag;
    81. }
    82. },
    83. methods: {
    84. doSubmit: function () {
    85. var obj = {
    86. username: this.username,
    87. pwd: this.pwd,
    88. age: this.age,
    89. sex: this.sex,
    90. hobbyMax: this.hobbyMax,
    91. type: this.type,
    92. info: this.info,
    93. }
    94. console.log(obj);
    95. }
    96. }
    97. })
    98. script>
    99. html>

    效果演示

    二、自定义组件

    1、 vue组件

     1.1、组件简介

          组件(Component)是Vue最强大的功能之一

          组件可以扩展HTML元素,封装可重用的代码

          组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树

      1.2、 全局和局部组件

    • 全局组件Vue.component(tagName, options),tagName为组件名,options为配置选项。
    • 局部组件: new Vue({el:'#d1',components:{...}})

          注册后,我们可以使用以下方式来调用组件:

    <tagName>tagName>

      1.3 props

          props是父组件用来传递数据的一个自定义属性。

    父组件的数据需要通过props把数据传给子组件,子组件需要显式地用props选项声明 "prop"

       1:因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods

            以及生命周期钩子等。仅有的例外是像el这样根实例特有的选项。

       2:当我们定义这个 组件时,你可能会发现它的data并不是像这样直接提供一个对象

      

    1.       data: {
    2.           count: 0
    3.         }

            取而代之的是,一个组件的data选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:

    1.         data: function () {
    2.           return {
    3.             count: 0
    4.           }
    5.         }

        3:定义组件名的方式有两种

             短横线分隔命名(建议使用)

    1.          Vue.component('my-component-name', { /* ... */ }),
    2. 引用方式:<my-component-name>

             首字母大写命名

           

    1.   Vue.component('MyComponentName', { ... }),
    2. 引用方式: <my-component-name><MyComponentName>都是可接受的  

        4:HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,

             camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名:

           

      props: ['postTitle'],<my-tag post-title="hello!">my-tag>

        5:props: ['title', 'likes', 'isPublished', 'commentIds', 'author']

             希望每个 prop 都有指定的值类型  

    1.        props: {
    2.            title: String,
    3.            likes: Number,
    4.            isPublished: Boolean,
    5.            commentIds: Array,
    6.            author: Object,
    7.            callback: Function,
    8.            contactsPromise: Promise // or any other constructor
    9.          }

    2、案例

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>组件title>
    6. <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js">script>
    7. <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js">script>
    8. head>
    9. <body>
    10. <div id="app">
    11. <my-img>my-img>
    12. <my-button m="卡拉米">my-button>
    13. div>
    14. body>
    15. <script type="text/javascript">
    16. Vue.component('my-button', {
    17. // props是定义组件中的变量的
    18. props: ['m'],
    19. // template代表了自定义组件在页面上显示的类容
    20. template: '',
    21. data: function () {
    22. return {
    23. n: 1
    24. }
    25. },
    26. methods: {
    27. incrn() {
    28. this.n++;
    29. }
    30. }
    31. });
    32. Vue.component('my-img', {
    33. // template代表了自定义组件在页面上显示的类容
    34. template: '',
    35. });
    36. // 绑定边界 ES6具体体现
    37. new Vue({
    38. el: '#app',
    39. data() {
    40. return {};
    41. }
    42. })
    43. script>
    44. html>

    三、组件通信

    1. 自定义事件

    1.    监听事件$on(eventName)
    2.    触发事件$emit(eventName)

       1.1、Vue自定义事件是为组件间通信设计  

            vue中父组件通过prop传递数据给子组件,而想要将子组件的数据传递给父组件,则可以通过自定义事件的绑定

    1.         父Vue->子Vue,通过prop传递数据
    2.         子Vue->父Vue,通过事件传递数据

       1.2、事件名

            不同于组件和prop,事件名不存在任何自动化的大小写转换。而是触发的事件名需要完全匹配监听这个事件所用的名称。

            建议使用“短横线分隔命名”

    2、案例

    2.1、父传子

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>通信title>
    6. <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js">script>
    7. head>
    8. <body>
    9. <div id="app">
    10. <h3>父传子1h3>
    11. <my-button m="牛马">my-button>
    12. <h3>父传子2h3>
    13. <my-button m="小卡拉米" n="2">my-button>
    14. div>
    15. body>
    16. <script>
    17. // 定义全局组件的方式
    18. Vue.component('my-button', {
    19. props: ['m', 'n'],
    20. template: '',
    21. data: function () {
    22. return {
    23. n: 1
    24. };
    25. },
    26. methods: {
    27. MyButton: function () {
    28. this.n++;
    29. }
    30. }
    31. })
    32. var vm = new Vue({
    33. el: "#app",
    34. data: {
    35. msg: "999"
    36. }
    37. });
    38. script>
    39. html>

    2.2、子传父

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>通信title>
    6. <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js">script>
    7. head>
    8. <body>
    9. <div id="app2">
    10. <h3>子传父h3>
    11. <my-buttons m="666" @getBut="getXx">my-buttons>
    12. div>
    13. body>
    14. <script>
    15. // 定义全局组件的方式
    16. Vue.component('my-buttons', {
    17. props: ['m'],
    18. template: '',
    19. methods: {
    20. MyButton: function () {
    21. let id = 123;
    22. let name = "天才";
    23. this.$emit('getbut', id, name);
    24. }
    25. }
    26. })
    27. var vm = new Vue({
    28. el: "#app2",
    29. data: {
    30. msg: "666"
    31. },
    32. methods: {
    33. getXx: function (a, b) {
    34. console.log(a);
    35. console.log(b);
    36. }
    37. }
    38. });
    39. script>
    40. html>

  • 相关阅读:
    一文全面介绍JWT框架知识
    .Net Core 3.0 对 MongoDB 的多条件(两种)查询操作
    [构造]Repetitions Decoding Codeforces1642D
    微信开发之一键踢出群聊的技术实现
    MySQL存储过程详解与案例应用
    EPLAN_010#STEP格式_箱柜模型的定义、拼柜
    LeetCode 33. 搜索旋转排序数组
    MySQL的JDBC 编程
    “Jmeter WebSocket协议压测”,助你轻松应对高并发场景!
    vue一些知识补充
  • 原文地址:https://blog.csdn.net/weixin_74383330/article/details/133063543