Vue3 开发语法使用总结(超详细、超基础)

news2024/11/23 13:11:24

前言

最近开源了一套后台管理模板Wocwin-Admin,是基于 Vue3.2、TypeScript、Vite4、Pinia、Element-Plus、Qiankun(微前端) 技术栈,借此归纳一下Vue3.2的新语法。

一、全局注册(属性/方法)

1、main.ts注册

import { createApp } from "vue";
import App from "./App.vue";
// 所有业务api接口
import api from "@/api";
const instance = createApp(App);
// 注册全局api方法
instance.config.globalProperties.$api = api;

2、.vue文件使用

<script setup lang="ts">
import { getCurrentInstance } from 'vue'
const {  appContext } = getCurrentInstance()
const global = appContext.config.globalProperties
// 获取所有业务api接口
console.log(global.$api)
</script>

输出结果如下:在这里插入图片描述

二、获取 this

<script setup lang="ts">
import { getCurrentInstance } from 'vue'
// proxy 就是当前组件实例,相当于Vue2单文件的this——没有全局的、路由、状态管理之类的
const { proxy, appContext } = getCurrentInstance()
// 这个 global 就是全局实例(可以获取挂载全局的方法)
const global = appContext.config.globalProperties
</script>

三、template可存在多个根节点

其实本质上 Vue3 每个组件还是一个根节点,因为 DOM 树只能是树状结构的,只是 Vue3 在编译阶段新增了判断,如果当前组件不只一个根元素,就添加一个 fragment 组件把这个多根组件的给包起来,相当于这个组件还是只有一个根节点,并且fragment 组件是一个不会被渲染出来的内置组件

<template>
    <div>1</div>
    <div>2</div>
    <div>3</div>
</template>

四、获取 DOM

<template>
    <el-button ref="buttonRef"></el-button>
</template>
<script setup lang="ts">
import { ref} from "vue";
// 注意:这个变量名和 DOM 上的 ref 属性必须同名,会自动形成绑定
const buttonRef= ref(null)
// 获取到 DOM
console.log(buttonRef.value)
</script>

五、解除绑定(定时器、监听之类的操作)

<script setup lang="ts">
import { onBeforeUnmount, onDeactivated } from 'vue'
// 组件卸载前
onBeforeUnmount(() => {
	// 清除定时器
    clearTimeout(timer)
    // 清除监听事件
    window.removeAddEventListener('所监听的事件')
})
// 退出缓存组件
onDeactivated(() => {
   // 清除定时器
    clearTimeout(timer)
    // 清除监听事件
    window.removeAddEventListener('所监听的事件')
})
</script>

六、ref 和 reactive使用

通常情况:ref 用于创建一个响应式的基本数据类型(如字符串、数字或布尔值)。它返回一个包含响应式值的对象,在script 可以通过 .value 属性访问该值,template 中直接使用。
通常情况:reactive 用于创建一个响应式的对象。它返回一个新的响应式对象,该对象与原始对象具有相同的属性和值。

<script setup lang="ts">
import { ref, reactive } from "vue"
const count = ref(1)
// 输出结果:1  注意:ref 返回的属性在 template 中直接使用,不需要再.value
console.log(count.value)

const state= reactive({
    name: "wocwin",
    address: "广州市",
    ...
})
console.log(state.name) // wocwin
</script>

七、toRef 和 toRefs使用(解决直接解构会丢失响应式)

解决直接解构会丢失响应式:这两共同点就是用来创建响应式的引用的,主要用来取出响应式对象里的属性,或者解构响应式对象,解构出来的属性值依然是响应式属性

<script setup lang="ts">
import { reactive, toRef, toRefs } from "vue"
const state= reactive({
    name: "wocwin",
    address: "广州市",
})
// 这样能拿到 name / address,但是会变成普通变量,没有响应式效果
const { name, address} = state
// 取出来一个响应式属性
const name = toRef(state, 'name')
// 这样解构出来的所有属性都是有响应式的
const { name, address} = toRefs(state)
</script>

