Vue3 中组件的使用(上)
目录
- 前言:
- 一、什么是组件
- 二、注册组件
- 1. 全局注册
- 2. 局部注册
- 二、传递数据【父 -> 子】
- 1. 字符串数组的形式
- 2. 对象的形式
- 三、组件事件【子 -> 父】
- 1. 字符串数组式声明自定义事件
- 2. 【子组件】触发组件事件
- 3. 【父组件】监听子组件自定义事件
- 4. 组件事件例子
- 总结:
前言:
在编写vue里的SPA(Single Page Application单页面应用)时,我们始终绕不开组件的使用,Vue3 里有一些重要更新,在这里分享给大家。
一、什么是组件
组件(Component
)是 Vue.js
最强大的功能之一。
组件可以扩展 HTML
元素,封装可重用的代码。
组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树:
组件就相当于页面的零件,当做正常的标签使用,不过能够进行自定义的数据传输和事件监听。
组件内也能使用其他的组件,任意处都能够使用。
二、注册组件
一个 Vue
组件在使用前需要先被 “注册”,这样 Vue
才能在渲染模板时找到其对应的实现;组件注册有两种方式:全局注册、局部注册
1. 全局注册
可使用 app.component(name, Component)
注册组件的方法,在此应用的任意组件的模板中使用
name
:注册的名字Component
:需要注册的组件
// 在 main.js 中注册全局组件
import { createApp } from 'vue'
import App from './App.vue'
// 1:引入需要被注册的组件
import Login from './components/Login.vue' const app = createApp(App)// 2:全局注册组件
app.component('MLogin', Login)app.mount('#app')
// 我们使用注册的组件
<template><h3>登录系统</h3><!-- 使用全局注册的组件 --><MLogin />
</template>
2. 局部注册
局部注册的组件需要在使用它的父组件中显式导入,并且只能在该父组件中使用
在组合式
API
中的<script setup>
内,直接导入的组件就可以在模板中直接可用,无需注册。
<script setup>
// 1:引入需要注册的组件,无需注册
import LoginVue from './components/Login.vue';
</script><template><h3>登录系统</h3><!-- 2:使用全局注册的组件 --><LoginVue />
</template>
二、传递数据【父 -> 子】
如果父组件向子组件进行传递数据,那么我们需要在子组件中声明 props
来接收传递数据的属性,可采用字符串数组式或对象式来声明 props
父组件向子组件传递数据,在使用组件
let
的标签上采用属性方式传递的 props
值,可使用 v-bind:
或 :
来绑定属性
组件中 props
中的数据是只读的,不可直接更改,只能通过父组件进行更改
声明与使用
- 在选项式
API
中
1. 我们可以提供props
选项来声明接收传递的数据
2. 在JS
中可使用this.$props
来访问声明的自定义的属性
3. 在视图模板中,可直接访问props
中声明的自定义属性- 在组合式
API
中
1. 我们可以采用defineProps
宏来声明接收传递的数据
2. 在JS
中可使用defineProps
返回的对象来访问声明的自定义的属性
3. 在视图模板中,可直接访问defineProps
中声明的自定义属性
1. 字符串数组的形式
// 字符串数组的形式
<script setup>// 使用 defineProps 宏来声明
defineProps(['flat', 'title']) </script>
例子:
// 父组件
<script setup>
import { ref } from 'vue';
import ButtonVue from './components/Button.vue';let isError = ref(false) // 主题
let isFlat = ref(false) // 阴影
let btnText = ref('普通按钮') // 按钮文本
</script><template>主题:<input type="checkbox" v-model="isError">阴影:<input type="checkbox" v-model="isFlat">按钮文本:<input type="text" v-model="btnText"><hr><!-- 父向子传值,可采用属性的方式赋值 --><ButtonVue :title="btnText" :error="isError" :flat="isFlat"/>
</template>
// 子组件
<script setup>
// 声明接收父组件传递的属性值:自定义属性
let propsData = defineProps(['title', 'error', 'flat'])function showPropsData() {// 在 JS 中,需要通过 defineProps 返回对象来访问 props 的内容console.log(propsData)console.log(propsData.title)console.log(propsData.error)console.log(propsData.flat)
}function changeErrorProps() {// 不能直接修改 props 的数据,因为是只读的propsData.error = !propsData.error
}
</script><template><!-- 在视图模板上,可直接使用 props 中的属性 --><button :class="{ error, flat }" @click="showPropsData" @mousedown.right="changeErrorProps">{{ title }}</button>
</template><style>
button {border: none;padding: 12px 25px;
}.error {background-color: rgb(197, 75, 75);color: white;
}.flat {box-shadow: 0 0 10px grey;
}
</style>
2. 对象的形式
对象形式声明的 props
,可以对传来的值进行校验,如果传入的值不满足类型要求,会在浏览器控制台中抛出警告来提醒使用者
对象形式声明的 props
,key
是 prop
的名称,值则为约束的条件
对象中的属性:
type
:类型,如String
、Number
、Boolean
、Array
、Object
、Date
、Function
、Symbol
default
:默认值;对象或者数组应当用工厂函数返回
required
:是否必填,布尔值
validator
:自定义校验,函数类型
<script>
// 对象的形式defineProps({// 基础类型检查// (给出 `null` 和 `undefined` 值则会跳过任何类型检查)propA: Number,// 多种可能的类型propB: [String, Number],// 必传,且为 String 类型propC: {type: String,required: true},// Number 类型的默认值propD: {type: Number,default: 100},// 对象类型的默认值propE: {type: Object,// 对象或数组的默认值// 必须从一个工厂函数返回。// 该函数接收组件所接收到的原始 prop 作为参数。default(rawProps) {return { message: 'hello' }}},// 自定义类型校验函数propF: {validator(value) {// The value must match one of these stringsreturn ['success', 'warning', 'danger'].includes(value)}},// 函数类型的默认值propG: {type: Function,// 不像对象或数组的默认,这不是一个工厂函数。这会是一个用来作为默认值的函数default() {return 'Default function'}}})
</script>
例子:
// 父组件
<script setup>
import { ref } from 'vue';
import ButtonVue from './components/Button.vue';let isError = ref(false) // 主题
let isFlat = ref(false) // 阴影
let btnText = ref('普通按钮') // 按钮文本
</script><template>主题:<input type="checkbox" v-model="isError">阴影:<input type="checkbox" v-model="isFlat">按钮文本:<input type="text" v-model="btnText"><hr><!-- 父向子传值,可采用属性的方式赋值 --><ButtonVue :title="btnText" :error="isError" :flat="isFlat"/>
</template>
// 子组件
<script setup>
// 声明接收父组件传递的属性值:自定义属性
let propsData = defineProps({title: {type: String,required: true},error: Boolean,flat: Boolean,tips: {type: String,default: '我是一个普通的按钮'}
})function showPropsData() {// 在 JS 中,需要通过 defineProps 返回对象来访问 props 的内容console.log(propsData)console.log(propsData.title)console.log(propsData.error)console.log(propsData.flat)
}function changeErrorProps() {// 不能直接修改 props 的数据,因为是只读的propsData.error = !propsData.error
}
</script><template><!-- 在视图模板上,可直接使用 props 中的属性 --><button :title="tips" :class="{ error, flat }" @click="showPropsData" @mousedown.right="changeErrorProps">{{ title }}</button>
</template><style>
button {border: none;padding: 12px 25px;
}.error {background-color: rgb(197, 75, 75);color: white;
}.flat {box-shadow: 0 0 10px grey;
}
</style>
注意:
- 所有
prop
默认都是可选的,除非声明了required: true
- 除
Boolean
外的未传递的可选prop将会有一个默认值undefined
Boolean
类型的未传递prop
将被转换为false
;- 当
prop
的校验失败后,Vue
会抛出一个控制台警告【在开发模式下】- 注意
prop
的校验是在组件实例被创建之前
1. 在选项式API
中,实例的属性(比如data
、computed
等) 将在default
或validator
函数中不可用
2. 在组合式API
中,defineProps
宏中的参数不可以访问<script setup>
中定义的其他变量,因为在编译时整个表达式都会被移到外部的函数中
特别提醒:
关于
Boolean
类型转换:
为了更贴近原生boolean attributes
的行为,声明为Boolean
类型的props
有特别的类型转换规则
如声明时:defineProps({ error: Boolean })
传递数据时:
-<MyComponent error/>
:相当于<MyComponent :error="true" />
-<MyComponent />
:相当于<MyComponent :error="false" />
三、组件事件【子 -> 父】
有的时候,父组件在使用子组件时,子组件如何给父组件传值呢?
- 子组件声明自定义的事件
- 子组件中触发自定义事件(可传值)
- 父组件使用子组件时监听对应的自定义事件,并执行父组件中的函数(获取子组件传递的值)
1. 字符串数组式声明自定义事件
- 在选项式
API
中,子组件可通过emits
选项来声明自定义的事件 - 在组合式
API
中,子组件可通过defineEmits()
宏来声明自定义的事件
字符串数组式声明自定义事件
采用字符串数组可以声明简单的自定义事件:
<script setup>defineEmits(['inFocus', 'submit'])
</script>
对象式声明自定义事件
采用对象式声明自定义事件,还可以进行校验传递的参数是否符合预期要求
对象式声明自定义事件中,属性名为自定义事件名,属性值则是是否验证传递的参数:
- 属性值为
null
则不需要验证 - 属性值为函数时,参数为传递的数据,函数返回
true
则验证通过,返回false
则验证失败,验证失败可以用警告语句提示开发者【注意:无论是true
还是false
都会继续执行下去的,父组件都会获取到传递的值】
<script setup>
defineEmits({autoEvent1: null, // 无需校验// 需要校验,param 可以是多个参数,返回布尔值来表明事件是否合法autoEvent2: (param) => {// true 则通过// false 则不通过,可以在控制台输入警告语句}
})
</script>
2. 【子组件】触发组件事件
在选项式 API
中,可通过组件当前实例 this.$emit(event, ...args)
来触发当前组件自定义的事件
在组合式 API
中,可调用 defineEmits
宏返回的 emit(event, ...args)
函数来触发当前组件自定义的事件
其中上方两个参数分别为:
event
:触发事件名,字符串类型...args
:传递参数,可没有,可多个
<script setup>// 自定义事件,并返回 emit 函数
const emit = defineEmits(['changeAge'])function emitAgeEvent() {// 触发自定义事件 changeAge,并传递参数 1,20emit('changeAge', 1, 20)
}
</script><template><button @click="emitAgeEvent">触发自定义事件</button><hr><!-- 触发自定义事件 changeAge,并传递参数 30 --><button @click="emit('changeAge', 30)">触发自定义事件</button>
</template>
3. 【父组件】监听子组件自定义事件
使用 v-on:event="callback"
或者 @event="callback"
来监听子组件是否触发了该事件
event
:事件名字(camelCase
形式命名的事件,在父组件中可以使用kebab-case
形式来监听)callback
:回调函数,如果子组件触发该事件,那么在父组件中执行对应的回调函数,回调函数声明参数可自动接收到触发事件传来的值
<script setup>
import { ref } from 'vue';import ButtonVue from './components/Button.vue';let startAge = ref(0)
let endAge = ref(0)// 子组件触发事件的回调函数
function addAge(start_age, end_age) {console.log('----------------');console.log(start_age)console.log(end_age)startAge.value = start_ageendAge.value = end_age
}
</script><template><h3>开始年龄:{{ startAge }}</h3><h3>结束年龄:{{ endAge }}</h3><!-- 使用引入的组件,并通过属性传递数据 --><ButtonVue @change-age="addAge" />
</template>
4. 组件事件例子
字符串数组式声明自定义事件
// 父组件
<script setup>
import { reactive } from 'vue';
import StudentVue from './components/Student.vue';let student = reactive({name: 'Jack',age: 18,sex: '男'
})// 获取子组件传递值
function getNewAge(newAge) {console.log('年龄的新值:' + newAge)student.age = newAge
}
function getNewAgeAndName(newAge, newName) {console.log('年龄的新值:' + newAge)console.log('名字的新值:' + newName)student.age = newAgestudent.name = newName
}
function getNewStudent(stu){console.log('学生新值:');console.log(stu);student.age = stu.agestudent.name = stu.namestudent.sex = stu.sex
}
</script><template>{{ student }}<hr><StudentVue @change-student="getNewStudent"@change-age-and-name="getNewAgeAndName" @change-age="getNewAge" />
</template>
// 子组件
<script setup>
// 自定义事件
let emit = defineEmits(['changeAge', 'changeAgeAndName', 'changeStudent'])function emitEventAge() {// 选项式通过 this.$emit 触发自定义事件,并传值emit('changeAge', 30)
}</script><template><button @click="emitEventAge">更改年龄</button><br><br><button @click="emit('changeAgeAndName', 10, 'Annie')">更改年龄和名字</button><br><br><button @click="emit('changeStudent', { age: 40, name: 'Drew', sex: '男' })">更改学生(验证通过)</button><br><br><button @click="emit('changeStudent', { age: -10, name: 'Tom', sex: '男' })">更改学生(验证失败)</button>
</template>
对象式声明自定义事件
// 父组件
<script setup>
import { reactive } from 'vue';
import StudentVue from './components/Student.vue';let student = reactive({name: 'Jack',age: 18,sex: '男'
})// 获取子组件传递值
function getNewAge(newAge) {console.log('年龄的新值:' + newAge)student.age = newAge
}
function getNewAgeAndName(newAge, newName) {console.log('年龄的新值:' + newAge)console.log('名字的新值:' + newName)student.age = newAgestudent.name = newName
}
function getNewStudent(stu){console.log('学生新值:');console.log(stu);student.age = stu.agestudent.name = stu.namestudent.sex = stu.sex
}
</script><template>{{ student }}<hr><StudentVue @change-student="getNewStudent"@change-age-and-name="getNewAgeAndName" @change-age="getNewAge" />
</template>
// 子组件
<script setup>
// 自定义事件
let emit = defineEmits({changeAge: null, // 无需验证changeAgeAndName: null, // 无需验证changeStudent: stu => {if (stu.age <= 0) {console.warn('年龄不得小于等于0')// false:验证不通过,会有警告语句,父组件依旧可以获取该值return false}// true:验证通过return true}
})function emitEventAge() {// 选项式通过 this.$emit 触发自定义事件,并传值emit('changeAge', 30)
}</script><template><button @click="emitEventAge">更改年龄</button><br><br><button @click="emit('changeAgeAndName', 10, 'Annie')">更改年龄和名字</button><br><br><button @click="emit('changeStudent', { age: 40, name: 'Drew', sex: '男' })">更改学生(验证通过)</button><br><br><button @click="emit('changeStudent', { age: -10, name: 'Tom', sex: '男' })">更改学生(验证失败)</button>
</template>
总结:
欢迎大家加入我的社区,在社区中会不定时发布一些精选内容:https://bbs.csdn.net/forums/db95ba6b828b43ababd4ee5e41e8d251?category=10003
以上就是 Vue3 中组件的使用(上),不懂得也可以在评论区里问我或私聊我询问,以后会持续发布一些新的功能,敬请关注。
我的其他文章:https://blog.csdn.net/weixin_62897746?type=blog
相关文章:

