一、Codeium是什么?
Codeium可以通过AI帮助开发者生成代码,目前已支持Visual Studio、JetBrains等多个常见IDE以及多个浏览器,且对个人用户免费使用。
下面将通过生成日期正则表达式以及单元测试用例、用Vue3和Element Plus生成一个登陆组件的案例,看看它对我们日常开发能提供的帮助。
Codeium支持多种编程语言: Python、Javascript、TypeScript、Java、Go、C/C++ 等)
支持的Editor如下图所示:
支持的预览如下图所示:
二、如何在Visual Studio Code使用
1、Install Codeium Extension
2、Authorize(授权)
3、登录Codeium账户
登录成功之后:
三、配置Authentication Token
1、复制token
2、Open the Command Palette
3、Paste your Token
4、授权成功状态
四、如何应用
1、代码生成
比如生成一个日期正则表达式,演示效果如下:
2、单元测试用例
代码如下:
test('YYYY-MM-DD格式的日期应该匹配正则表达式', () => {
const date = '2022-03-15';
expect(regex.test(date)).toBe(true);
});
test('YYYY/MM/DD格式的日期不应该匹配正则表达式', () => {
const date = '2022/03/15';
expect(regex.test(date)).toBe(false);
});
test('YYYY年MM月DD日格式的日期不应该匹配正则表达式', () => {
const date = '2022年03月15日';
expect(regex.test(date)).toBe(false);
});
test('YY-MM-DD格式的日期不应该匹配正则表达式', () => {
const date = '22-03-15';
expect(regex.test(date)).toBe(false);
});
这里我们定义了一个名为regex的变量来存储正则表达式。随后,我们使用Jest测试框架编写了四个测试用例:
- 检查一个符合YYYY-MM-DD格式的日期是否能够成功匹配正则表达式。
- 检查一个使用YYYY/MM/DD格式的日期是否不能匹配正则表达式。
- 检查一个使用YYYY年MM月DD日格式的日期是否不能匹配正则表达式。
- 检查一个使用YY-MM-DD格式的日期是否不能匹配正则表达式。
这些测试用例将通过调用test函数来执行,并使用expect和toBe函数来断言测试结果。
3、用Vue3和Element Plus生成一个登陆组件
生成的代码如下:
<template>
<div class="login-container">
<el-card class="login-card">
<h2 class="login-title">用户登录</h2>
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" label-width="80px" class="login-form">
<el-form-item label="用户名" prop="username">
<el-input v-model.trim="loginForm.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" v-model.trim="loginForm.password"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" :loading="submitting" @click="handleSubmit">登录</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script>
import { defineComponent } from 'vue';
import { ElForm, ElFormItem, ElInput, ElButton, ElCard } from 'element-plus';
export default defineComponent({
name: 'LoginPage',
components: {
ElForm,
ElFormItem,
ElInput,
ElButton,
ElCard,
},
data() {
return {
loginForm: {
username: '',
password: '',
},
loginRules: {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
],
},
submitting: false,
};
},
methods: {
async handleSubmit() {
try {
await this.$refs.loginForm.validate();
this.submitting = true;
// 在这里发送登录请求,请求成功后跳转到目标页面
} catch (error) {
console.error(error);
} finally {
this.submitting = false;
}
},
},
});
</script>
<style>
.login-container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.login-card {
width: 400px;
}
.login-title {
text-align: center;
margin-bottom: 20px;
}
.login-form {
width: 100%;
}
</style>
代码说明:
在这个示例中,我们使用了Element Plus组件库中的ElForm、ElFormItem、ElInput、ElButton和ElCard组件来实现一个简单的登录页面。页面中包含一个带有用户名和密码输入框的表单,以及一个登录按钮。当用户点击登录按钮时,表单将被验证。如果表单验证通过,将发送登录请求,请求成功后跳转到目标页面。在代码中,我们使用了Vue 3的defineComponent函数来定义组件,并将组件的数据、方法和模板都封装在了组件内部。
4、自动补全与提示
5、Vue3源码分析
function createGetter(isReadonly = false, shallow = false) {
// 闭包返回 get 拦截器方法
return function get(target: Target, key: string | symbol, receiver: object) {
if (key === ReactiveFlags.IS_REACTIVE) {
return !isReadonly
} else if (key === ReactiveFlags.IS_READONLY) {
return isReadonly
} else if (key === ReactiveFlags.IS_SHALLOW) {
return shallow
} else if (
key === ReactiveFlags.RAW &&
receiver ===
(isReadonly
? shallow
? shallowReadonlyMap
: readonlyMap
: shallow
? shallowReactiveMap
: reactiveMap
).get(target)
) {
return target
}
const targetIsArray = isArray(target)
console.log('----get1', target, key)
if (!isReadonly) {
if (targetIsArray && hasOwn(arrayInstrumentations, key)) {
console.log('----get2', target, key)
console.log('----arrayInstrumentations', arrayInstrumentations)
const res = Reflect.get(arrayInstrumentations, key, receiver)
console.log('----res', res)
return res
}
if (key === 'hasOwnProperty') {
return hasOwnProperty
}
}
const res = Reflect.get(target, key, receiver)
if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
return res
}
if (!isReadonly) {
track(target, TrackOpTypes.GET, key)
}
if (shallow) {
return res
}
if (isRef(res)) {
// ref unwrapping - skip unwrap for Array + integer key.
return targetIsArray && isIntegerKey(key) ? res : res.value
}
if (isObject(res)) {
// Convert returned value into a proxy as well. we do the isObject check
// here to avoid invalid value warning. Also need to lazy access readonly
// and reactive here to avoid circular dependency.
return isReadonly ? readonly(res) : reactive(res)
}
return res
}
}
const set = /*#__PURE__*/ createSetter()
const shallowSet = /*#__PURE__*/ createSetter(true)
function createSetter(shallow = false) {
return function set(
target: object,
key: string | symbol,
value: unknown,
receiver: object
): boolean {
let oldValue = (target as any)[key]
if (isReadonly(oldValue) && isRef(oldValue) && !isRef(value)) {
return false
}
if (!shallow) {
if (!isShallow(value) && !isReadonly(value)) {
oldValue = toRaw(oldValue)
value = toRaw(value)
}
if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
oldValue.value = value
return true
}
} else {
// in shallow mode, objects are set as-is regardless of reactive or not
}
console.log('----set', target, key, value)
const hadKey =
isArray(target) && isIntegerKey(key)
? Number(key) < target.length
: hasOwn(target, key)
const result = Reflect.set(target, key, value, receiver)
// don't trigger if target is something up in the prototype chain of original
if (target === toRaw(receiver)) {
if (!hadKey) {
trigger(target, TriggerOpTypes.ADD, key, value)
} else if (hasChanged(value, oldValue)) {
trigger(target, TriggerOpTypes.SET, key, value, oldValue)
}
}
return result
}
}
帮我分析的结果:
这段代码是 Vue3 的响应式系统中的一部分,主要实现了 get 和 set 操作的拦截器方法。在 get 方法中,首先判断了 key 是否为一些特殊的内部标记,如果是,则返回相应的值。接着判断是否为数组,并且是否有对应的数组操作方法,如果有,则返回该操作方法。然后再判断 key 是否为“hasOwnProperty”,如果是,则返回全局对象中的 hasOwnProperty 方法。最后,如果没有上述情况,则调用 Reflect.get 方法获取目标对象的属性值,并将该属性值返回。
在 set 方法中,首先判断 oldValue 是否为只读的 ref 对象,如果是,则判断 value 是否为 ref 对象,如果不是,则返回 false。接着判断是否为浅层模式,如果不是,则将 value 和 oldValue 都转换为原始值。然后再判断是否为数组,并且 oldValue 是否为 ref 对象,并且 value 不是 ref 对象,如果是,则将 oldValue 的值设置为 value。如果是浅层模式,则直接将 value 设置为目标对象的属性值。接着调用 Reflect.set 方法设置目标对象的属性值,并根据目标对象和设置的属性值是否发生变化,触发相应的 trigger 事件。最后,将 Reflect.set 方法的返回值返回。
五、总结
Codeium能够为我们生成一些代码,把我们从重复、无聊的代码解放出来,我们可以在日常开发中创造性的去使用它,一定会对它爱不释手的。