vue 0723

1、ref和reactive的区别

ref:

1. 用途:

ref 主要用于包裹基本类型值(如 Number、String、Boolean)或者用来创建一个可被 Vue 追踪的引用对象。当需要对某个基本类型值进行响应式处理时,`ref` 是非常有用的。它返回一个对象,其 .value 属性持有实际的值

2. 响应式:

当修改 .value 时,Vue 会注意到这个变化并触发相应的视图更新。这对于表单输入绑定或者简单的数据响应式处理非常适用

3. 使用场景:

适合于简单数据属性的响应式处理,或者是你需要直接操作DOM元素时

reactive:

1.用途:

reactive`则用于使一个对象的所有属性变为响应式的。当有一个包含多个属性的对象,并且希望这些属性都能自动追踪变化时,就应当使用 reactive。它返回一个新的代理对象,可以直接通过这个代理对象修改其属性,而所有变动都会被Vue自动追踪

2. 响应式:

修改代理对象的任何属性都会触发Vue的响应式系统,进而更新依赖于这些属性的视图

3. 使用场景:

更适用于复杂的、包含多个层级的数据结构。如果有一个包含多个嵌套对象的状态对象,使用 reactive`可以让你轻松地保持整个状态树的响应式

总结:

基本类型 vs 对象:

如果要使基本类型数据响应式,使用 ref;如果要使一个对象或对象的属性响应式,使用 reactive
访问方式:

ref`通过 .value`访问实际数据,而 reactive 直接通过属性访问
适用场景:

简单数据用 ref,复杂数据结构或对象用 reactive

2、ElementPlus中什么是slot槽

slot是一种在Vue组件内部预留的占位区域,允许你在使用组件时插入自定义内容。这种机制让组件变得更加灵活和可重用,它允许外部使用者决定在组件内部的特定位置显示什么内容

2.1 插槽的分类

默认插槽:没有指定name属性的插槽,即为默认插槽。父组件在插入内容时,如果没有指定插槽名称,则会插入到默认插槽中。

具名插槽:通过指定name属性来定义的插槽。父组件在插入内容时,需要使用v-slot指令(或简写为#)加上插槽名称来指定内容应该插入到哪个具名插槽中。

作用域插槽:一种特殊的插槽,它允许子组件将其内部的数据“暴露”给父组件,父组件可以根据这些数据来定制插槽的内容。作用域插槽通过v-slot来接收子组件传递的数据。

2.2 插槽的使用

表头插槽(header slot):用于自定义表格的表头内容。在ElementPlus中,表头插槽的名称可能以header-开头,并可以附加column-key属性来指定该插槽对应的列。

列插槽(default slot):用于自定义表格的列内容。在ElementPlus中,列插槽的名称为default,并可以在插槽中使用rowcolumn参数来获取当前行和列的数据。

底部插槽(footer slot):用于自定义表格的底部内容。在ElementPlus中,底部插槽的名称可能以footer-开头,并可以附加column-key属性来指定该插槽对应的列。

3.2 示例

基本使用:

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

具名slot:

<el-dialog>
  <template #title>
    自定义对话框标题
  </template>
  对话框内容
  <template #footer>
    自定义对话框底部操作按钮
  </template>
</el-dialog>

作用域slot:

<el-table :data="tableData">
  <el-table-column prop="name" label="姓名">
    <template #default="scope">
      {{scope.row.name}
    </template>
  </el-table-column>
</el-table>

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

<template>
	<div style="padding-left: 50px;">
		<el-card style="width: 500px;">
			<!-- 新增按钮: 点击后显示模态对话框,用于输入新的商品分类信息 -->
			<el-button type="primary" size="small" @click="toadd">新增</el-button>
			
			<!-- 列出了编号、商品分类,每行有选择框、分类名称和操作列(修改/删除按钮) -->
			<el-table :data="state.tableData">
				<el-table-column type="selection"  width="55" />
				<el-table-column property="id" label="编号" />
				<el-table-column property="name" label="商品分类" />
				
				<!-- 操作列: -->
				<!-- 修改: 点击后填充表单并打开模态框供用户编辑分类信息。 -->
				<!-- 删除: 根据当前行的ID调用删除功能。 -->
				<el-table-column align="center" label="操作">
					<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-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>

<script setup>
	import {ref,reactive,onMounted} from 'vue'
	import {ClassifyList,ClassifySave,ClassifyDelete} from '../api/classify.js'

	// dialogFormVisible: 控制模态对话框的显示隐藏
	const dialogFormVisible = ref(false)
	
	// dialogTitle: 显示对话框标题,区分新增和修改
	const dialogTitle = ref("新增")
	
	// form: 用于双向绑定表单输入的反应式对象,包含分类ID和名称
	const form = reactive({
		id: null,
		name:null,
	})
	
	// formInit: 用于保存表单的初始状态,便于重置表单
	var formInit = reactive({})

	//封装一个加载方法,加载页面
	// refresh: 调用ClassifyList API获取分类列表数据,并更新到state.tableData
	const refresh = ()=>{
		ClassifyList()
		.then(res =>{
			// state.tableData: 存储表格数据的反应式数组
			state.tableData = res.data
		})
		.catch(err =>{
			console.log(err)
		})
	}
	
	onMounted(()=>{
		refresh()
		Object.assign(formInit, form)
	})
	
	// var tableData = ref([])
	const state = reactive({
		tableData:[]
	})
	
	// toadd: 显示新增分类的模态框,重置表单
	const toadd = ()=>{
		dialogFormVisible.value = true
		dialogTitle.value = "新增"
		Object.assign(form, formInit)
	}
	
	// toupdate: 显示修改分类的模态框,并将当前行数据填充到表单
	const toupdate = (row)=>{
		dialogFormVisible.value = true
		dialogTitle.value = "修改"
		
		Object.assign(form, row)
	}
	
	// save: 调用ClassifySave API保存表单中的分类信息,关闭模态框并刷新列表
	const save = ()=>{
		ClassifySave(form)
		.then(()=>{
			dialogFormVisible.value = false
			refresh()
		})
	}
	
	// del: 调用ClassifyDelete API删除指定ID的分类,完成后刷新列表
	const del = (id)=>{
		ClassifyDelete(id)
		.then(()=>{
			refresh()
		})
	}
	
</script>

<style>
	.container {
	      display: flex;
	      align-items: center; /* 垂直居中对齐 */
	    }
		.container img{
			widows: 50px;
			height: 50px;
			margin-right: 15px;
		}
</style>

新增结果:

修改结果:

删除结果:

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

雪花算法(Snowflake Algorithm)是由Twitter开源的一种分布式ID生成算法,它可以生成全局唯一、趋势递增的ID。这个算法生成的ID是一个64位的整数,由时间戳、数据中心ID、机器ID和序列号组成。然而,在JavaScript中处理这种长整型数字时,可能会遇到精度问题,因为JavaScript中的Number类型虽然能表示很大范围的数值,但它遵循IEEE 754浮点数标准,对于超过53位的整数无法精确表示。

解决方案:

在自己的模型类中加上:

//负责定义如何将 long 类型转换为字符串以及如何将字符串转换回 long 类型
[JsonConverter(typeof(LongToStringConverter))]

然后在模型类中新建一个LongToStringConverter类,用于处理精度的问题

using System.Text.Json;
using System.Text.Json.Serialization;

namespace KFC527.Models
{
    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());
        }
    }
}

