[Vue] Template syntax, event handlers and comprehensive cases, custom components, component communication

1. Event handler

We previously used the v-on directive for event monitoring

1. Event modifier

In Vue we call modifiers through the instruction suffix represented by a dot (.) , such as:

  1.  .stop : Stop the event from bubbling up. This modifier will stop the event from bubbling further to the parent element when the event fires. Equivalent to calling event.stopPropagation()
  2.   .prevent : Prevent the default event. By default, some elements have default event behaviors, such as <a>label click jumps, which .prevent can be used to prevent the triggering of default events. It is equivalent to calling  event.preventDefault().
  3.   .capture : Use event capture mode. By default, events are handled in the bubbling phase (i.e. from child elements to parent elements). Use  modifiers to move event handling to the event capture stage (i.e. from parent element to child element). .capture
  4.   .self : Only trigger events on the current element itself. When an event is bound to a child element, this modifier only allows the event to be triggered on the child element, but not the same event on the parent element.
  5.   .once :: Trigger the event only once. Use  .once modifiers to ensure that the event is only triggered once, after which the event listener is automatically removed.
  <!-- 阻止单击事件冒泡 -->
  <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>
  <!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->
  <div v-on:click.self="doThat">...</div>
  <!-- click 事件只能点击一次 -->
  <a v-on:click.once="doThis"></a>

2. Bubble case (.stop)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>事件处理器</title>
    <!--  jQuery-->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <!--  vue.js-->
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script>
</head>
<style>
    .red {
        width: 400px;
        height: 400px;
        background-color: red;
    }

    .orange {
        width: 300px;
        height: 300px;
        background-color: orange;
    }

    .blue {
        width: 200px;
        height: 200px;
        background-color: blue;
    }

    .black {
        width: 500px;
        height: 500px;
        background-color: black;
    }
</style>
<body>
<!-- 定义边界 -->
<div id="app">
    <p>冒泡事件</p>
    <div class="black" @click="black">
        <div class="red" @click="red">
            <div class="orange" @click="orange">
                <div class="blue" @click="blue">
                </div>
            </div>
        </div>
    </div>
</div>
</body>
<script type="text/javascript">
    // 绑定边界	ES6具体体现
    new Vue({
        el: '#app',
        data() {
            return {
                f200: 'f200'
            };
        },
        methods: {
            red() {
                alert("red(红色)");
            },
            orange() {
                alert("orange(橙色)");
            },
            blue() {
                alert("blue(蓝色)");
            },
            black() {
                alert("black(黑色)");
            }
        }
    })
</script>

</html>

When we add the .stop modifier

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>事件处理器</title>
    <!--  jQuery-->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <!--  vue.js-->
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script>
</head>
<style>
    .red {
        width: 400px;
        height: 400px;
        background-color: red;
    }

    .orange {
        width: 300px;
        height: 300px;
        background-color: orange;
    }

    .blue {
        width: 200px;
        height: 200px;
        background-color: blue;
    }

    .black {
        width: 500px;
        height: 500px;
        background-color: black;
    }
</style>
<body>
<!-- 定义边界 -->
<div id="app">
    <p>冒泡事件</p>
    <div class="black" @click.stop="black">
        <div class="red" @click.stop="red">
            <div class="orange" @click.stop="orange">
                <div class="blue" @click.stop="blue">
                </div>
            </div>
        </div>
    </div>
</div>
</body>
<script type="text/javascript">
    // 绑定边界	ES6具体体现
    new Vue({
        el: '#app',
        data() {
            return {
                f200: 'f200'
            };
        },
        methods: {
            red() {
                alert("red(红色)");
            },
            orange() {
                alert("orange(橙色)");
            },
            blue() {
                alert("blue(蓝色)");
            },
            black() {
                alert("black(黑色)");
            }
        }
    })
</script>

</html>

3. Trigger case (.once)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>事件处理器</title>
    <!--  jQuery-->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <!--  vue.js-->
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script>
</head>
<body>
<!-- 定义边界 -->
<div id="app">
    <p>点击</p>
    <input :value="msg"/>
    <button @click="dosub">提交</button>
</div>
</body>
<script type="text/javascript">
    // 绑定边界	ES6具体体现
    new Vue({
        el: '#app',
        data() {
            return {
                msg: '偶买噶'
            };
        },
        methods: {
            dosub() {
                alert(this.msg);
            }
        }
    })
</script>

</html>

