vue3 - 组件注册和组件通信(setup语法糖)

news2025/1/31 8:18:53

这里介绍的是vue3中组件的注册和组件通信父传子,子传父。
前提:用的是vue3版本且使用了setup语法糖 <script setup> .....<script>

1,组件注册

1.1,全局注册:

全局注册需要在 在main.js中进行注册;
全局注册的组件可以在此应用的任意组件的模板中使用;

import { createApp } from "vue";
这是两个组件
import InputList from "@/components/component/Input.vue";
import Footer from "@/components/component/Footer.vue";

const app = createApp(App);
可以进行链式注册
app.component('InputList',InputList).component('Footer',Footer)

1.2,局部注册

<script setup>
import { reactive, ref, createApp } from "vue";
/* 组件局部注册 */
const app = createApp({});
import InputList from "@/components/component/Input.vue";
app.component({
  InputList,
});
</script>

2,组件通信

2.1,父传子

组件传值和vue2的原理是一样的,用自定义属性进行传值;
在使用 <script setup> 的单文件组件中,props 可以使用 defineProps() 宏来声明:

父组件:

<script setup>
import { reactive, ref, createApp } from "vue";
/* 父组件需要传给子组件的值 */
const inputList = ref([
  {
    name: "胡桃",
    age: 18,
    value: "112222222222",
  },
  {
    name: "行秋",
    age: 20,
    value: "1333333333333",
  },
  {
    name: "钟离",
    age: 5000,
    value: "14444444444444",
  },
]);
</script>

<template>
  <div class="demo">
    <h3>组件使用:</h3>
    <InputList foo="aaa" :phoneList="inputList" @submit="submit" />
  </div>
</template>

可以看到这里使用了 InputList 组件,传了一个字符串(aaa)和一个数组(inputList);
注意: 自定义属性如果前面不加冒号(:)会默认你传的是一个字符串,加上冒号才说明你在此处引用的是一个变量;

子组件:

子组件可以更细致地声明对传入的 props 的校验要求,是否必传,是否有默认值;
接收对象或数组的默认值 必须从一个工厂函数返回才可以使用;

<script setup>
/* 这种形式是针对 setup语法糖的写法
 * 允许接收多个属性
 */
const props = defineProps({
  // foo是我从父元素传进来的字符串
  foo: {
    type: String, //类型约定
    required: false, //是否必传
    default: "bbb", // 默认值 不传的时候触发 传空字符也不会触发
  },

  /* phoneList 是一个数组
    对象或数组的默认值
    必须从一个工厂函数返回。 
    该函数接收组件所接收到的原始 prop 作为参数
    */
  phoneList: {
    type: Array,
    required: true,
    // 父组件不传则会使用下面的值
    default(Props) {
      return [
        {
          name: "胡桃",
          age: 18,
          value: "112222222222",
        }
        ....
      ];
    },
  },
});
console.log("props:", props);
</script>

2.2,子传父

在子组件的模板中,可以直接使用 $emit 方法触发自定义事件进行传值;如图所示:

在这里插入图片描述
子组件:

<script setup>
import { reactive, ref } from "vue";

/* 我们在 <template> 中使用的 $emit 方法不能在组件的 <script setup> 部分中使用,但 defineEmits() 会返回一个相同作用的函数供我们使用: */
const emit = defineEmits(["submit"]);

/* 确认按钮  点击然后用自定义事件用来传给父组件一些有用的信息 */
const enter = () => {
  // 传给父组件 可以添加参数
  emit("submit",inputList.value);
}
</script>
<template>
  <div class="demo">
      <div class="submit"><button @click="enter">确 认</button></div>
    </div>
  </div>
</template>

父组件:

<script setup>
import { reactive, ref, createApp } from "vue";
// 接收子组件传过来的参数
const submit = (params) => {
  console.log("params", params);
};
</script>

<template>
  <div class="demo">
    <h3>组件使用:</h3>
    <InputList foo="aaa" :phoneList="inputList" @submit="submit" />
  </div>
</template>

3,所有代码