5、什么是RESTful

5.1 定义

RESTful是一种软件架构风格,它遵循REST(Representational State Transfer)原则,使用HTTP协议传输数据,并通过URL来定位和操作资源

5.2 特点

无状态协议:RESTful使用无状态协议,即服务器不维护与客户端的连接状态,每个请求都是独立的。这种无状态协议使得RESTful更加灵活和可扩展,可以轻松地支持并发请求和负载均衡。

基于HTTP协议:RESTful使用HTTP协议来传输数据,HTTP协议是一种通用的协议,可以轻松地与其他系统进行集成。

资源唯一标识:在RESTful中,每个资源都有一个唯一的URL,可以通过HTTP请求来获取或修改该资源的状态。

标准化:RESTful采用了一些标准化的概念和规则,如HTTP协议、URL、JSON等,使得开发人员可以更加轻松地设计和实现系统。

5.3 RESTful的核心规范与约束

统一接口:RESTful架构的核心规范是统一接口,它包含四个子约束:

        资源标识:每个资源都拥有一个资源标识,可以用来唯一地标明该资源。

        通过标准的动词对资源进行操作:客户端使用GET、POST、PUT、DELETE四个表示操作方式的动词对服务端资源进行操作。其中,GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。

        自描述性消息:资源的自描述性,即资源的表现形式(如XML或JSON)能够自我描述其结构和内容。

        HATEOAS(超媒体作为应用状态引擎):客户端可以通过服务端返回的响应来获取下一步操作所需要的信息,如操作的URL等,从而无需额外的文档即可调用到所有的服务器资源。

5.4 RESTful的应用场景

RESTful适用于许多不同的应用场景,包括:

        Web 应用程序:如社交媒体网站、博客、在线商店等。

        移动应用程序:如手机应用程序、平板电脑应用程序等。

        后端应用程序:如数据库服务器、消息队列服务器等。

        物联网设备:如智能家居设备、智能城市设备等。

5.5 RESTful的优势

        可扩展性:由于RESTful使用无状态协议,可以轻松地支持并发请求和负载均衡,从而提高系统的可扩展性。

        可靠性:RESTful使用HTTP协议来传输数据,HTTP协议是一种通用的协议,可以保证数据的可靠性和安全性。

        易于使用和管理:RESTful使用标准化的概念和规则,如HTTP协议、URL、JSON等,使得开发人员可以更加轻松地设计和实现系统。

        跨平台支持:RESTful可以用于构建跨平台的应用程序,如Web应用程序、移动应用程序、后端应用程序等。