Vue3 中组件的使用(上)
目录前言:一、什么是组件二、注册组件1. 全局注册2. 局部注册二、传递数据【父 -> 子】1. 字符串数组的形式2. 对象的形式三、组件事件【子 -> 父】1. 字符串数组式声明自定义事件2. 【子组件】触发组件事件3. 【父组件】监听子组件自定义事件4. 组件事件例子…...

spring-boot、spring-cloud、spring-cloud-alibaba版本对应
一、查询 spring-boot(spring-boot-starter-parent) 版本号 https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-parent 二、查询 spring-cloud(spring-cloud-dependencies) 版本号 https://mvnrepository.com/artifact/org.springframework…...

【沐风老师】3DMAX一键楼梯脚本插件StairGenerator使用教程
3DMAX一键楼梯插件StairGenerator,不需要花费太多的时间,轻松从2D平面图生成3D楼梯模型,生成的楼梯模型细节丰富真实。 【主要功能】 1.简单:轻松实现2D到3D建模。 2.具有最详细三维结构的台阶平面图。 3.楼梯各部件完全参数化…...

OpenShift 简介
OpenShift 是红帽 Red Hat 公司基于开源的云平台,是平台即服务(PaaS),是一种容器应用平台。允许开发人员构建、测试和部署云应用。该系统是在 K8S 核心之上添加工具,从而实现更快的应用开发、部署及扩展。 在 OpenShi…...

