vue3(六)-基础入门之自定义组件与插槽、ref通信

一、全局组件

html:

html 复制代码
<div id="app">
   <mytemplace></mytemplace>
</div>

javascript:

html 复制代码
<script>
      const { createApp } = Vue
      const app = createApp({})
      app
        .component('mytemplace', {
          template: '<div><button>返回</button></div>'
        })
        .mount('#app')
</script>

结果展示:

二、局部组件

  • 局部组件只能在父组件中使用,其他组件无法使用该局部组件
  • 父组件与子组件属性和方法不能共享

html:

html 复制代码
<div id="app">
   <mytemplate></mytemplate>
</div>

javascript:

html 复制代码
<script>
      const { createApp, ref } = Vue
      const app = createApp({})
      app
        .component('mytemplate', {
          template:
            '<div> <input type="text" v-model="inputText" /><childTemplate @click="buttonClk"></childTemplate><ul><li v-for="item in myDataList">{{ item }}</li></ul></div>',
          data() {
            return {
              myDataList: ['123', '123qwe', 'aaa'],
              inputText: ''
            }
          },
          methods: {
            buttonClk() {
              console.log('自定义组件-父组件点击事件')
            }
          },
          components: {
            childTemplate: {
              template: '<button @click="childButtonClk">点击</button>',
              methods: {
                childButtonClk() {
                  console.log('自定义组件-子组件点击事件')
                }
              }
            }
          }
        })
        .mount('#app')
</script>

1.结果展示:

2.点击按钮输出结果:

三、父组件与子组件之间的传参

1、父传子

父传子通过属性向下传递:在子组件中自定义属性名,并传递相应的参数过去。子组件通过 props 接受传过来的参数

html 复制代码
<body>
    <div id="app">
      <mytemplace mypros="传递固定参数"></mytemplace>
      <mytemplace :mypros="parentProps"></mytemplace>
      <mytemplace :mypros="parentProps" :mypros1="parentProps1"></mytemplace>
    </div>
    <script src="./lib/vue.global.js"></script>
    <script>
      const { createApp } = Vue
      const app = createApp({
        data() {
          return {
            parentProps: '传递动态参数属性前加冒号',
            parentProps1: true
          }
        }
      })
      app
        .component('mytemplace', {
          template: '<div><button>{{mypros+"-"+mypros1}}</button></div>',
          //属性校验,指定参数类型
          props: {
            mypros: String,
            mypros1: Boolean
          }
          // props: ['mypros', 'mypros1']
        })
        .mount('#app')
    </script>
</body>

2、子传父

子传父通过事件传递参数:子组件的点击事件通过 this.$emit(父组件中自定义的事件名称, 传递的参数) 传递参数到父组件;父组件通过自定义事件接收参数

html 复制代码
<body>
    <div id="app">
      <mytemplace @myevent="parentClick($event)"></mytemplace>
    </div>
    <script src="./lib/vue.global.js"></script>
    <script>
      const { createApp } = Vue
      const app = createApp({
        methods: {
          parentClick(e) {
            console.log('父组件点击:' + e)
          }
        }
      })
      app
        .component('mytemplace', {
          data() {
            return { childProp: '子组件属性' }
          },
          template: '<div><button @click="childClick()">返回</button></div>',
          methods: {
            childClick() {
              this.$emit('myevent', this.childProp)
            }
          }
        })
        .mount('#app')
    </script>
</body>

四、slot 插槽

当需要在子组件标签中插入一个或多个 父组件的标签时,需要在子组件中定义一个 slot 标签