6、对象赋值和Object.Assign的区别

6.1 对象赋值

对象赋值在JavaScript中是通过等号(=)将一个对象的引用赋给另一个变量。这意味着两个变量都指向堆内存中的同一个对象实例。因此,修改其中一个变量所引用的对象的属性,也会影响到另一个变量所引用的对象。

6.1.1 特点

        两个变量共享同一个对象实例

        修改一个变量的属性会反映到另一个变量上

        不涉及对象的复制,只是引用传递

6.1.2 实例

let obj1 = { name: 'Alice', age: 30 };  
let obj2 = obj1; // obj2 指向 obj1 所引用的对象  
obj2.name = 'Bob'; // 修改 obj2 的 name 属性  
console.log(obj1.name); // 输出 'Bob',因为 obj1 和 obj2 指向同一个对象

6.2 Object.assign()

Object.assign()是JavaScript的一个静态方法,用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象

6.2.1 特点

        浅拷贝:只复制对象自身的可枚举属性到目标对象,不会复制继承属性或不可枚举属性

        如果源对象的属性值是一个对象的引用,则只复制引用,而不是对象本身

        如果目标对象和源对象有同名属性,则源对象的属性值会覆盖目标对象的属性值

        第一个参数是目标对象,后面的参数都是源对象

6.2.2 实例

let target = { name: 'Alice', age: 30 };  
let source1 = { age: 25 };  
let source2 = { job: 'Engineer' };  
  
Object.assign(target, source1, source2);  
Object.assign(目标对象, 源对象, 源对象);   

console.log(target); // 输出 { name: 'Alice', age: 25, job: 'Engineer' }

6.3 区别

对象赋值Object.assign()
本质引用传递,两个变量指向同一个对象浅拷贝,复制可枚举属性到新对象
影响修改一个变量的属性会影响另一个变量修改源对象属性不会影响目标对象(除非引用类型)
用途简单地让两个变量共享同一个对象合并对象属性,创建新对象
深拷贝不涉及深拷贝不支持深拷贝,只复制引用类型属性的引用

7、如果实现修改回显

7.1 form的初始化与更新

// form: 用于双向绑定表单输入的反应式对象,包含分类ID和名称
	const form = reactive({
		id: null,
		name:null,
	})

// toupdate: 显示修改分类的模态框,并将当前行数据填充到表单
	const toupdate = (row)=>{
		dialogFormVisible.value = true
		dialogTitle.value = "修改"
		
		Object.assign(form, row)
	}

form对象用于存储表单数据,当用户点击“修改”按钮时,toupdate方法会被调用,它接收当前行的数据row,并通过Object.assign将当前行的数据复制到form中,从而实现表单的回显。

7.2 对话框的显示与标题变更:

// dialogTitle: 显示对话框标题,区分新增和修改
	const dialogTitle = ref("新增")

// toadd: 显示新增分类的模态框,重置表单
	const toadd = ()=>{
		dialogTitle.value = "新增"

	}
	
	// toupdate: 显示修改分类的模态框,并将当前行数据填充到表单
	const toupdate = (row)=>{
		dialogTitle.value = "修改"

	}

dialogTitle用来控制模态对话框的标题,初始化为"新增"。在toupdate方法中,当用户点击修改时,标题会变更为"修改",以指示用户正在进行修改操作。在toadd方法中,当用户点击修改时,标题会变更为"新增",以指示用户正在进行增加操作

7.3 对话框的显示控制

	// dialogFormVisible: 控制模态对话框的显示隐藏
	const dialogFormVisible = ref(false)

    const toadd = ()=>{
		dialogFormVisible.value = true
	}
	
	// toupdate: 显示修改分类的模态框,并将当前行数据填充到表单
	const toupdate = (row)=>{
		dialogFormVisible.value = true
	}

dialogFormVisible控制对话框的显示与隐藏。在toaddtoupdate方法中,通过改变其值为true来显示对话框,从而开启新增或修改操作

8、如何实现新增清空数据

8.1 初始化表单数据

// form: 用于双向绑定表单输入的反应式对象,包含分类ID和名称
	const form = reactive({
		id: null,
		name:null,
	})

在脚本中,定义了form作为表单绑定的数据对象,,用于存储表单的当前状态

// formInit: 用于保存表单的初始状态,便于重置表单
	var formInit = reactive({})

formInit 是另一个响应式对象,用于存储表单的初始状态,以便在需要时可以重置表单

8.2 复制 form 到 formInit

onMounted(()=>{
		refresh()
		Object.assign(formInit, form)
	})

将 form 的当前状态(此时为初始状态)复制到 formInit

8.3 用toadd 函数以重置表单

// toadd: 显示新增分类的模态框,重置表单
	const toadd = ()=>{
		dialogFormVisible.value = true
		dialogTitle.value = "新增"
		Object.assign(form, formInit)
	}

当调用 toadd 方法时,form 会被重置为formInit(初始状态),所有表单字段都会被清空,为新增商品分类准备了一个干净的表单

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值