首页 > 其他分享 >Vue-插槽及自定义事件分发

Vue-插槽及自定义事件分发

时间:2023-09-23 15:55:47浏览次数:35  
标签:Vue 自定义 插槽 绑定 vue 组件 页面

一.插槽slot

在某些场景中,我们可能想要为子组件传递一些模板片段,让子组件在它们的组件中渲染这些片段。

<slot> 元素是一个插槽出口 (slot outlet),标示了父元素提供的插槽内容 (slot content) 将在哪里被渲染。

 插槽就好比一个占位符,它不是解决页面必须元素的位置,而是解决未知元素的位置,好比:页面导航栏,有那些导航指向哪里都是写死的,网站不倒闭他都不变的,是不需要使用插槽的,

最该使用插槽的应该是数据库中查询出来的数据,这类数据在页面显示有一个很明显的特点:每个人的数据查询都是不一样的,数据条目也是不一样的,所以很难从HTML+CSS的架构来完美构造接收数据库数据的前端页面,

所以vue作为一个专注视图层的js库,插槽的概念就孕育而生,它使用slot标签在页面进行占位,数据库数据不会先到页面上,而是先到vue的组件中去,把数据按条目整理好了再去页面代替slot插槽的位置,完成无差别渲染

这样对不同数据量的页面很友好,使得前端也能工程化,结构化

代码展示:

<div id="app">
<msf>
<!--  插槽位置需要绑定插槽组件,用于传参到那个组件内,数据一般是页面先获取到,获取到后由插槽和组件渲染-->
  <msf-title slot="msf-title" :title="title"></msf-title>
  <msf-body slot="msf-body" v-for="a in args" :arg="a"></msf-body>
</msf>
</div>

<script>
  //组件内部留有插槽
  Vue.component('msf',{
    //绑定插槽位置,每个slot标签使用前都需要绑定
    template: '<div>\
    <slot name="msf-title"></slot>\
    <ul>\
    <slot name="msf-body"></slot>\
    </ul>\
    <div></div>'
  });
  //插槽:根据数据库条目动态改变页面内容
  Vue.component('msf-title',{
    props: ['title'],
    template: '<div>{{title}}</div>'
  })
  Vue.component('msf-body',{
    props: ['arg'],
    template: '<li>{{arg}}</li>'
  })
  let vue = new Vue({
    el: "#app",
    data: {
      title: '计算机必修课程',
      args: ['java','mysql','spring','js']
    }
  });
</script>

 

如上代码,我们需要知道四个域:

页面占位插槽,组件,插槽,model层数据域

利用vue绑定app元素,使得在model层数据都可以在此范围内使用,在页面占位插槽也在这个区域内,先使用一个组件,这个组件是用来控制格式的,比如美化插槽这块区域,使得这块区域更好看

组件如果需要美化插槽的部分,那么就需要在美化的位置也加入插槽slot标签,并且需要在name属性下填写插槽的名字,用于绑定唯一插槽

插槽要做的就是自己是使用什么方式输出,以及接收参数,如:使用h标签,p标签,li标签来装饰输出数,接收参数需要页面占位插槽绑定

页面占位插槽需要两个属性,slot属性:标识model穿过来的数据放在那个插槽内,需要传到这个插槽,v-指令:用于绑定model层,数据双向绑定,也是让model层知道数据到底传到哪里

插槽代码结果展示:

 二.自定义事件内容分发

自定义事件分发指的是在插槽的基础上,写入一些事件来操作数据,写入事件是很简单的,但是实际操作数据就很难了

首先在插槽中只能使用自己的方法属性,它是不能调用到实例化的Vue对象中的方法的,但是使用插槽位置的方法又操作不了model层的数据

所以我们要想怎么在插槽的方法调用到Vue实例化对象中的方法,利用它来操作model层的数据

Vue官方提供了一个方法:this.$emit()  来调用自定义的方法

代码展示:

<div id="app">
    <mm>
        <mm-body slot="mm-body" v-for="(arg,index) in args" :arg="arg" :index="index" v-on:removed="VueRemoved(index)"></mm-body>
    </mm>
</div>

<script>
    Vue.component('mm',{
        template: '<div>\
        <ul>\
        <slot name="mm-body"></slot>\
        </ul>\
        </div>'
    });
    Vue.component('mm-body',{
        props: ['arg','index'],
        template: '<li>{{arg}}<button v-on:click="removed">删除</button></li>',
        methods:{
            removed: function (index) {
                this.$emit('removed',index);
            }
        }
    })
    let vue = new Vue({
        el: "#app",
        data: {
            args: ['神里凌华','雷电将军','神里绫人','枫原万叶','流浪者']
        },
        methods:{
            VueRemoved: function (index) {
                this.args.splice(index,1);
            }
        }
    });
