[Vue] Sintaxis de plantilla, controladores de eventos y casos completos, componentes personalizados, comunicación de componentes

1. Controlador de eventos

Anteriormente utilizamos la directiva v-on para el monitoreo de eventos.

1. modificador de evento

En Vue llamamos modificadores mediante el sufijo de instrucción representado por un punto (.) , como por ejemplo:

  1.  .stop : evita que el evento se propague. Este modificador evitará que el evento se propague más al elemento principal cuando se active el evento. Equivale a llamar event.stopPropagation()
  2.   .prevent : previene el evento predeterminado. De forma predeterminada, algunos elementos tienen comportamientos de eventos predeterminados, como <a>saltos de clic en etiquetas, que .prevent se pueden usar para evitar que se activen los eventos predeterminados. Es equivalente a llamar  event.preventDefault().
  3.   .capture : utiliza el modo de captura de eventos. De forma predeterminada, los eventos se manejan en la fase de difusión (es decir, desde elementos secundarios hasta elementos principales). Utilice  modificadores para mover el manejo de eventos a la etapa de captura de eventos (es decir, del elemento principal al elemento secundario). .capture
  4.   .self : solo desencadena eventos en el propio elemento actual. Cuando un evento está vinculado a un elemento secundario, este modificador solo permite que el evento se active en el elemento secundario, pero no el mismo evento en el elemento principal.
  5.   .once :: Activa el evento solo una vez. Utilice  .once modificadores para asegurarse de que el evento solo se active una vez, después de lo cual el detector de eventos se elimina automáticamente.
  <!-- 阻止单击事件冒泡 -->
  <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. Caja de burbujas (.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>

Cuando agregamos el modificador .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.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. Caso de activación (.una vez)

<!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>

Solo puedes hacer clic una vez después de agregar .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. Caso integral (formulario)

Cabe señalar que hobbyMax en la casilla de verificación v-model="hobbyMax" usa una matriz para recibir

<!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>

Demostración de efectos

2. Componentes personalizados

1. componente de vista

 1.1 Introducción a los componentes

      El componente es una de las características más poderosas de Vue

      Los componentes pueden ampliar elementos HTML y encapsular código reutilizable.

      El sistema de componentes nos permite construir aplicaciones grandes con componentes pequeños independientes y reutilizables. La interfaz de casi cualquier tipo de aplicación se puede abstraer en un árbol de componentes.

  1.2 Componentes globales y locales

  • Componente global : Vue.component(tagName, opciones) , tagName es el nombre del componente y las opciones son opciones de configuración.
  • Componente local : nuevo Vue({el:'#d1',components:{...}})

      Después del registro, podemos llamar al componente usando:

<tagName></tagName>

  1.3 accesorios

      props es una propiedad personalizada utilizada por el componente principal para pasar datos.

Los datos del componente principal deben pasarse al componente secundario a través de accesorios, y el componente secundario debe declarar explícitamente "prop" mediante la opción de accesorios.

   1: Debido a que los componentes son instancias de Vue reutilizables, reciben las mismas opciones que el nuevo Vue, como datos, cálculo, observación y métodos.

        Y ganchos del ciclo de vida, etc. Las únicas excepciones son las opciones específicas de la instancia raíz como el.

   2: Cuando definimos este componente <button-counter> , es posible que sus datos no proporcionen directamente un objeto como este

  

      data: {

          count: 0

        }

        En cambio, la opción de datos de un componente debe ser una función, de modo que cada instancia pueda mantener una copia separada del objeto devuelto:

        data: function () {

          return {

            count: 0

          }

        }

    3: Hay dos formas de definir nombres de componentes

         Nombres separados por guiones (recomendado)

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

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

         Poner en mayúscula la primera letra del nombre.

       

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

    4: Los nombres de atributos en HTML no distinguen entre mayúsculas y minúsculas, por lo que el navegador interpretará todos los caracteres en mayúscula como caracteres en minúscula. Esto significa que cuando usas plantillas del DOM,

         Los nombres de accesorios de CamelCase deben nombrarse usando sus nombres equivalentes de kebab-case:

       

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

    5: accesorios: ['título', 'me gusta', 'isPublished', 'commentIds', 'autor']

         Se espera que cada accesorio tenga un tipo de valor específico.  

       props: {

           title: String,

           likes: Number,

           isPublished: Boolean,

           commentIds: Array,

           author: Object,

           callback: Function,

           contactsPromise: Promise // or any other constructor

         }

2. Caso

<!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. Comunicación de componentes

1. Eventos personalizados

  1.    Escuchando eventos : $on(eventName)
  2.    Evento desencadenante : $emit(eventName)

   1.1. Los eventos personalizados de Vue están diseñados para la comunicación entre componentes.  

        En Vue, el componente principal pasa datos al componente secundario a través de prop. Si desea pasar los datos del componente secundario al componente principal, puede vincular el evento personalizado.

  1.         Parent Vue->child Vue, pasar datos a través de prop
  2.         Child Vue->parent Vue, pasar datos a través de eventos

   1.2 Nombre del evento

        A diferencia de los componentes y accesorios, no existe una conversión automática de casos para los nombres de eventos. En cambio, el nombre del evento desencadenado debe coincidir exactamente con el nombre utilizado para escuchar este evento.

        Se recomienda utilizar "nombres separados por guiones".

2. Caso

2.1. Pasar de padre a hijo

<!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, padre hijo

<!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>

Supongo que te gusta

Origin blog.csdn.net/weixin_74383330/article/details/133063543
Recomendado
Clasificación