八、watch和 watchEffect使用

watch 是一个函数,能接收三个参数,参数一是监听的属性,参数二是接收新值和老值的回调函数,参数三是配置项
watch 是对传入的一个或多个值进行监听,触发时会返回新值和老值,且默认第一次不会执行
watchEffect 是传入一个立即执行函数,所以默认第一次就会执行,且不需要传入监听内容,会自动收集函数内的数据源作为依赖,当依赖发生变化时会重新执行函数,不会返回新值和老值。

<script setup lang="ts">
import { watch, ref, reactive,watchEffect } from "vue"
const name = ref("wocwin")
const state = reactive({
    address: "广州市",
    age: 22,
    children: []
})
// 监听 ref 属性
watch(name, (newName, oldName) => { ... })

// 监听单个属性
watch(
    () => state.address, 
    (newAddress, oldAddress) => { ... }
)
// 监听多个属性,数组放多个值,返回的新值和老值也是数组形式
watch([data.age, data.address], ([newAge, newAddress], [oldAge, oldAddress]) => { 
...
})
// 第三个参数是一个对象,为可配置项
watch(data.children, (newList, oldList) => { ... }, {
    // 这两个和 Vue2 一样
    immediate: true,
    deep: true,
})
// 在 watch 回调函数中能接收第三个参数 onInvalidate,为清除副作用的函数,首次触发监听的回调函数(handler)不会执行 onInvalidate,之后每次触发默认会先执行 onInvalidate
watch(name, (newName, oldName,onInvalidate) => { 
 console.log("wocwin")
 onInvalidate(() => {
        console.log(2222)
    })
})
// onInvalidate 的使用场景就是:比如监听的回调函数(handler)里有一些异步操作,当再次触发 watch 的时候可以用它来对前面未完成的异步任务执行取消/重置/初始化等操作。
/**
*watchEffect
*/
watchEffect(() => {
    // 会自动收集这个函数使用到的属性作为依赖,进行监听
    // 监听的是 state.name 属性,不会监听 state
    console.log(state.name)
})
</script>

九、computed(计算属性——是一个函数)

<script setup lang="ts">
import { computed } from "vue"
const props = defineProps({
 modelValue: {
    type: [String, Number, Array]
  },
})
const emits = defineEmits(['update:modelValue'])

// 函数写法
const isFirst = computed(() => {
...
})

// 对象写法
// vue3 v-model简写
let childSelectedValue: any = computed({
  get() {
    return props.modelValue
  },
  set(val) {
    emits('update:modelValue', val)
  }
})

</script>

十、nextTick

<script setup lang="ts">
import { nextTick} from 'vue'
// 方式 一
const handleClick = async () => {
  await nextTick()
  console.log("wocwin")
}
// 方式二
nextTick(() => {
    console.log("wocwin")
})
// 方式三
nextTick().then(() => {
    console.log("wocwin")
  })
</script>

十一、mixins 和 hooks

Vue2 中逻辑的抽离复用一般用 mixins:但是其没有独立命名空间,mixins 会和组件内部产生命名冲突
Vue3 中逻辑抽离复用的 hooks 语法,其实就是一个函数,可以传参,拿返回值来用。

1、封装hooks(具体代码查看Wocwin-Admin)

import { storeToRefs } from "pinia";
import { Theme } from "./interface";
import { ElMessage } from "element-plus";
import { DEFAULT_PRIMARY } from "@/config";
import { useGlobalStore } from "@/store/modules/global";
import { getLightColor, getDarkColor } from "@/utils/color";
import { asideTheme, AsideThemeType } from "@/styles/theme/aside";
/**
 * @description 全局主题 hooks
 * */