</script>

 

这个小案例讲的是插槽或者组件加入一些事件的操作方法,

但是映射到vue的大知识点是:组件只能直接调用自己的方法(methods),而组件不能直接操作model层的数据,而vue中的实例方法(methods)可以直接操作model层数据,因为它们位于同一域中,都在Vue实例对象之中。

在这里我们要清楚vue的两步操作:

  • 绑定
  • 传入

我们说了,触发事件的按钮是在组件中的,所以触发事件也只能在组件中触发,但是要操作的数据的方法在vue实例中,得想想怎么让这个实例方法进来,思考view层的数据是怎么到组件中去的,传入,通过v-bind:组件参数 = 'view层参数',这就是关键,需要的vue实例方法可以通过传入的方式到组件中去,所以v-on:removed = VueRemoved(index) 这就是传入组件的操作,好了我们已经解决了一个view层的方法怎么送到组件中去了

接着,view层的方法怎么来呢,这个方法肯定是vue实例中的,这就是vue实例中el属性的功劳了,它绑定的区域内都可以使用此个vue实例,然后后v-on指令是专门用于view绑定vue实例中的事件的,所以使用v-on:="VueRemoved",就可以使得将方法绑定到view层中去,完整的v-on:removed = VueRemoved(index),既包含了绑定vue实例中的方法,也包含了将绑定方法传入到组件中去

完成上面一步后,在组件中removed就是VueRemoved的一个映射,所以我们可以直接调用它,这个自定义方法使用:this.$emit()   来完成调用

 自定义事件内容分发结果展示:

 按钮点击可删除

标签:Vue,自定义,插槽,绑定,vue,组件,页面
From: https://www.cnblogs.com/5ran2yl/p/17724140.html

相关文章

  • vue中created和mounted区别
    在Vue.js中,created和mounted都是生命周期钩子函数,用于在组件不同的生命周期阶段执行代码。它们的主要区别如下:1.created钩子函数:2.created在组件实例被创建后立即调用。此时组件的实例已经被创建,并且组件的数据观测(dataobservation)和事件机制已经初始化完成。3.created......
  • ts和vue3的结合常见的一些问题(持续更新)
    特此注意是vue3,而不是vue2使用typescript的interface关键词定义一个存数据的数据类型interfacePosition{long:number,lnt:number,height:number}constposition=ref<Position>({long:0,lnt:0,height:0})......
  • vue2 访问网关的时候post无法请求
    问题复现:后台使用微服务的框架在consul配置并使用网关进行代理。 问题描述:前台访问网关调用后台方法 请求方式为get时正常使用~post时显示跨域问题 post访问路径正常但就是无效果显示跨域问题报错解决方法:module.exports=defineConfig({......
  • vue3的面试题
    1.什么是Vue3?Vue3有哪些新增特性?答:Vue3是Vue.js框架的最新版本,它增加了很多新特性,包括CompositionAPI、Teleport、Suspense和Fragment等。2.Vue3CompositionAPI是什么?它的作用是什么?答:Vue3CompositionAPI是Vue3中的一个新特性,它的作用是将组件中的逻辑分解成可复用的可......
  • 【Java 基础篇】Java 比较器排序:精通自定义对象排序
    在Java编程中,排序是一个非常常见且重要的操作。Java提供了多种排序机制,其中之一就是使用比较器(Comparator)进行排序。比较器允许您自定义对象的排序方式,使您能够实现各种排序需求,从简单的对象排序到复杂的多属性排序。本篇博客将从入门到高级,详细介绍Java比较器排序的使用。什......
  • 全面分析 Vue 的 computed 和 watch 的区别
    全面分析Vue的computed和watch的区别 一、computed介绍computed用来监控自己定义的变量,该变量在data内没有声明,直接在computed里面定义,页面上可直接使用。//基础使用{{msg}}<inputv-model="name"/>//计算属性computed:{msg:function(){retur......
  • 【vue2】 demo1
    练习用的<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title><scriptsrc="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>......
  • Vue.js 3.0 promise的运用
    ......
  • vue3 defineEmits的使用
    1.计数器案例父组件:<template><h2>当前计数为:{{counter}}</h2><HelloWorld@add1="add1"@decre1="decre1"></HelloWorld></template><scriptsetup>import{ref}from'vue'import......
  • vue前端导出pdf
    functionexportDataPdf(el,fileName,splitClassName){ //防止页面数据被切割 constA4_WIDTH=595 constA4_HEIGHT=842 el.style.height='initial' constpageHeight=el.scrollWidth/A4_WIDTH*A4_HEIGHT //获取分割dom,此处为class类名为item......