这里是当前案例的所有代码,还不太懂的话可以在看一下;

父组件:

<script setup>
import { reactive, ref, createApp } from "vue";
/* 组件局部注册 */
const app = createApp({});
import InputList from "@/components/component/Input.vue";
app.component({
  InputList,
});

/* 父组件需要传给子组件的值 */
const inputList = ref([
  {
    name: "胡桃",
    age: 18,
    value: "112222222222",
  },
  {
    name: "行秋",
    age: 20,
    value: "1333333333333",
  },
  {
    name: "钟离",
    age: 5000,
    value: "14444444444444",
  },
]);

// 接收子组件传过来的参数
const submit = (params) => {
  console.log("params", params);
};
</script>

<template>
  <div class="demo">
    <h3>组件使用:</h3>
    <InputList foo="aaa" :phoneList="inputList" @submit="submit" />
  </div>
</template>

<style></style>

子组件:

<script setup>
import { reactive, ref } from "vue";
import "./Input.css";

/* 这种形式是针对 setup语法糖的写法
 * 允许接收多个属性
 */
const props = defineProps({
  // foo是我从父元素传进来的字符串
  foo: {
    type: String, //类型约定
    required: false, //是否必传
    default: "bbb", // 默认值 不传的时候触发 传空字符也不会触发
  },

  /* phoneList 是一个数组
    对象或数组的默认值
    必须从一个工厂函数返回。 
    该函数接收组件所接收到的原始 prop 作为参数
    */
  phoneList: {
    type: Array,
    required: true,
    // 父组件不传则会使用下面的值
    default(Props) {
      return [
        {
          name: "胡桃",
          age: 18,
          value: "112222222222",
        },
        {
          name: "行秋",
          age: 20,
          value: "1333333333333",
        },
        {
          name: "钟离",
          age: 5000,
          value: "14444444444444",
        },
      ];
    },
  },
});
console.log("props:", props);

/* 这里对数据做一些拷贝 拷贝之后的数据也是响应式的 因为用的是ref */
const inputList = ref(props.phoneList);

/* 我们在 <template> 中使用的 $emit 方法不能在组件的 <script setup> 部分中使用,但 defineEmits() 会返回一个相同作用的函数供我们使用: */
const emit = defineEmits(["submit"]);

/* 添加按钮 */
const addInput = () => {
  let inputsList = inputList.value;
  if (inputsList.length >= 4) {
    alert("至多只能填写四个");
    return;
  }
  inputList.value.push({
    value: "",
  });
};

/* 删除按钮 */
const delInput = () => {
  let inputsList = inputList.value;
  if (inputsList.length <= 1) {
    alert("至少要填写一个");
    return;
  }
  inputsList.pop();
};

/* 确认按钮  用自定义事件用来传给父组件一些有用的信息 */
const enter = () => {
  const isHaveEmpty = inputList.value.find((item, index) => {
    return item.value === "";
  });
  if (isHaveEmpty) {
    return alert("输入框不能为空!");
  }
  
  // 传给父组件 可以添加参数
  emit("submit",inputList.value);

};
</script>

<template>
  <div class="demo">
    <p>This is a input 组件</p>
    <div class="input">
      <div class="-btn">
        <button class="btn" @click="addInput">点击添加</button>
        <button class="btn" @click="delInput">点击删除</button>
      </div>
      <div class="inpContainer">
        <input
          type="text"
          v-for="item in inputList"
          :key="item.name"
          v-model="item.value"
          class="inp"
        />
      </div>
      <div class="submit"><button @click="enter">确 认</button></div>
    </div>
  </div>
</template>
<style>
.input .-btn {
  width: 200px;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  height: 30px;
}
.btn {
  cursor: pointer;
  margin-left: 10px;
}

.inpContainer {
  display: inline-block;
  width: 50%;
  height: auto;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  flex-wrap: wrap;
}
.inp {
  width: 180px;
  height: 30px;
  margin: 5px 10px;
}
.submit{
  cursor: pointer;
  margin-left: 10px;
}
</style>


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/407643.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot整合调用微信模板方法实现微信公众号消息通知推送,Java实现微信公众号给关注用户推送自定义消息通知(手把手从0到1)