netty自定义封包实现
文章目录说明分享内置编码器和解码器解码器编码器代码实现创建核心类消息实体类自定义编码类自定义解码类服务端ServerHandler入口类客户端ClientHandler入口类测试参考总结说明 netty是java重要的企业级NIO,使用它可以快速实现很多功能通信功能如:http、…...

ORA error集锦
1、oralce 数据客户端需要安装的问题 保存信息为: “无法连接到数据库,因为数据库客户端软件无法加载。确保已正确安装并配置数据库客户端软件” 从百度网盘下载,并安装win32 oracle client 安装包 2、ORA错误 “执行异常,ORA-00911: inval…...

格雷码的实现
格雷码:任意两个相邻的二进制数之间只有一位不同 想必通信专业的学生应该都接触过格雷码,它出现在数电、通信原理等课程里。 如下图所示一个四位格雷码是什么样子的: 格雷码的特点: 其最大的特点是任意上下相邻的两个码值间&am…...

快到金3银4了,准备跳槽的可以看看
前两天跟朋友感慨,今年的铜九铁十、裁员、疫情导致好多人都没拿到offer!现在已经12月了,具体明年的金三银四只剩下两个月。 对于想跳槽的职场人来说,绝对要从现在开始做准备了。这时候,很多高薪技术岗、管理岗的缺口和市场需求也…...