export const useTheme = () => {
  const globalStore = useGlobalStore();
  const { primary, isDark, isGrey, isWeak, asideInverted, layout } = storeToRefs(globalStore);

  // 切换暗黑模式 ==> 并带修改主题颜色、侧边栏颜色
  const switchDark = () => {
    const body = document.documentElement as HTMLElement;
    if (isDark.value) body.setAttribute("class", "dark");
    else body.setAttribute("class", "");
    changePrimary(primary.value);
    setAsideTheme();
  };
  // 修改主题颜色
  const changePrimary = (val: string | null) => {
    if (!val) {
      val = DEFAULT_PRIMARY;
      ElMessage({ type: "success", message: `主题颜色已重置为 ${DEFAULT_PRIMARY}` });
    }
    // 计算主题颜色变化
    document.documentElement.style.setProperty("--el-color-primary", val);
    document.documentElement.style.setProperty(
      "--el-color-primary-dark-2",
      isDark.value ? `${getLightColor(val, 0.2)}` : `${getDarkColor(val, 0.3)}`
    );
    for (let i = 1; i <= 9; i++) {
      const primaryColor = isDark.value ? `${getDarkColor(val, i / 10)}` : `${getLightColor(val, i / 10)}`;
      document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, primaryColor);
    }
    globalStore.setGlobalState("primary", val);
  };
  // 灰色和弱色切换
  const changeGreyOrWeak = (type: Theme.GreyOrWeakType, value: boolean) => {
    const body = document.body as HTMLElement;
    if (!value) return body.removeAttribute("style");
    const styles: Record<Theme.GreyOrWeakType, string> = {
      grey: "filter: grayscale(1)",
      weak: "filter: invert(80%)"
    };
    body.setAttribute("style", styles[type]);
    const propName = type === "grey" ? "isWeak" : "isGrey";
    globalStore.setGlobalState(propName, false);
  };
  // 设置侧边栏样式 ==> light、inverted、dark
  const setAsideTheme = () => {
    // 默认所有侧边栏为 light 模式
    let type: AsideThemeType = "light";
    // transverse 布局下菜单栏为 inverted 模式
    if (layout.value == "transverse") type = "inverted";
    // 侧边栏反转色目前只支持在 vertical 布局模式下生效
    if (layout.value == "vertical" && asideInverted.value) type = "inverted";
    // 侧边栏 dark 模式
    if (isDark.value) type = "dark";
    const theme = asideTheme[type!];
    for (const [key, value] of Object.entries(theme)) {
      document.documentElement.style.setProperty(key, value);
    }
  };
  // init theme
  const initTheme = () => {
    switchDark();
    if (isGrey.value) changeGreyOrWeak("grey", true);
    if (isWeak.value) changeGreyOrWeak("weak", true);
  };
  return {
    initTheme,
    switchDark,
    changePrimary,
    changeGreyOrWeak,
    setAsideTheme
  };
};

2、具体页面使用

<template>
<div class="theme-item">
      <span>主题颜色</span>
      <el-color-picker v-model="primary" :predefine="colorList" @change="changePrimary" />
    </div>
</template>
<script setup lang="ts">
import { useTheme } from "@/hooks/useTheme";
const { changePrimary } = useTheme();
</script>

十二、多个 v-model

// 父组件写法
<template>
    <child v-model:name="name" v-model:age="age" />
</template>
<script setup lang="ts">
import { ref } from "vue"
const name = ref('wocwin')
const age = ref(22)
</script>

// 子组件
<script setup lang="ts">
const emit = defineEmits(['update:name', 'update:age'])

const handleClick = () => {
    console.log('点击了')
    emit('update:name', '这是新的名字')
}
</script>

十三、CSS 样式穿透