1、具名插槽: 在子组件中通过 name 属性为插槽取名,在 template 标签中通过 v-slot:插槽名(或者:#插槽名) 选择对应的插槽

html :

html 复制代码
<div id="app">
  <myslot>
    <template v-slot:slot1>插槽1</template>
    <template v-slot:slot2>插槽2</template>
    <template #slot3>插槽3</template>
  </myslot>
</div>

js :

html 复制代码
<script>
const app = Vue.createApp({
  data () {
    return { chooseValue: 'component1' }
  },
  components: {
    myslot: {
      template:
        '<div><button>组件</button><input type="text"/><slot name="slot1"></slot><slot name="slot2"></slot><slot name="slot3"></slot></div>'
    }
  }
}).mount('#app')
</script>

2、默认内容: 当父组件没有内容替换插槽时,在 < slot > 标签中的内容回被视为默认内容显示出来

html :

html 复制代码
<defaultslot> </defaultslot>

js :

javascript 复制代码
const app = Vue.createApp({
  data () {
    return { chooseValue: 'component1' }
  },
  components: {
    defaultslot: {
      template:
        '<div><button>组件</button><input type="text"/><slot>默认内容</slot></div>'
    }
  }
}).mount('#app')

结果展示 :


3、动态插槽名: 通过 #[动态插槽名] (或者 v-slot:[动态插槽名]) 动态选择插槽(动态插槽名必须为小写

html 复制代码
<myslot>
 <template #[slotname]>插槽1</template>
</myslot>

<select v-model="slotname">
<option value="slot1">插槽1</option>
<option value="slot2">插槽2</option>
<option value="slot2">插槽3</option>
</select>
javascript 复制代码
const app = Vue.createApp({
  data () {
    return { slotname: 'slot1' }
  },
  components: {
    myslot: {
      template:
        '<div><button>组件</button><input type="text"/><slot name="slot1">插槽11</slot><slot name="slot2">插槽22</slot><slot name="slot3">插槽33</slot></div>'
    }
  }
}).mount('#app')

A、结果展示:初始下拉框默认为插槽1,所以第一个插槽被替换,其他2个插槽使用默认内容

B、结果展示:选择插槽2后,第二个插槽被替换,其他2个插槽使用默认内容

4、默认插槽传参

html 复制代码
<scopeslot v-slot="slotvalue">
	{{ slotvalue.text }} {{ slotvalue.count }}
</scopeslot>
html 复制代码
<script>
scopeslot: {
      data () {
        return { greetingMessage: 'hello' }
      },
      template: '<div><slot :text="greetingMessage" :count="1"></slot></div>'
}
</script>

结果展示:

5、具名插槽传参:

html :

html 复制代码
<scopeslot1>
    <template v-slot="info">{{ info.message }} {{ info.age }}</template>
    <template #scope1="{message,age}">{{ message }} {{ age }}</template>
</scopeslot1>

js:

html 复制代码
<script>
scopeslot1: {
      template:
        '<div><slot message="无名插槽" age="18"></slot>--<slot name="scope1" message="具名插槽" age="20"></slot></div>'
}
</script>

五、ref 通信

子组件(标签)中定义 ref 属性后,可以通过 this.$refs.ref属性名 获得子组件(标签)对象,从而获取子组件(标签)的控制权

html 复制代码
<body>
    <div id="app">
    	<!-- 通过ref获取输入框的内容 -->
      <input type="text" ref="myInputText" />
      <mytemplace ref="myRef"></mytemplace>
      <button @click="parentClick">父组件点击事件</button>
    </div>
    <script src="./lib/vue.global.js"></script>
    <script>
      const { createApp } = Vue
      const app = createApp({
        data() {
          return { parentPro: 'refTest' }
        },
        methods: {
          parentClick() {
            this.$refs.myRef.childClick(this.parentPro)
          }
        }
      })
      app
        .component('mytemplace', {
          data() {
            return { childProp: '子组件属性' }
          },
          template: '<div><button @click="childClick()">返回</button></div>',
          methods: {
            childClick(e) {
              console.log('子组件点击事件', e)
            }
          }
        })
        .mount('#app')
    </script>
</body>
相关推荐
2501_944526422 分钟前
Flutter for OpenHarmony 万能游戏库App实战 - 关于页面实现
android·java·开发语言·javascript·python·flutter·游戏
壹号机长12 分钟前
canvas烟花特效各种前端框架都可以使用H5,vue,react,
vue.js·react.js·前端框架
咸鱼2.013 分钟前
【java入门到放弃】VUE部分知识点
java·javascript·vue.js
web小白成长日记33 分钟前
Vue3中如何优雅实现支持多绑定变量和修饰符的双向绑定组件?姜姜好
前端·javascript·vue.js
十六年开源服务商1 小时前
WordPress在线聊天系统推荐
大数据·javascript·html
喵喵喵小鱼1 小时前
arcgis JavaScript api实现同时展示多个撒点气泡
开发语言·javascript·arcgis
谢尔登2 小时前
Vue3架构设计——调度系统
前端·javascript·vue.js
Kratzdisteln2 小时前
【1902】0121-1 Dify工作流节点详细配置(方案B最终版)
java·前端·javascript
霍理迪2 小时前
js数据类型与运算符
开发语言·前端·javascript
Hi_kenyon2 小时前
小白理解main.js
前端·javascript·vue.js