开发中遇到的问题

ref和reactive的区别

在 Vue 3 中,refreactive 都是用来创建响应式数据的方法,但它们之间存在一些关键的区别,主要在于它们的用途和工作方式。

ref

ref 是用来创建一个响应式的引用类型。当你使用 ref 创建一个变量时,你会得到一个具有 .value 属性的对象,这个属性实际上指向了响应式的数据。这是 ref 的典型用法:

import { ref } from 'vue';

const myRef = ref(10);
console.log(myRef); // 输出:{ value: 10 }
console.log(myRef.value); // 输出:10

在模板中,你通常需要使用 .value 来访问 ref 的值:

<template>
  <div>{{ myRef.value }}</div>
</template>

ref 主要用于以下场景:

  • 当你需要在组件的模板中直接绑定一个变量的值。
  • 当你需要在计算属性、条件语句或循环中使用一个值。
  • 当你想要创建一个单一的响应式值。
reactive

reactive 是用来创建一个完整的响应式对象。与 ref 不同,reactive 直接返回一个普通的 JavaScript 对象,其中的所有属性都是响应式的:

import { reactive } from 'vue';

const state = reactive({ count: 10 });
console.log(state); // 输出:{ count: 10 }
console.log(state.count); // 输出:10

由于 reactive 返回的是普通对象,你不需要 .value 访问器来获取或设置值:

<template>
  <div>{{ state.count }}</div>
</template>

reactive 更适合以下场景:

  • 当你有一个复杂的数据结构,如对象或数组,需要完全响应式。
  • 当你想要避免使用 .value 访问器来简化代码。
总结
  • ref 适用于单个变量或简单的数据类型,需要 .value 访问器来读取或修改值。
  • reactive 适用于复杂的对象结构,不需要额外的访问器,可以直接使用点语法读取或修改属性。

ElementPlus中的slot槽

 

Element Plus(简称 EP)是 Element UI 的一个全面升级版,专为 Vue 3 设计,提供了丰富的 UI 组件。在 Element Plus 中,`slot`(插槽)是一种非常重要的概念,用于父组件向子组件注入内容。插槽允许你在组件的不同位置放置自定义的内容,这增加了组件的复用性和灵活性。

基本插槽(默认插槽)

基本插槽是最简单的插槽类型,它允许你在组件标签体中放置内容。例如,在使用 `el-button` 组件时,你可以在按钮标签内放置文本:

<template>
  <el-button>点击我</el-button>
</template>

这里的 `"点击我"` 就是放置在默认插槽中的内容。

 具名插槽

具名插槽允许你指定一个插槽名称,然后在组件模板中使用这个名称来插入内容。这对于组件有多个可以插入内容的位置时非常有用。例如,在 `el-card` 组件中,你可以使用具名插槽来添加标题和内容:

<template>
  <el-card>
    <template #header>
      <div>卡片标题</div>
    </template>
    <div>卡片内容</div>
  </el-card>
</template>

这里的 `#header` 就是一个具名插槽,你可以在 `el-card` 组件中定义这个插槽来展示自定义的头部内容。

作用域插槽

作用域插槽允许父组件访问子组件的数据或方法。这通常通过在插槽中定义一个带有数据的插槽属性来实现。例如,在 `el-table` 中,你可以使用作用域插槽来自定义单元格的内容:

<template>
  <el-table :data="tableData">
    <template #name="{ row }">
      <span>{{ row.name }}</span>
    </template>
  </el-table>
</template>

<script setup>
import { ref } from 'vue';
const tableData = ref([
  { name: '张三', age: 24 },
  { name: '李四', age: 22 },
]);
</script>

在这个例子中,`#name` 插槽接收一个 `row` 对象,它是当前行的数据。你可以在插槽模板中使用这个对象来展示行数据。

 动态插槽

动态插槽允许你使用变量来决定使用哪个插槽。这对于需要动态决定插槽名称的场景很有用。例如:

<template>
  <el-card>
    <template v-for="slot in ['header', 'footer']" :key="slot" #[slot]="{}">
      <div>{{ slot }} 内容</div>
    </template>
  </el-card>
</template>

这里使用 `v-for` 和 `#[slot]` 语法来动态地渲染 `header` 和 `footer` 插槽。

通过使用插槽,Element Plus 组件可以变得更加灵活和可定制,从而适应不同的UI需求。

对话框、自定义标题、表单、展现控制、新增和修改控制

 对话框我们使用的时element-plus中的对话框组件