You can only click once after adding .once

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>事件处理器</title>
    <!--  jQuery-->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <!--  vue.js-->
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script>
</head>
<body>
<!-- 定义边界 -->
<div id="app">
    <p>点击</p>
    <input :value="msg"/>
    <button @click.once="dosub">提交</button>
</div>
</body>
<script type="text/javascript">
    // 绑定边界	ES6具体体现
    new Vue({
        el: '#app',
        data() {
            return {
                msg: '偶买噶'
            };
        },
        methods: {
            dosub() {
                alert(this.msg);
            }
        }
    })
</script>

</html>

4. Comprehensive case (form)

It should be noted that hobbyMax in the checkbox v-model="hobbyMax" uses an array to receive

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>表单</title>
    <!--  jQuery-->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <!--  vue.js-->
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script>
</head>
<body>
<div id="app">
    <label>姓名:</label><input v-model="username"/><br/>
    <label>密码:</label><input v-model="pwd" type="password"/><br/>
    <!-- 将用户的输入值转为 Number 类型 -->
    <label>年龄:</label><input v-model.number="age" type="number"/><br/>
    <label>性别:</label>
    <div v-for="s in sexMax">
        <input type="radio" v-model="sex" name="sex" v-bind:value="s.id"/>{
   
   {s.name}}<br/>
    </div>
    <label>爱好:</label>
    <div v-for="h in hobby">
        <input type="checkbox" v-model="hobbyMax" v-bind:value="h.id"/>{
   
   {h.name}}
    </div>
    <label>类别:</label>
    <select v-model="type">
        <option v-for="t in types" v-bind:value="t.id">{
   
   {t.name}}</option>
    </select><br/>
    <label>备注:</label>
    <!--    v-bind:value="info"-->
    <textarea v-model="info"></textarea><br/>
    确认<input type="checkbox" v-model="flag"/>
    <input type="submit" v-bind:disabled="show" v-on:click="doSubmit"/>
</div>
</body>
<script type="text/javascript">
    new Vue({
        el: '#app',
        data() {
            return {
                username: null,
                pwd: null,
                age: 10,
                sex: 1,
                sexMax: [{id: 1, name: "男"}, {id: 2, name: "女"}, {id: 3, name: "其他"}],
                hobby: [
                    {
                        id: 1,
                        name: '篮球'
                    },
                    {
                        id: 2,
                        name: '唱'
                    },
                    {
                        id: 3,
                        name: '跳'
                    },
                    {
                        id: 4,
                        name: 'rap'
                    }],
                hobbyMax: [],
                types: [
                    {
                        id: 1,
                        name: '职业人'
                    },
                    {
                        id: 2,
                        name: '学生'
                    },
                    {
                        id: 3,
                        name: '社会人'
                    }],
                type: null,
                info: '请输入你的个性签名',
                flag: false
            }
        },
        computed: {
            show: function () {
                return !this.flag;
            }
        },
        methods: {
            doSubmit: function () {
                var obj = {
                    username: this.username,
                    pwd: this.pwd,
                    age: this.age,
                    sex: this.sex,
                    hobbyMax: this.hobbyMax,
                    type: this.type,
                    info: this.info,
                }
                console.log(obj);
            }
        }

    })
</script>
</html>

Effect demonstration

2. Custom components

1. vue component

 1.1. Introduction to components

      Component is one of the most powerful features of Vue

      Components can extend HTML elements and encapsulate reusable code

      The component system allows us to build large applications with independent and reusable small components. The interface of almost any type of application can be abstracted into a component tree.

  1.2. Global and local components

  • Global component : Vue.component(tagName, options) , tagName is the component name, and options are configuration options.
  • Local component : new Vue({el:'#d1',components:{...}})

      After registration, we can call the component using:

<tagName></tagName>

  1.3 props

      props is a custom property used by the parent component to pass data.

The data of the parent component needs to be passed to the child component through props, and the child component needs to explicitly declare "prop" using the props option.

   1: Because components are reusable Vue instances, they receive the same options as new Vue, such as data, computed, watch, methods

        And life cycle hooks, etc. The only exceptions are root-instance-specific options like el.

   2: When we define this <button-counter> component, you may find that its data does not directly provide an object like this

  

      data: {

          count: 0

        }

        Instead, a component's data option must be a function, so each instance can maintain a separate copy of the returned object:

        data: function () {

          return {

            count: 0

          }

        }

    3: There are two ways to define component names

         Names separated by dashes (recommended)

         Vue.component('my-component-name', { /* ... */ }),