最新BlackArch发布,提供1400款渗透测试工具
近日,BlackArch Linux新版本发布,此版本为白帽子和安全研究人员提供了大约1400款渗透测试工具,如果你是一位白帽子或者安全研究人员,这个消息无疑会让你很感兴趣。BlackArch Linux是一款基于Arch Linux的发行版,主要面…...

重走前端路JS进阶篇:This 指向与箭头函数
JavaScript 高级 This 指向规则 案例 function foo() {console.log(this)}// 1 调用方式1foo();// 2 调用方式2 放入对象中调用var obj {name: "why",foo: foo}obj.foo()// 调用方式三 通过 call/apply 调用foo.call("abc")指向定义 this 是js 给函数的…...

Python基础:函数式编程
一、概述 Python是一门多范式的编程语言,它同时支持过程式、面向对象和函数式的编程范式。因此,在Python中提供了很多符合 函数式编程 风格的特性和工具。 二、lambda表达式(匿名函数) 除了 函数 中介绍的 def语句,P…...

【YBT2023寒假Day14 C】字符串题(SAM)(树链剖分)(线段树)
字符串题 题目链接:YBT2023寒假Day14 C 题目大意 对于一个字符串 S 定义 F(S) 是 fail 树上除了 0 点其它点的深度和。 G(S) 是 S 每个子串 S’ 的 F(S’) 之和。 然后一个空串,每次在后面加一个字符,要你维护这个串的 G 值。 思路 考虑…...

