vue2升级vue3: TSX Vue 3 Composition API Refs
在vue2时代,$refs 直接操作子组件
this.$refs.gridlayout.$children[index];
虽然不推荐这么做,但是确实非常好用。但是vue2快速迁移到vue3,之前的这个写法因为干进度,不想重构,直接搬迁,发现不行?
看了下官方的文档:https://v3.cn.vuejs.org/guide/migration/array-refs.html#%E8%BF%81%E7%A7%BB%E7%AD%96%E7%95%A5
<template>
<div v-for="item in list" :ref="setItemRef"></div>
</template>
<script setup>
let itemRefs = ref()
const setItemRef = el => {
if (el) {
itemRefs.push(el)
}
}
onBeforeUpdate(() => {
itemRefs = []
})
onUpdated(() => {
console.log(itemRefs)
})
</script>
注意:
itemRefs 不必是数组:它也可以是一个对象,其 ref 可以通过迭代的 key 被设置。
如有需要,itemRefs 也可以是响应式的,且可以被侦听。
在tsx 这个怎么弄呢?
TSX refs
网上的大部分教程都是 template 的
Typing Template Refs
const el = ref<HTMLInputElement | null>(null)
普通元素
Typing Component Template Refs
import MyModal from './MyModal.vue'
const modal = ref<InstanceType<typeof MyModal> | null>(null)
const openModal = () => {
modal.value?.open()
}
对于子组件,其实和 let timer: ReturnType<typeof setTimeout> = null; 类似。
如果不进行类型声明,modal 方法无法调用。 需要是as 魔法了
还有一个需要特别注意,就是子组件内容是暴露出来的,如果是 <script setup> 组件,是无法获取内容的,具体参看:
Refs 获取子元素,并操作子元素
import { defineComponent, nextTick, onBeforeUpdate, onMounted, onUnmounted, ref } from 'vue';
import ChartWrapper from '@/components/chart-wrapper';
import props from './props';
import { AddChartType, PanelModel, IGridPos } from '@/typings';
import { DashboardModule, sortGridPanels } from '@modules/dashboard';
import { getPluginTypes, handleInitChartPlugin, handleInitDataSource } from '@/utils/dashboard';
import Loading from '@/components/loading';
import { GRID_COL_NUM, GRID_ROW_HEIGHT, GRID_ROW_MARGIN, initPanel } from '@/constants';
import { debounce } from 'lodash';
import { deepClone } from '@/utils';
import AddPanel from '@dashboard/grid-panel/add-panel';
import TabPanel from '@dashboard/tab-panel/index';
import { GridItem, GridLayout } from 'v3-grid-layout';
import 'v3-grid-layout/dist/style.css';
import './index.scss';
import Row from './Row';
import EventBus from '@/utils/eventBus';
export default defineComponent({
name: 'GridPanelPlugin',
props,
emits: ['ready', 'delete', 'mounted'],
setup(props, { emit }) {
const layout = ref<IGridPos[]>([]);
const gridLayout = ref<InstanceType<typeof GridLayout>>(null);
const gridItem = ref<InstanceType<typeof GridItem>[]>([]);
const dashboardPanel = ref<Element>(null);
onBeforeUpdate(() => {
gridItem.value = [];
});
function drag(e: DragEvent) {
const parentRect = dashboardPanel.value.getBoundingClientRect();
let mouseInGrid = false;
if (
((mouseXY.x > parentRect.left) && (mouseXY.x < parentRect.right))
&& ((mouseXY.y > parentRect.top) && (mouseXY.y < parentRect.bottom))) {
mouseInGrid = true;
}
if (mouseInGrid === true && (layout.value.findIndex(item => item.i === 'drop')) === -1) {
layout.value.push({
x: (layout.value.length * 2) % (GRID_COL_NUM || 12),
y: layout.value.length + (GRID_COL_NUM || 12), // puts it at the bottom
w: 1,
h: 1,
i: 'drop',
});
}
const index = layout.value.findIndex(item => item.i === 'drop');
if (index !== -1) {
const el = gridItem.value[index];
el.dragging.data = { top: mouseXY.y - parentRect.top, left: mouseXY.x - parentRect.left };
const new_pos = el.calcXY(mouseXY.y - parentRect.top, mouseXY.x - parentRect.left);
if (mouseInGrid === true) {
gridLayout.value.dragEvent('dragstart', 'drop', new_pos.x, new_pos.y, 1, 1);
DragPos.i = String(index);
DragPos.x = layout.value[index].x;
DragPos.y = layout.value[index].y;
}
if (mouseInGrid === false) {
gridLayout.value.dragEvent('dragend', 'drop', new_pos.x, new_pos.y, 1, 1);
layout.value = layout.value.filter(obj => obj.i !== 'drop');
}
}
}
function dragend(e: DragEvent) {
// const parentRect = document.getElementById('dashboard-panel').getBoundingClientRect();
const parentRect = dashboardPanel.value.getBoundingClientRect();
let mouseInGrid = false;
if (((mouseXY.x > parentRect.left) && (mouseXY.x < parentRect.right))
&& ((mouseXY.y > parentRect.top) && (mouseXY.y < parentRect.bottom))) {
mouseInGrid = true;
}
if (mouseInGrid === true) {
gridLayout.value.dragEvent('dragend', 'drop', DragPos.x, DragPos.y, 1, 1);
layout.value = layout.value.filter(obj => obj.i !== 'drop');
// UNCOMMENT below if you want to add a grid-item
this.layout.push({
x: DragPos.x,
y: DragPos.y,
w: 1,
h: 1,
i: DragPos.i,
});
this.$refs.gridLayout.dragEvent('dragend', DragPos.i, DragPos.x,DragPos.y,1,1);
try {
this.$refs.gridLayout.$children[this.layout.length].$refs.item.style.display="block";
} catch {
}
}
}
return {
gridLayout,
gridItem,
dashboardPanel,
layout,
movedId,
inited,
isLayoutReady,
isShowEditRowDialog,
rowForm,
};
},
render() {
if (!this.inited) {
return (<Loading/>);
}
return (
<div
ref='dashboardPanel'
id='dashboard-panel'
class={'dashboard-panel flex-1'}>
<GridLayout
ref='gridLayout'
layout={this.layout}
col-num={GRID_COL_NUM}
row-height={GRID_ROW_HEIGHT}
is-resizabl={this.editable}
is-draggable={this.editable}
vertical-compact={true}
use-css-transforms={false}
margin={GRID_ROW_MARGIN}
on-layout-updated={this.handleLayoutUpdated}
on-layout-ready={this.onLayoutReady}
>
{
this.layout.map((item) => {
return (
<GridItem
ref={(el: any) => {
if (el) {
this.gridItem.push(el);
}
}}
{{...item}}
>
{chart}
</GridItem>
);
})
}
</GridLayout>
</div>
);
},
});
当然,这个代码是抽离出来的。
这个vue3-grid-layout,自己写了弄了一版,https://github.com/zhoulujun/vue3-grid-layout
转载本站文章《vue2升级vue3: TSX Vue 3 Composition API Refs》,
请注明出处:https://www.zhoulujun.cn/html/webfront/ECMAScript/vue3/8873.html
vue2升级vue3: TSX Vue 3 Composition API Refs的更多相关文章
- vue2升级vue3:Vue Demij打通vue2与vue3壁垒,构建通用组件
如果你的vue2代码之前是使用vue-class-component 类组件模式写的.选择可以使用 https://github.com/facing-dev/vue-facing-decorator ...
- vue2升级vue3:vue2 vue-i18n 升级到vue3搭配VueI18n v9
项目从vue2 升级vue3,VueI18n需要做适当的调整.主要是Vue I18n v8.x 到Vue I18n v9 or later 的变化,其中初始化: 具体可以参看:https://vue- ...
- vue2升级vue3指南(二)—— 语法warning&error篇
本文总结了vue2升级vue3可能会遇到的语法警告和错误,如果想知道怎样升级,可以查看我的上一篇文章:vue2升级vue3指南(一)-- 环境准备和构建篇 Warning 1.deep /deep/和 ...
- vue2升级vue3:vue-i18n国际化异步按需加载
vue2异步加载之前说过,vue3还是之前的方法,只是把 i18n.setLocaleMessage改为i18n.global.setLocaleMessage 但是本文还是详细说一遍: 为什么需要异 ...
- uniapp项目vue2升级vue3简单记录
看到好多开源项目都升级了vue3,看文章说vue3性能升级很多,而且组合式api很香,遂把最近开发的自助洗车app升级下,在此记录下出现的问题. uniapp升级vue3官方指南 我是先去vue官网看 ...
- 蒲公英 · JELLY技术周刊 Vol.21 -- 技术周刊 · React Hooks vs Vue 3 + Composition API
蒲公英 · JELLY技术周刊 Vol.21 选 React 还是 Vue,每个人心中都会有自己的答案,有很多理由去 pick 心水的框架,但是当我们扪心自问,我们真的可以公正的来评价这两者之间的差异 ...
- vue2升级vue3指南(一)—— 环境准备和构建篇
1.nodejs和npm 注意二者的版本,版本过低需要升级,本人升级后的版本如下: $ node -v v16.15.1 $ npm -v 8.11.0 2.package.json 和依赖升级 由于 ...
- Vue3:不常用的Composition API && Fragment、Teleport、Suspense && 与Vue2对比的一些变化
1 # 一.Vue3不常用的Composition API 2 # 1.shallowReactive与shallowRef 3 .shallowReactive: 只处理对象最外层属性的响应式(浅响 ...
- Vue2 到 Vue3,重温这 5 个常用的 API
距离Vue3发布已经过去一年多时间了,从Vue2到Vue3是一个不小的升级,包括周边生态等.虽然目前大多数开发者们在使用的仍旧以Vue2为准,但Vue3显然是Vue开发者们未来必须面对的,而且前不久V ...
- 了解 Vue 的 Compsition API
在这篇文章中,我将讲讲 Vue 的 Composition API 为什么比之前的 Options API 要好,以及它是如何工作的. Options API 有什么问题 首先,这里不是要大家放弃 O ...
随机推荐
- Java Exception最佳实践(转)
https://www.dubby.cn/detail.html?id=9033 1.异常介绍 2.Java中的异常介绍 3.自定义异常 4.几个建议 1)不要生吞异常 2)申明具体的异常 3)尽可能 ...
- 手撕Vuex-模块化共享数据上
前言 好,经过上一篇的介绍,实现了 Vuex 当中的 actions 方法,接下来我们来实现 Vuex 当中的模块化共享数据(modules). modules 方法用于模块化共享数据,那么什么叫模块 ...
- Redis Functions 介绍之二
首先,让我们先回顾一下上一篇讲的在Redis Functions中关于将key的名字作为参数和非key名字作为参数的区别,先看下面的例子.首先,我们先在一个Lua脚本文件mylib.lua中定义如下的 ...
- go基础-方法
概述 方法是面向对象编程 (OOP) 的一个特性,在 C++/Java 语言中方法是类函数,go做为函数式编程语言,通过特有技能支持相似的功能,所以说go也支持面向对象编程特性. go 方法本质也是函 ...
- Vue3 第三章
Vite目录 public 下面的不会被编译 可以存放静态资源 assets 下面可以存放可编译的静态资源 components 下面用来存放我们的组件 App.vue 是全局组件 main ts 全 ...
- jmeter-jsr223取样器的使用
相比于BeanShell 取样器,JSR223取样器具有可大大提高性能的功能(编译)如果需要,一定要使用JSR223取样器编写脚本是更好的选择!!! 属性描述名称:显示的此取样器的描述性名称,可自定义 ...
- [NOI online2022普及A] 王国比赛
题目描述 智慧之王 Kri 统治着一座王国. 这天 Kri 决定举行一场比赛,来检验自己大臣的智慧. 比赛由 \(n\) 道判断题组成,有 \(m\) 位大臣参加.现在你已经知道了所有大臣的答题情况, ...
- 安卓之各种Adapter优劣分析
文章摘要 在 Android 开发中,适配器(Adapter)是一种非常重要的设计模式,它用于将数据与视图组件进行绑定.适配器可以帮助我们在不同的视图组件(如 ListView.GridView.Re ...
- ElasticSearch-document文档数据-增删改
文档就是相当于每条记录. 每个文档(数据记录行)都有几个元数据,分别是: _index,表示该文档是那个索引中的. _type,表示文档的类型 _id,文档的唯一ID编号 _score,相关性分数. ...
- 华企盾DSC启动服务器提示“发生系统错误5”
解决方法:没有管理员权限 导致,需要以管理员权限运行服务器安装包,覆盖安装一下