目录 概述 公众号给关注用户推送自定义消息 一、申请公众号模板消息 二、获取安装“web开发者工具” 三、微信网页授权说明 四、微信网页授权 - 流程时序图 五、HTTPClient 实现微信公众号消息推送与发布&#xff08;四步走&#xff09; 六、通过weixin-java-mp SDK实现…

flex布局(弹性盒子一)

目录 一、弹性盒子的开启 二、弹性盒子的不同样式 1.flex-direction&#xff1a;子项目的排列方向 2.flex-wrap&#xff1a;子项目多行 3. flex-flow 是flex-direction和flex-wrap的一起指定&#xff08;简写&#xff09; 一、弹性盒子的开启 设置内容区的样式&#xff1a…

Vue组件库实现按需引入可以这么做

本文为Varlet组件库源码主题阅读系列第七篇&#xff0c;读完本篇&#xff0c;可以了解到如何通过unplugin-vue-components插件来为你的组件库实现按需引入。 手动引入 前面的文章中我们介绍过Varlet组件库的打包流程&#xff0c;最后会打包成几种格式&#xff0c;其中module和…

JavaScript对象

文章目录前言一、对象1.1什么是对象1.2为什么需要对象二、创建对象的三种方式1.利用字面量创建对象2.对象的调用2.1变量、属性、函数、方法总结3.利用new Object创建对象3.1利用构造函数创建对象4.new关键字总结前言 一、对象 1.1什么是对象 现实生活中&#xff1a;万物皆对象…

vue-在组件中使用v-model

一、使用场景 子组件想要使用父组件的值,又想去改父组件的值 二、V-Model的本质 1.给子组件的 value 传个变量 2.监听子组件的input事件,并且把传过来的值赋给父组件的变量 三、关键步骤 1. props 的使用 在自定义的 vue 文件中&#xff0c;声明父组件要向子组件传递的 pr…

左右等高布局

开篇概述 作为这个专栏的开篇&#xff0c;简单介绍一下开这个专栏的初衷。之前在团队中做代码 review 时&#xff0c;经常会发现一些不太“健壮”的 css 代码。这些不太“健壮”的 css 代码&#xff0c;当遇到一些特殊情况时&#xff0c;界面显示就有可能出现问题。其中&#…

uniapp/vue虚拟列表,数据列表渲染优化

引言 相信大家经常会遇到展示一堆数据的需求&#xff0c;几十条数据还好&#xff0c;要是几百上千条&#xff0c;甚至带上了图片。那就会卡得不行。这时候就需要按需加载。 按需加载有懒加载和虚拟列表。 懒加载&#xff1a;通过JS滚动或触底触发事件来加载更多的数据&#…

报错“Cannot read properties of null (reading ‘addEventListener‘)“

场景 控制台报错"Cannot read properties of null (reading addEventListener)" 错误原因 因为 JavaScript 中操作DOM元素的函数方法需要在 HTML 文档渲染完成后才可以使用&#xff0c;如果没有渲染完成&#xff0c;此时的 DOM 树是不完整的&#xff0c;这样在调用…

css鼠标变成小手(css中鼠标悬停是为小手)

CSS控制鼠标样式变换如何写代码呢&#xff1f; 代码&#xff1a;&#xff1a;p stylecursor: crosshair演示&#xff1a;定位指示/p如果需要将鼠标变换成帮助状态的时候。代码&#xff1a;p stylecursor: help演示&#xff1a;帮助/p当然这些只是一些常见的比较实用的代码。我们…

前端实现可拖拽流程的js框架

1 AntV X6 是 AntV 旗下的图编辑引擎&#xff0c;提供了一系列开箱即用的交互组件和简单易用的节点定制能力&#xff0c;方便我们快速搭建 DAG 图、ER 图、流程图等应用。 XFlow是基于 X6 图编辑引擎、面向 React 技术栈用户的专业图编辑应用级解决方案, 帮助您轻松开发复杂的…