Tailwind CSS 在Vue中的使用
什么是Tailwind CSS? Tailwind CSS 是一个功能类优先的 CSS 框架,它集成了诸如 flex, pt-4, text-center 和 rotate-90 这样的的类,支持 hover 和 focus 样式,它们能直接在脚本标记语言中组合起来,构建出任何设计。 …...

三层楼100人办公网络如何规划设计实施(实战案例)
如何设计组网 1.采用防火墙+三层交换机+二层POE交换机+AP的方案 2.三层交换机作为网络的核心,提供网络的配置、划分和各个VLAN间的数据交换,而每个VLAN由二层交换机组建 3.网络主干设备的选型,建议网络主干设备或核心层设备选择具备第3层交换功能的高性能主干交换机。 4…...

Redis:实现全局唯一ID
Redis:实现全局唯一ID一. 概述二. 实现(1)获取初始时间戳(2)生成全局ID三. 测试为什么可以实现全局唯一?其他唯一ID策略补充:countDownLatch一. 概述 全局ID生成器:是一种在【分布式…...

webpack打包基本原理——实现webpack打包核心功能
webpack打包的基本原理 核心功能就是把我们写的模块化代码转换成浏览器能够识别运行的代码,话不多说我们一起来了解它 首先我们建一个空项目用 npm init -y 创建一个初始化的,在跟目录下创建src文件夹,src下创建index.js,add.js…...