<style lang="scss" scoped>
:deep(.el-form) {
    .el-form-item { 
    ...
     }
</style>

十四、CSS 绑定 JS 变量

<template>
    <div class="name">wocwin</div>
</template>
<script setup>
import { ref } from "vue"
const str = ref('#f00')
</script>
<style scoped lang="scss">
.name {
    color: v-bind(str); // JS 中的色值变量 #f00 就赋值到这来了
}
</style>

相关文章

wocwin-admin地址

wocwin-admin在线预览地址

基于ElementUi或AntdUI再次封装基础组件文档

基于Element-plus再次封装基础组件文档(vue3+ts)

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

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

相关文章

Ubuntu22 2023最新版安装教程

Ubuntu22安装教程 2023全网最新版 前置资源准备 如果选择使用虚拟机安装&#xff0c;那么需要准备VmwareWorkstation 在官网进行下载安装 VmwareWorkstation官网:https://www.vmware.com/products/workstation-pro/workstation-pro-evaluation.html 前置资源准备好后就可以…

【SpringCloud config分布式配置中心】—— 每天一点小知识

&#x1f4a7; S p r i n g C l o u d c o n f i g 分布式配置中心 \color{#FF1493}{SpringCloud config分布式配置中心} SpringCloudconfig分布式配置中心&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &#x1f984; 个人主页——微风撞见云的…

okcc呼叫系统运营商的重点功能有什么

一、资费套餐模块 资费套餐&#xff0c;即客户进行业务时使用的资费标准。填写资费套餐名称&#xff0c;选择计费规则方式&#xff0c;点击“确认”按钮即可创建一条资费套餐&#xff0c;如下图所示。 计费规则即计费所遵循的规则。OKCC系统目前设计了以下三种计费方式(后续还…

Caretta 利用 eBPF 实现 Kubernetes 应用网络拓扑

介绍 Caretta 是一种轻量级的独立工具&#xff0c;快速展示集群中运行的服务可视化网络图。 Caretta 利用 eBPF 有效地展示 K8s 集群中的服务网络交互图&#xff0c;并利用 Grafana 查询和可视化收集的数据。科学家们早就知道&#xff0c;海龟和许多动物一样&#xff0c;通过…

【瑞萨RA_FSP】AGT——低功耗定时器

文章目录 一、AGT简介二、AGT的框图分析1. 16位计数器2. 16位重装载寄存器3. 计数时钟源4. 比较匹配功能5. 比较匹配输出引脚6. 输出引脚7. 下溢事件信号/测量完成事件信号输出 三、AGT工作模式详解四、实验&#xff1a;比较匹配功能——PWM输出1. 硬件设计2. 文件结构3. FSP配…

基础篇:新手使用vs code新建go项目(从0开始到运行)

学习新语言&#xff0c;搭建新环境。在网上找了一些教程&#xff0c;感觉还是写一个比较详细的方便以后自己使用。其实vs code没有新建项目这个功能&#xff0c;具体怎么运行go语言的项目请看下文。 一、下载GO安装包 1.点击go安装包下载链接下载相应的版本&#xff08;本次下…

【计算机网络自顶向下】简答题习题总结(三)

文章目录 第三章 传输层UDP用户数据报协议可靠数据传输原理面向连接传输TCP流量控制可靠数据传输机制 题目 第三章 传输层 传输层服务&#xff1a;在两个不同的主机的运行应用程序之间提供逻辑通信 在接收主机多路分解 将接收到的数据段传递给正确的套接字【多路分解】 在发送…

线程与轻进程(OS)

目录 1、进程的引入 2、线程的概念 3、线程的结构 3、线程控制块 5、线程的实现 &#xff08;1&#xff09;用户级别线程 &#xff08;2&#xff09;核心级别线程 &#xff08;3&#xff09;混合线程 6、线程的应用 1、进程的引入 进程切换 上下文涉及内容多&#xf…

软件测试面试,从简历到面试常问,不学几招怎么跳槽?

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 软件测试面试环节…

关于Java多线程不安全的问题简析

在了解多线程不安全的问题之前 让我们先来看如下代码 public class demo18 {public static int count 0;public static void main(String[] args) throws InterruptedException {Thread t1 new Thread(()->{for (int i 0; i < 10000; i) {count;}});Thread t2 new …

软件测试报告需要做哪些测试内容?软件测试外包服务公司靠谱吗?

在软件开发领域中&#xff0c;测试是最为重要的环节之一&#xff0c;它在确保软件质量方面有着至关重要的作用。软件测试是一种检验软件代码是否符合设计和用户期望的过程。软件测试的主要目的是发现缺陷并确保软件在实际使用中的可靠性&#xff0c;安全性&#xff0c;以及稳定…

Linux中centos修改系统时间并写到硬件,Linux中centos设置定时自动同步网络时间

文章目录 前言一、centos修改系统时间并写到硬件1.1查看当前的系统时间1.2修改系统时间1.3查看硬件时间1.4同步系统时间和硬件时间1.5本地时间写入硬件时间 二、centos设置定时自动同步网络时间2.1安装ntpdate工具2.2CentOS安装/操纵crontab2.3启动crontab并查看状态2.4写一个c…

Ubuntu系统安装Mysql服务并设置远程连接-Navicat连接Mysql-物联网系统

目录 一、前言 二、Mysql的安装 三、Mysql服务管理 四、配置Mysql远程连接 五、修改登录限制 六、修改Root密码 七、Navicat连接Mysql 一、前言 在我们购买服务器后&#xff0c;常需要在服务器上部署数据库以存储我们所需要的数据&#xff0c;因此我们本文将在Ubuntu系统…

LeetCode - #81 搜索旋转排序数组 II

文章目录 前言1. 描述2. 示例3. 答案关于我们 前言 我们社区陆续会将顾毅&#xff08;Netflix 增长黑客&#xff0c;《iOS 面试之道》作者&#xff0c;ACE 职业健身教练。&#xff09;的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 LeetCode 算法到目前我们已经更新…

解决阿里云服务器被植入挖矿脚本过程

文章目录 前言一、服务器为什么会被告警挖矿&#xff1f;二、怎么解决&#xff1a;1.top 命令查看进程cpu 占用情况&#xff1a;2.通过pid进程号&#xff0c;查找改程序所在的目录&#xff1a;3. 强制删除脚本文件&#xff1a;4. 强制杀死进程&#xff1a;5. 检查是否有脚本的定…

three.js物体纹理及其常用属性介绍

一、Three中的纹理和材质介绍 THREE中的纹理和材质是用来渲染3D场景中的物体表面的。纹理贴图定义物体表面的颜色和外观&#xff0c;而材质则定义物体表面如何反射光线。 纹理可以使用多种类型的图像文件&#xff0c;包括JPEG、PNG、GIF等。纹理可以是简单的颜色、图案或者是复…

史上最卷618背后:国产手机厂商突围的“新武器”

智能手机&#xff0c;究竟还是不是个好生意? 这个问题在近些年被市场反复追问&#xff0c;在最近被称为“史上最卷”的618期间&#xff0c;更是被增添了悲观的色彩。IDC中国研究经理郭天翔表示&#xff0c;本次618智能终端市场是低于预期的&#xff0c;同时也低于去年同期。除…

Qt6.2教程——1.Qt安装及编写登录界面

本文旨在帮助读者理解如何使用ChatGPT来辅助安装和学习Qt 6.2。我们将从Qt 6.2的基本概念开始&#xff0c;然后深入了解其安装过程&#xff0c;并探讨如何使用ChatGPT作为一个强大的辅助工具。对于那些寻求在学习和使用Qt 6.2中找到有效支持的人来说&#xff0c;这篇文章将提供…

FBM207C RH917GY将相关调节系统打到手动状态,必要时到现场进行调节

​ FBM207C RH917GY将相关调节系统打到手动状态&#xff0c;必要时到现场进行调节 FBM207C RH917GY将相关调节系统打到手动状态&#xff0c;必要时到现场进行调节 随着自动化水平的提高&#xff0c;dcs控制系统(集散控制系统)逐渐代替了常规仪表&#xff0c;其优越性已被广大操…

Vue 常用属性

数据属性 组件的 data 选项是一个函数&#xff08;data里面是有return的&#xff09;。Vue 会在创建新组件实例的过程中调用此函数&#xff08;将里面定义的变量都放到实例里面去&#xff0c;你就可以使用this点出来&#xff0c;包括HTML里面就能够使用这些变量的&#xff09;。…