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>
相关推荐
前端付豪22 分钟前
Vue 中的 JSX:让组件渲染更灵活的正确方式
前端·javascript·vue.js
apollo_qwe1 小时前
Vue 权限控制神技!自定义 auth 指令优雅实现按钮级权限管理
vue.js·架构
阿登林2 小时前
Vue面试项目经验分享:如何专业展示技术能力与解决问题
vue.js·经验分享·面试
黄交大彭于晏2 小时前
UniApp 全局通知功能实现
前端·vue.js·uni-app
一 乐2 小时前
流浪动物救助|流浪猫狗救助|基于Springboot+vue的流浪猫狗救助平台设计与实现(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·毕设
国思RDIF框架2 小时前
国思RDIF低代码快速开发框架 v6.2.2版本发布
前端·vue.js·后端
小高0073 小时前
深入理解 package.json:前端项目的 "身份证"
前端·javascript·vue.js
lichenyang4533 小时前
Next.js 学习笔记:从约定式路由到 Tailwind、Image、Font 优雅整合。
前端·javascript·全栈
修罗-zero3 小时前
vue在获取某一个div的大小,怎么确保div渲染好,内容撑开后才去获取大小
前端·javascript·vue.js
咫尺的梦想0073 小时前
vue笔记(第一天)
前端·vue.js·笔记