git的使用(终端输入指令) 上
git目录前言1.创建仓库2.创建文件和修改数据状态分区3 .删除、撤销重置 、和比较前言 今天带大家手把手敲一遍 git 流程: 安装一下git(详细观看我之前发的git文档࿰…...

react定义css样式,使用less,css模块化
引入外部 css文件 import ./index.css此时引入的样式是全局样式 使用less 安装 npm i style-loader css-loader sass-loader node-sass -D生成config文件夹 npm run eject配置 以上代码运行完,会在根目录生成config文件夹 进入 config > webpack.config.js 查找…...

基于JavaWeb的学生管理系统
文章目录 项目介绍主要功能截图:登录用户信息管理院系信息管理班级信息管理新增学生课程管理成绩管理部分代码展示设计总结项目获取方式🍅 作者主页:Java韩立 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系�…...

win11右键新建菜单添加选项
需要操作 2 处注册表, 以下以在右键新建菜单中添加 .html 为例 在主键 HKEY_CLASSES_ROOT 中,搜索 .html 找到后 ,右键点击它,选 新建 ->项, 在这里插入图片描述 项目名字是:ShellNew 新建后&#x…...

leetcode Day5(卡线复试,放弃版)
Day5 最后一个单词长度(要求最后一个,可以反向计数) int lens.length()-1; while(s.charAt(len)){len--;//最后是一个空格,就是无字符时 } int wordlen0;//记录字符长度 /*charAt() 方法用于返回指定索引处的字符。索引范围为从 0…...

cmake 入门二 库的编译,安装与使用
工程描述 1,建立一个静态库和动态库,提供HelloFunc 函数供其他程序编程使用,HelloFunc 向终端输出Hello World字符串。 2,安装头文件与共享库。 1 库的工程结构 1.1 工程目录下的CMakeLists.txt PROJECT…...

Python中实现将内容进行base64编码与解码
一、需求说明需要使用Python实现将内容转为base64编码,解码,方便后续的数据操作。二、base64简介Base64是一种二进制到文本的编码方式【是一种基于 64 个可打印字符来表示二进制数据的表示方法(由于 2^664,所以每 6 个比特为一个单…...

集合TreeSet的使用-java
TreeSet的特点:可排序、不重复、无索引。可排序:按照元素的大小默认升序排序;底层是基于红黑树的数据结构实现排序的,增删改查性能都较好。对于数值、字符串类型的(Integer 、Double、String)TreeSet可以排…...

Mybatis-plus 分页集成以及基本使用总结 入门和案例 注解连表查询分页案例等
简介 Mybaits-plus 是mybits 的升级版,从mybaits 升级到mybaits-plus 可以实现平滑升级 Mybaits-plus 本身提供了大量的基本查询方法以及强大的 Wrapper(包装) 类 用于查询的 QueryWrapper 以及 更新的 UpdateWrapper ,使用Wrapper 基本已经可以构建大…...

5个设计师常用素材库
推荐5个设计素材网站,免费下载! 1、菜鸟图库 菜鸟图库-免费设计素材下载 菜鸟图库是一个素材量非常丰富的网站,该网站聚合了平面、UI、淘宝电商、高清背景图、图片、插画等高质量素材。平面设计模板非常多,很多都能免费下载&…...

PHP/7.2.11 缺少 apache2/logs/httpd.pid 文件
启动服务时:systemctl restart httpd.service,报错:● httpd.service - httpd serviceLoaded: loaded (/etc/systemd/system/httpd.service; enabled; vendor preset: disabled)Active: failed (Result: exit-code) since 五 2023-02-24 16:1…...

【centos7下部署mongodb】
一.安装环境 CentOS7MongoDB4.0.13正式版。 二.下载MongoDB 1.1 官网下载地址:https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.13.tgz 1.2 将压缩包通过xftp上传到服务器/opt目录,然后解压、改名 三. 配置环境变量及配置文件 3.1配置系…...

pycharm首次使用爬虫框架scrapy遇到的问题和解决方法(二)
在首次使用scrapy框架的过程中,一直是对着别人的框架步骤撸代码的。然而,撸着撸着发现好像别人的也用不了。后面就只能自己找踏坑了。 问题报错: 1,IndexError: list index out of range 2,pymysql.err.ProgrammingError: (1064, "You have an error in your SQL s…...

pyflink学习笔记(二):table_apisql
Joins Inner Join 官网说明:和 SQL 的 JOIN 子句类似。关联两张表。两张表必须有不同的字段名,并且必须通过 join 算子或者使用 where 或 filter 算子定义至少一个 join 等式连接谓词。先创建2个表,两个表的字段是相同的,我想验证…...