前端使用print.js实现打印

前言 项目中经常会用到前端调用浏览器打印的功能&#xff0c;也经常会遇到一些问题&#xff0c;写这篇文章是为了更好的梳理一下相关内容。下面的内容基于vue。 如果需要用到前端生成二维码可以看我的这篇文章&#xff1a;在vue项目中使用qrcodesjs2生成二维码 注&#xff1a…

【学姐面试宝典】—— 前端基础篇Ⅰ(HTTP/HTML/浏览器)

前言 博主主页&#x1f449;&#x1f3fb;蜡笔雏田学代码 专栏链接&#x1f449;&#x1f3fb;【前端面试专栏】 今天开始学习前端面试题相关的知识&#xff01; 感兴趣的小伙伴一起来看看吧~&#x1f91e; 文章目录http 和 https 的基本概念http 和 https 的区别https 协议的工…

【React Router v6】这17个API,你真的都懂了吗?(建议收藏)

😇本文目录😇 Component1.` <BrowserRouter> `2.`<HashRouter>`3.`<Routes />与<Route />`4.`<Link>`5.`<NavLink>`6.`<Navigate />`7.`<Outlet>`Hooks1.`useRoutes()`2.`useNavigate()`3.`useParams()`

【微信小程序】电商移动前端API文档

文章目录一、文档更新说明1、返回值调整2、分类页图片3、订单支付接口二、路径说明三、电商登录实现方式四、API详情1、全局权限访问&#xff08;1&#xff09;主页API获取首页轮播图数据获取首页分类选项数据获取首页楼层数据&#xff08;2&#xff09;商品API商品列表搜索搜索…

pinia详细使用步骤(0基础)

Pinia简介 学vue2的都知道vuex状态管理&#xff0c;所谓状态管理&#xff0c;简单来说就是一个存储数据的地方&#xff0c;存放在Vuex中的数据在各个组件中都能访问到&#xff0c;它是Vue生态中重要的组成部分。 而pinia同理也是起到状态管理的作用&#xff0c;但是它又不完全…

TDesign小程序组件库体验

原来小程序开发有组件库选择的问题&#xff0c;可以使用WeUI或者Vant。今年腾讯开源了前端的框架TDesign&#xff0c;我也分享了两篇使用文章。 年初分享的主要是PC端的框架&#xff0c;除了有PC端的框架外&#xff0c;最近TDesign又新出了小程序的框架&#xff0c;组件比较丰…

前端vue视频vue-video-player插件总结知识点案例(带源码)

目录文档安装main.js文件全局引入视频格式组件方法切换视频清晰度基础案例效果如下完整案例1效果如下完整案例2效果如下最后文档 文档地址 选项参考 API文档 配置函数方法等 Git地址 Git地址 安装 1.vue-video-player 插件下载 npm install vue-video-player --save2.推…

vue3-admin商品管理后台项目(登录页开发和功能实现)

今天来实现vue3-admin商品管理后台项目的登录页功能 首先在pages文件夹下面添加一个login.vue文件&#xff0c;里面先写入简单的template <template><div>登录</div> </template>然后在router文件夹下面的Index.js里面编辑&#xff0c;仍然是引入页面…

【前端开发工具】VUE3 devtools安装

背景 尤雨溪在2020年9月19日晚正式发布vue3.0 one piece。此版本相较于vue2版本&#xff0c;更快、更小、更易维护、更易于原生、让开发者更轻松&#xff1b;所以学习vue3&#xff0c;对于一个前端开发者来说是一个刻不容缓的学习趋势。 学习vue3自然也离不开debug啦~~ Vue官方…

JS——正则表达式(超详细)

正则表达式概念创建正则表达式正则表达式常用方法test(字符串)search(正则表达式&#xff09;正则表达式.exec(字符串&#xff09;字符串.match(正则表达式)字符串.replace(正则表达式&#xff0c;新的内容&#xff09;断言范围类字符类字符类取反修饰符g&#xff1a;global全文…