<div style="padding-left: 50px;">
		<el-card style="width: 500px;">
			<el-button type="primary" @click = "toadd">新增</el-button>
			<el-table :data="tableData" style="width: 100%">
				<el-table-column type="selection" property="id" width="55" />
				
				<el-table-column property="name" label="姓名" width="120" />
				<el-table-column property="address" label="地址" />
				<el-table-column label="操作" align="center">
					<template #default="scope">
					<el-button type="success" size="small" @click="toupdate(scope.row)">修改</el-button>
					<el-button type="danger" size="small" @click="del(scope.row.id)">删除</el-button>
					</template>
				</el-table-column>
			</el-table>
		</el-card>
	</div>
	
	<el-dialog v-model="dialogFormVisible"  width="500">
	    <template #header>
			{{dialogTitle}}商品分类管理
		</template>
		
		<el-form :model="form">
			<el-form-item label="分类">
				<el-input v-model="form.name"></el-input>
			</el-form-item>
		</el-form>
	    <template #footer>
	      <div class="dialog-footer">
	        <el-button @click="dialogFormVisible = false">取消</el-button>
	        <el-button type="primary" @click="save">
	          保存
	        </el-button>
	      </div>
	    </template>
	  </el-dialog>

 自定义标题

 <template #header>
			{{dialogTitle}}商品分类管理
		</template>

 通过槽函数进行自定义标题

展现控制:通过控制dialogFormVisible来判断表单是否展示。

新增控制:首先将dialogFormVisible置为true,将隐藏的表单展示出来,接着填写内容,提交新增内容,点击完成时,将dialogFormVisible重新置为false即可。

修改也是类似的控制流程。

雪花算法引起javascript long型精度问题及解决方案

 现象:雪花算法生成的ID通常是64位的长整型数字,这在很多编程语言中都可以很好地处理。然而,在JavaScript中,由于其数字类型是基于双精度浮点数(Double-precision 64-bit binary format IEEE 754)实现的,只能保证在-2^532^53-1(即大约-9,007,199,254,740,9919,007,199,254,740,991)之间的整数精度。这意味着64位雪花算法生成的ID,尤其是那些大于2^53-1的值,在JavaScript中会丢失精度。

解决方案:

使用[JsonConverter(typeof(LongToStringConverter))]特性来指示编译器在序列化和反序列化时使用我们的自定义转换器。在序列化过程中,long类型的值会被转换为字符串,而在反序列化时,字符串会被转换回long类型。

通过这种方式,可以在.NET应用程序中有效地处理long类型在JSON中的字符串表示,确保数据在传输过程中的完整性和兼容性。

internal class LongToStringConverter : JsonConverter<long>
{
    public override long Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // 读取时将字符串转换回long
        return long.Parse(reader.GetString());
    }

    public override void Write(Utf8JsonWriter writer, long value, JsonSerializerOptions options)
    {
        // 写入时将long转换为字符串
        writer.WriteStringValue(value.ToString());
    }
}

 调用该自定义转换器:

  [Table("tb_class")]
  public class Classify
  {
      [JsonConverter(typeof(LongToStringConverter))]
      public long? Id { get; set; }
      public string? Name { get; set; }
  }

 

什么是RESTful

 

RESTful(Representational State Transfer 的缩写,表述性状态转移)是一种软件架构风格,主要用于设计网络应用程序的API,特别是Web服务。RESTful API的设计基于HTTP协议,遵循一系列原则和约束条件,以实现简洁、可扩展、易于理解、安全且能够自描述的网络服务。

以下是RESTful API的一些关键特征和原则:

1. **无状态(Stateless)**:
   RESTful服务在每个请求之间应该是无状态的,即服务器不会保存任何有关客户端状态的信息。每次请求必须包含所有必要的信息,以便服务器能够理解并处理请求。

2. **客户端-服务器模型(Client-Server Model)**:
   RESTful架构将用户界面(客户端)与数据存储(服务器)分离,这使得两者可以独立演化。客户端负责用户界面和用户体验,而服务器负责数据存储和业务逻辑。

3. **缓存(Cacheability)**:
   RESTful服务的响应可以被标记为可缓存或不可缓存,这有助于提高性能和减少带宽消耗。

4. **统一的接口(Uniform Interface)**:
   RESTful API具有统一的接口,包括:
   - **资源定位**:使用URL来唯一标识资源。
   - **无状态的HTTP方法**:使用标准的HTTP方法(如GET、POST、PUT、DELETE)来操作资源。
   - **状态码**:使用HTTP状态码来表示请求的结果。
   - **超媒体作为应用状态引擎(HATEOAS)**:响应中包含链接到其他相关资源的链接,使得客户端能够发现和跟随这些链接,从而进一步操作资源。