引用方式:<my-component-name>

         Capitalize the first letter of the name

       

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

    4: Attribute names in HTML are case-insensitive, so the browser will interpret all uppercase characters as lowercase characters. This means that when you use templates from the DOM,

         CamelCase prop names need to be named using their equivalent kebab-case names:

       

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

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

         It is expected that each prop has a specified value type  

       props: {

           title: String,

           likes: Number,

           isPublished: Boolean,

           commentIds: Array,

           author: Object,

           callback: Function,

           contactsPromise: Promise // or any other constructor

         }

2. Case

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>组件</title>
    <!--  jQuery-->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <!--  vue.js-->
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script>
</head>
<body>
<!-- 定义边界 -->
<div id="app">
    <!-- 定义组件不能用驼峰命名 -->
    <!-- 需求是:当引用一个myButton,也页面上一个独特标记按钮 -->
    <my-img></my-img>
    <my-button m="卡拉米"></my-button>

    <!-- <button onclick=""></button> -->
</div>
</body>
<script type="text/javascript">
    Vue.component('my-button', {
        // props是定义组件中的变量的
        props: ['m'],
        // template代表了自定义组件在页面上显示的类容
        template: '<button v-on:click="incrn">我被{
   
   {m}}点击{
   
   {n}}次</button>',
        data: function () {
            return {
                n: 1
            }
        },
        methods: {
            incrn() {
                this.n++;
            }
        }
    });
    Vue.component('my-img', {
        // template代表了自定义组件在页面上显示的类容
        template: '<img style="width: 100px;height: 100px;" src="https://ts1.cn.mm.bing.net/th/id/R-C.b0ea268fa1be279d112489ce83ad4696?rik=qItsh%2fBiy33hlg&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140303%2f1-140303215009.jpg&ehk=S6PLWamt%2bMzQV8uO9ugcU5d5M19BpXtCpNz2cRJ7q9M%3d&risl=&pid=ImgRaw&r=0">',
    });
    // 绑定边界	ES6具体体现
    new Vue({
        el: '#app',
        data() {
            return {};
        }
    })
</script>

</html>

3. Component communication

1. Custom events

  1.    Listening for events : $on(eventName)
  2.    Trigger event : $emit(eventName)

   1.1. Vue custom events are designed for communication between components  

        In Vue, the parent component passes data to the child component through prop. If you want to pass the data of the child component to the parent component, you can bind the custom event.

  1.         Parent Vue->child Vue, pass data through prop
  2.         Child Vue->parent Vue, pass data through events

   1.2. Event name

        Unlike components and props, there is no automatic case conversion for event names. Instead, the name of the triggered event needs to exactly match the name used to listen for this event.

        It is recommended to use "dash separated names"

2. Case

2.1. Pass from father to son

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>通信</title>
    <!--  vue.js-->
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script>
</head>
<body>
<div id="app">
    <h3>父传子1</h3>
    <my-button m="牛马"></my-button>
    <h3>父传子2</h3>
    <my-button m="小卡拉米" n="2"></my-button>
</div>
</body>
<script>
    // 定义全局组件的方式
    Vue.component('my-button', {
        props: ['m', 'n'],
        template: '<button v-on:click="MyButton">{
   
   {m}}被点了{
   
   {n}}次</button>',
        data: function () {
            return {
                n: 1
            };
        },
        methods: {
            MyButton: function () {
                this.n++;
            }
        }
    })
    var vm = new Vue({
        el: "#app",
        data: {
            msg: "999"
        }
    });
</script>
</html>

2.2, child father

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>通信</title>
    <!--  vue.js-->
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.10/vue.js"></script>
</head>
<body>
<div id="app2">
    <h3>子传父</h3>
    <!-- 使用自定义组件my-button的时候进行传值(相当于jsp标签往助手类中传值的概念) -->
    <my-buttons m="666" @getBut="getXx"></my-buttons>
</div>
</body>
<script>
    // 定义全局组件的方式
    Vue.component('my-buttons', {
        props: ['m'],
        template: '<button v-on:click="MyButton">{
   
   {m}}被点了</button>',
        methods: {
            MyButton: function () {
                let id = 123;
                let name = "天才";
                this.$emit('getbut', id, name);
            }
        }
    })
    var vm = new Vue({
        el: "#app2",
        data: {
            msg: "666"
        },
        methods: {
            getXx: function (a, b) {
                console.log(a);
                console.log(b);
            }
        }
    });
</script>
</html>

Guess you like

Origin blog.csdn.net/weixin_74383330/article/details/133063543