Vue3注册局部组件和全局组件

Vue3局部组件注册

composition模式

javascript 复制代码
// composition模式
<template>
    <ChildCom />
</template>
<script setup>
// setup默认就注册了组件
import ChildCom from './components/ChildCom.vue'
</script>

options模式

javascript 复制代码
<template>
    <ChildCom />
</template>
<script>
import ChildCom from './components/ChildCom.vue'
export default {
    components: {
        ChildCom
    }
}
</script>

Vue3全局组件注册

在项目component文件夹下新建index.ts,

index.ts代码如下:

javascript 复制代码
import SearchForm from './search-form.vue';
import YihenNav from './YihenNavBox.vue';

import type { App } from 'vue';
const components: any = { SearchForm, YihenNav };
export default {
  install(app: App) {
    Object.keys(components).forEach((key: string) => {
      app.component(key, components[key]); // 遍历挂载组件
    });
  }
};

然后看看我们封装的全局公共组件YihenNav ,代码如下:

javascript 复制代码
<template>
  <div>
    <div class="navBox">
      <el-menu
        :default-active="active"
        active-text-color="#1182FB"
        mode="horizontal"
        @select="handSelect"
      >
        <el-menu-item
          :index="navItem.code"
          v-for="(navItem, navIndex) in navList"
          :key="navIndex"
          >{{ navItem.name }}</el-menu-item
        >
      </el-menu>
    </div>
  </div>
</template>

<script setup lang="ts">
import { defineEmits } from 'vue';

defineProps({
  active: String,
  navList: Array
});

const emits = defineEmits(['navSwitch']);
const handSelect = (key) => {
  emits('navSwitch', key);
};
</script>

<style lang="less" scoped>
.navBox {
  margin: 8px;
  background: #ffffff;
  .el-menu {
    border: none;
  }
}
</style>

最后在main.ts里引入index.ts即可:

javascript 复制代码
//main.ts
import globalComponent from './component/index';
const render = async(props: any = {}) => {
  app = createApp(App);
  app.use(globalComponent);
}
render();

然后在我们页面组件里使用,页面样式效果如下:

最开始前端会通过getBaseSettingInfo方法调后端接口获取详情,然后调updateBseSettingInfo接口方法编辑保存配置,完整代码如下:

javascript 复制代码
<template>
  <div>
    <yihen-nav :active="activeIndex" :nav-list="navList" @navSwitch='navSwitch' />
    <el-form
    ref="ruleFormRef"
    style="margin-left:100px; max-width: 600px"
    :model="ruleForm"
    :rules="rules"
    label-width="auto"
    class="demo-ruleForm"
  >
  <el-form-item label="IKE密钥周期(秒):" prop="ike_key_period">
      <el-input v-model="ruleForm.ike_key_period" />
    </el-form-item>
    <el-form-item label="IPsec密钥周期(秒):" prop="ipsec_key_period">
      <el-input v-model="ruleForm.ipsec_key_period" />
    </el-form-item>
    <el-form-item label="预共享密钥:" prop="default_shared_secret">
      <el-input v-model="ruleForm.default_shared_secret" />
    </el-form-item>
     <el-form-item label="IKE端口设置:" prop="ike_port">
      <el-input v-model="ruleForm.ike_port" />
    </el-form-item>
     <el-form-item label="NAT端口设置:" prop="nat_port">
      <el-input v-model="ruleForm.nat_port" />
    </el-form-item>

    <el-button
            style="margin-left:20px;"
            type="primary"
            @click="submit"
          >保存配置</el-button>
  </el-form>

  </div>
</template>
<script lang="ts" setup>
import { validator } from '@vpn/utils/validate.ts';
import { getBaseSettingInfo, updateBseSettingInfo } from '@vpn/api/ipsec.ts';
import { ElMessage, FormRules } from 'element-plus';
import { ref, reactive, onMounted } from 'vue';
const activeIndex = ref<string>('0');
const navList = reactive([{
  name: '基本配置',
  code: '0'
}]);

const ruleFormRef = ref();

interface RuleForm {
  ike_key_period: number | string
  ipsec_key_period: number | string
  default_shared_secret: string
  ike_port: number | string
  nat_port:number | string
}
const ruleForm = ref<RuleForm>({
  ike_key_period: '',
  ipsec_key_period: '',
  default_shared_secret: '',
  ike_port: '',
  nat_port: ''
});

const rules = reactive<FormRules<RuleForm>>({
  ike_key_period: [
    { required: true, message: '请输入IKE密钥周期', trigger: 'blur' },
    { validator: validator.ikeTimeSecond, trigger: 'blur' }
  ],
  ipsec_key_period: [
    { required: true, message: '请输入IPsec密钥周期', trigger: 'blur' },
    { validator: validator.ipsecTimeSecond, trigger: 'blur' }
  ],
  default_shared_secret: [
    { required: true, message: '请输入预共享密钥', trigger: 'blur' }
  ],
  ike_port: [
    { required: true, message: '请输入IKE端口', trigger: 'blur' },
    { validator: validator.sshPort, trigger: 'blur' }
  ],
  nat_port: [
    { required: true, message: '请输入NAT端口', trigger: 'blur' },
    { validator: validator.sshPort, trigger: 'blur' }
  ]
});

const navSwitch = (key) => {
  console.log(key);
};

const submit = async() => {
  await ruleFormRef.value.validate();
  const res: any = await updateBseSettingInfo(ruleForm);
  if (res.code === 200) {
    ElMessage({
      type: 'success',
      message: '保存成功'
    });
  } else {
    ElMessage({
      type: 'error',
      message: '保存失败'
    });
  }
};

onMounted(() => {
  getBaseInfo();
});

const getBaseInfo = () => {
  getBaseSettingInfo()
    .then(res => {
      console.log('基本配置详情', res);
      // ruleForm = Object.assign(ruleForm, res.data);
      ruleForm.value = res.data;
    });
};

</script>
<style lang="less" scoped>
.txl {
  text-align: left;
}
</style>
相关推荐
牛蛙点点申请出战2 分钟前
IconFontViewer -- 一个可以在 Android Studio 中实时预览 IconFont 的插件
android·前端·intellij idea
空中海3 分钟前
03 渲染机制、性能优化与现代 React
javascript·react.js·性能优化
ChalesXavier31 分钟前
Fetch API 的基本用法
javascript
是上好佳佳佳呀40 分钟前
【前端(十三)】JavaScript 数组与字符串笔记
前端·javascript·笔记
巴沟旮旯儿40 分钟前
vite项目配置文件和打包
前端·设计模式
彩票管理中心秘书长1 小时前
Pinia 插件架构与组合式函数:如何让你的 Store 长出“超能力”
前端
彩票管理中心秘书长1 小时前
Pinia 比 Vuex 强在哪?我用同一个模块写了两种实现,你自己看
前端
yingyima1 小时前
用 Cron 加 Webhook 打通自动化工作的任督二脉
前端
JackieDYH1 小时前
CSS Flexbox 与 Grid 的默认行为-布局的底层机制
前端·css·html
彩票管理中心秘书长1 小时前
E2E测试入门:别让用户帮你点鼠标了,找个机器人替你打工吧
前端