5. **分层系统(Layered System)**:
   RESTful架构可以构建在分层系统之上,这意味着中间层可以缓存、过滤、授权或重定向请求,而不影响上层或下层的客户端或服务器。

6. **按需代码(Code on Demand)**(可选):
   服务器可以扩展客户端的功能,通过在响应中包含代码(如JavaScript、CSS)来执行某些操作,但这不是强制性的。

RESTful API的设计强调了清晰的URL结构和使用标准的HTTP方法来表达资源的操作,使得API易于理解和使用。此外,RESTful API通常返回JSON或XML格式的数据,便于跨语言和跨平台的使用。

对象赋值和Object.Assign的区别

 

在 Vue 3 中,处理对象赋值时,理解直接赋值和 `Object.assign()` 的区别非常重要,因为这直接影响到数据的响应式行为和性能。

直接赋值

直接赋值通常指的是使用赋值运算符 `=` 来复制一个对象。然而,在 JavaScript 中,对象赋值实际上是浅拷贝,也就是说,你只是在复制对象的引用,而不是对象本身的内容。例如:

const original = { a: 1, b: 2 };
const copy = original;
original.a = 3;

console.log(copy); // 输出:{ a: 3, b: 2 }

在 Vue 中,由于数据的响应式特性,直接赋值一个响应式对象会导致 Vue 无法追踪到对象内部属性的变化,从而可能引发视图更新的问题。这是因为 Vue 通过代理和 getter/setter 来追踪对象属性的读写,直接赋值会绕过这一机制。

 Object.assign()

`Object.assign()` 方法用于合并一个或多个源对象到目标对象中。它会浅拷贝源对象的可枚举属性到目标对象上。例如:

const target = {};
const source = { a: 1, b: 2 };
Object.assign(target, source);
console.log(target); // 输出:{ a: 1, b: 2 }

尽管 `Object.assign()` 提供了对象属性的复制,但它仍然只进行浅拷贝,即对于对象的属性,它只会复制引用,不会深入拷贝对象内部的属性。这意味着如果源对象的属性是另一个对象,那么这个属性也会被浅拷贝,即复制引用而不是值。

在 Vue 3 中,使用 `Object.assign()` 来更新响应式对象同样可能导致响应式失效的问题,因为 Vue 无法追踪到新赋值的对象属性。例如,如果你有一个响应式对象,然后使用 `Object.assign()` 更新它,Vue 可能无法察觉到内部属性的变化,除非你使用正确的 Vue API 如 `this.$set` 或 `Vue.set`,或者使用 Vue 3 的 `ref` 和 `reactive` API 来创建响应式数据。

 Vue 3 的响应式 API

在 Vue 3 中,推荐使用 Composition API 中的 `reactive` 和 `ref` 来创建和操作响应式数据。对于对象,你可以使用 `reactive`:

import { reactive } from 'vue';

const state = reactive({ a: 1, b: 2 });
state.a = 3; // Vue 能够追踪到这个变化

如果需要深拷贝一个对象并保持响应式,你可以先使用 `JSON.parse(JSON.stringify(obj))` 或者第三方库如 lodash 的 `_.cloneDeep` 方法进行深拷贝,然后再用 `reactive` 包装。

总结来说,直接赋值和 `Object.assign()` 在 Vue 3 中可能不会保持数据的响应式特性,而使用 Vue 的响应式 API (`reactive`, `ref`) 是处理对象赋值和保持响应式行为的最佳实践。

如何实现修改回显

 在我们的前端的项目中如果想实现表单的修改功能,思路:首先将要将表单本来的内容填写到新开的表单上,然后进行操作即可

<el-button type="success" size="small" @click="toupdate(scope.row)">修改</el-button>
const toupdate=(row)=>{
		dialogFormVisible.value=true
		dialogTitle.value = "修改"
		
		Object.assign(form,row)
		
	}

 

如何实现新增清空数据

 在实现新增功能时,因为我们的代码里面使用的一个form所以,在新增界面需要将form的信息清除,这需要进行重新赋空值,注意不能赋null,不允许赋null。

const toadd=()=>{
		dialogFormVisible.value=true
		dialogTitle.value = "新增"
		Object.assign(form,formInit)
	}

  • 28
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值