共 20 篇文章

标签:回调函数 第2页

wordpress 钩子-国外主机测评 - 国外VPS,国外服务器,国外云服务器,测评及优惠码

wordpress 钩子

WordPress钩子是WordPress中非常重要的功能之一,它允许开发者在特定事件发生时执行自定义代码,本文将详细介绍如何使用动作、过滤器和自定义钩子。,动作是一段可执行的代码,可以在特定事件发生时被调用,当用户发布一篇文章时,可以触发一个动作来发送电子邮件通知。, ,1、添加动作:,使用 add_action()函数添加动作,该函数接受三个参数:动作名称、触发事件的标签和要执行的回调函数。,示例代码:,“`php,add_action(‘publish_post’, ‘my_function’);,“`,上述代码将在文章发布时触发名为 publish_post的动作,并执行 my_function函数。,2、删除动作:,使用 remove_action()函数删除动作,该函数接受两个参数:动作名称和要执行的回调函数。,示例代码:,“`php,remove_action(‘publish_post’, ‘my_function’);,“`,上述代码将删除名为 publish_post的动作。,过滤器用于修改或过滤数据流中的值,可以使用过滤器修改主题中的标题样式。,1、添加过滤器:,使用 add_filter()函数添加过滤器,该函数接受三个参数:过滤器名称、要过滤的参数和要执行的回调函数。,示例代码:,“`php,add_filter(‘get_the_title’, ‘my_function’);, ,“`,上述代码将在获取标题时触发名为 get_the_title的过滤器,并执行 my_function函数。,2、删除过滤器:,使用 remove_filter()函数删除过滤器,该函数接受两个参数:过滤器名称和要执行的回调函数。,示例代码:,“`php,remove_filter(‘get_the_title’, ‘my_function’);,“`,上述代码将删除名为 get_the_title的过滤器。,除了内置的动作和过滤器,还可以创建自定义钩子来满足特定的需求,自定义钩子允许开发者在特定事件发生时执行自定义代码。,1、添加自定义钩子:,使用 do_action()函数添加自定义钩子,该函数接受一个参数:钩子名称。,示例代码:,“`php,do_action(‘my_custom_hook’);,“`,上述代码将在执行到 do_action('my_custom_hook')时触发名为 my_custom_hook的自定义钩子。,2、删除自定义钩子:,使用 remove_action()函数删除自定义钩子,该函数接受两个参数:钩子名称和要执行的回调函数。,示例代码:, ,“`php,remove_action(‘my_custom_hook’, ‘my_function’);,“`,上述代码将删除名为 my_custom_hook的自定义钩子。,相关问题与解答:,1、Q: 如何在文章发布后自动发送电子邮件通知?,A: 可以使用动作来实现这个功能,在主题的functions.php文件中添加以下代码:,“`php,add_action(‘publish_post’, ‘send_email’);,“`,创建一个名为 send_email()的函数,并在其中编写发送电子邮件的逻辑,这样,每当有文章发布时,都会触发该动作并执行邮件发送函数。,2、Q: 如何修改主题中的标题样式?,A: 可以使用过滤器来实现这个功能,在主题的functions.php文件中添加以下代码:,“`php,add_filter(‘get_the_title’, ‘change_title’);,“`,创建一个名为 change_title()的函数,并在其中编写修改标题样式的逻辑,这样,每当获取标题时,都会触发该过滤器并执行标题样式修改函数。,WordPress钩子是一种允许开发者在特定时间执行自定义功能的函数,如创建新文章、修改页面等。

虚拟主机
怎么用PHP Ajax实现手机端九宫格抽奖程序(怎么用php ajax实现手机端九宫格抽奖程序)-国外主机测评 - 国外VPS,国外服务器,国外云服务器,测评及优惠码

怎么用PHP Ajax实现手机端九宫格抽奖程序(怎么用php ajax实现手机端九宫格抽奖程序)

在当前的互联网时代,手机端的应用程序越来越受到欢迎,抽奖程序是其中一种常见的应用,而九宫格抽奖程序则是其中的一种类型,下面我将详细介绍如何使用PHP和Ajax来实现手机端的九宫格抽奖程序。,1. PHP后端实现, ,我们需要在服务器端使用PHP来处理抽奖逻辑,这主要包括生成九宫格数据、验证用户输入以及返回抽奖结果。,1.1 生成九宫格数据,我们可以创建一个二维数组来表示九宫格,然后随机生成奖品位置,,1.2 验证用户输入,当用户点击九宫格中的某个格子时,我们需要验证用户是否中奖,我们可以通过比较用户点击的位置和奖品的位置来实现这一点。,1.3 返回抽奖结果,我们需要将抽奖结果返回给客户端,我们可以使用JSON格式来传输数据。,2. Ajax前端实现, ,在客户端,我们需要使用Ajax来与服务器进行通信,这主要包括发送抽奖请求和处理抽奖结果。,2.1 发送抽奖请求,我们可以使用jQuery的 $.ajax方法来发送请求。,2.2 处理抽奖结果,在 success回调函数中,我们可以更新页面显示抽奖结果。,相关问题与解答, Q1: 如何防止用户重复抽奖?,A1: 我们可以在服务器端记录用户的抽奖状态,如果用户已经抽过奖,就不再允许抽奖。, , Q2: 如何增加抽奖的趣味性?,A2: 我们可以在九宫格中添加一些动画效果,例如奖品移动、闪烁等。, Q3: 如何保证抽奖的公平性?,A3: 我们可以在服务器端使用随机数生成器来确保奖品的位置是随机的。, Q4: 如何处理并发抽奖请求?,A4: 我们可以在服务器端使用锁或者其他同步机制来确保并发抽奖的正确性。,

虚拟主机
网络服务器中的几种服务过程模式-国外主机测评 - 国外VPS,国外服务器,国外云服务器,测评及优惠码

网络服务器中的几种服务过程模式

网络服务器中的服务过程模式是服务器软件架构的核心组成部分,它们定义了服务器如何响应和处理客户端的请求,以下是几种常见的服务过程模式:,迭代服务器(Iterative Server), ,在迭代服务器模型中,服务器一次只处理一个客户端请求,直到该请求被完全处理完毕后才会接受下一个请求,这意味着在任何给定时间点,服务器只能为一个客户端提供服务,这种方式实现简单,但不适合处理大量并发请求,因为它无法充分利用服务器的多核处理器能力。,并发服务器(Concurrent Server),与迭代服务器不同,并发服务器可以同时处理多个客户端请求,它通常通过多线程或多进程来实现,每个线程或进程独立处理一个客户端连接,并发服务器可以更好地利用多核处理器,并提高系统的吞吐量,随着并发数的增加,服务器的资源消耗也会上升,可能需要复杂的同步机制来避免竞态条件和死锁。,多路复用服务器(Multiplexing Server), 多路复用服务器使用I/O多路复用技术(如select、poll或epoll)来同时监听多个客户端连接,当某个连接准备好进行数据传输时,服务器将处理该连接上的请求,这种模式可以在不创建新线程或进程的情况下处理大量并发连接,从而减少了资源消耗,它可能会受到单线程处理能力的限制,导致性能瓶颈。,事件驱动服务器(Event-driven Server), ,事件驱动服务器是一种非阻塞的服务器模型,它依赖于异步I/O操作和事件通知机制,服务器注册感兴趣的事件(如读、写或连接建立),并在事件发生时执行相应的回调函数,这种模式非常适合高并发场景,因为它可以在不等待I/O操作完成的情况下继续处理其他任务,Node.js和Nginx都是基于事件驱动模型的流行服务器实现。,相关问题与解答,Q1: 迭代服务器和并发服务器的主要区别是什么?,A1: 迭代服务器一次只能处理一个请求,而并发服务器可以同时处理多个请求,通常通过多线程或多进程实现。,Q2: 为什么多路复用服务器比迭代服务器更高效?,A2: 多路复用服务器可以监听多个客户端连接,而不是依次处理每个连接,这样可以在不创建额外线程或进程的情况下处理更多并发请求。, ,Q3: 事件驱动服务器如何处理高并发情况下的大量请求?,A3: 事件驱动服务器通过异步I/O和事件回调机制来处理请求,这样可以避免阻塞操作,并在等待I/O完成时处理其他任务。,Q4: 在设计一个高性能的网络服务器时,应该选择哪种服务过程模式?,A4: 选择哪种服务过程模式取决于具体的应用场景和需求,对于高并发环境,通常推荐使用并发服务器、多路复用服务器或事件驱动服务器,对于低并发或需要简单实现的场景,迭代服务器可能是一个合适的选择。,

虚拟主机
js filter map-国外主机测评 - 国外VPS,国外服务器,国外云服务器,测评及优惠码

js filter map

JavaScript中的filter方法和map方法,在JavaScript中, filter() 和 map() 是两个非常实用的方法,它们分别用于过滤数组和对数组中的每个元素进行操作,这两个方法都属于数组的原型方法,可以直接在数组对象上调用,本文将详细介绍这两个方法的用法和特点。, ,filter方法, filter() 方法接收一个回调函数作为参数,该 回调函数会对数组中的每个元素进行判断,如果回调函数返回 true,则该元素会被保留在新数组中;如果返回 false,则该元素会被过滤掉。 filter() 方法返回一个新数组,包含所有满足条件的元素。,下面是一个使用 filter() 方法的示例:,在这个示例中,我们定义了一个名为 numbers 的数组,包含了一些整数,我们使用 filter() 方法创建了一个新数组 evenNumbers,其中只包含原数组中的偶数,我们打印出新数组的内容,得到 [2, 4]。,map方法, map() 方法也接收一个回调函数作为参数,但与 filter() 不同的是, map() 方法会对数组中的每个元素执行回调函数,并将结果组成一个新数组返回,换句话说, map() 方法会根据回调函数的返回值来决定是否保留原数组中的元素。,下面是一个使用 map() 方法的示例:, ,在这个示例中,我们使用 map() 方法创建了一个新数组 squaredNumbers,其中包含了原数组 numbers 中的每个元素的平方,我们打印出新数组的内容,得到 [1, 4, 9, 16, 25]。,filter和map的区别,虽然 filter() 和 map() 都是用于处理数组的方法,但它们的主要区别在于:,1、 目的不同: filter() 方法主要用于过滤数组中的元素,而 map() 方法主要用于对数组中的元素进行操作并生成新的数组。,2、 返回值: filter() 方法返回一个新数组,包含所有满足条件的元素;而 map() 方法直接修改原数组,并返回一个新的空数组。,3、 回调函数的返回值: filter() 方法的回调函数只需返回一个布尔值;而 map() 方法的回调函数需要返回一个值,这个值将被用作新数组中对应位置的元素。,其他相关问题及解答, ,1、 如何使用filter和map一起处理数组?,答:可以使用 filter() 对数组进行过滤,然后再使用 map() 对过滤后的数组进行操作。,2、 如何使用箭头函数简化代码?,答:可以使用箭头函数来简化 filter() 和 map() 方法的使用。,JavaScript中的filter和map方法用于对数组进行筛选和转换操作。

虚拟主机
关于使用ISampleGrabberCB接口获取帧数据问题-国外主机测评 - 国外VPS,国外服务器,国外云服务器,测评及优惠码

关于使用ISampleGrabberCB接口获取帧数据问题

ISampleGrabberCB接口是DirectShow库中的一个回调接口,用于在获取视频帧数据时进行自定义处理,通过实现ISampleGrabberCB接口,我们可以在获取到视频帧数据后,对其进行预处理、后处理等操作,从而满足特定的需求。,1、创建IBaseFilter对象, ,要使用ISampleGrabberCB接口,首先需要创建一个IBaseFilter对象,然后将其作为参数传递给CreateStreamSampleGrabber方法,以创建一个ISampleGrabber对象。,2、实现ISampleGrabberCB接口,接下来,需要实现ISampleGrabberCB接口,并重写其中的几个虚拟函数:,QueryInterface:用于处理其他接口的请求;, ,AddRef:增加引用计数;,Release:减少引用计数;,NewSample:当有新的视频帧数据可用时调用此函数。,3、设置回调函数, ,在创建ISampleGrabber对象后,还需要设置其 回调函数,这可以通过ISampleGrabber::SetCallback方法来实现,该方法接受一个指向ISampleGrabberCB接口实例的指针作为参数。,4、开始获取帧数据,调用IMediaControl::Run方法启动媒体流,开始获取帧数据,在NewSample回调函数中,可以对获取到的视频帧数据进行处理。,ISampleGrabberCB接口是DirectShow中用于获取帧数据的回调 接口,可以自定义实现该接口并传递给ISampleGrabber接口,来获取视频帧的数据。下面是使用ISampleGrabberCB接口获取帧数据的一般步骤: 1. 创建ISampleGrabber对象。 2. 创建ISampleGrabberCB对象。 3. 将ISampleGrabberCB对象赋值给ISampleGrabber::SetCallback方法。 4. 启动ISampleGrabber对象。 5. 循环读取帧数据。

虚拟主机
nodejs读取文件的方式-国外主机测评 - 国外VPS,国外服务器,国外云服务器,测评及优惠码

nodejs读取文件的方式

Node.js 读取文件的方法有哪些?,在 Node.js 中,我们可以使用多种方法来读取文件,本文将介绍一些常用的方法,并通过小标题进行组织,以便读者更好地理解,我们还将提供一个相关问题与解答的栏目,以帮助读者巩固所学知识。, ,1、使用 fs.readFile() 方法,fs.readFile() 是 Node.js 中最基本的文件读取方法,它接收两个参数:文件路径和 回调函数,当文件读取完成时,回调函数会被调用,并将文件内容作为参数传递给回调函数。,示例代码:,2、使用 fs.readFileSync() 方法,fs.readFileSync() 是 fs.readFile() 的同步版本,与异步版本不同,它会阻塞事件循环,直到文件读取完成,它的性能更高,但在处理大文件时可能会导致程序卡顿。, ,示例代码:,3、使用 FileReader API,对于 HTML5 中的图像和文本文件,我们还可以使用 FileReader API 来读取文件,这种方法适用于浏览器环境,而不是 Node.js,以下是一个简单的示例:,HTML 代码:,JavaScript 代码:, ,4、使用 stream API,Node.js v10.10+ 引入了基于流的 API,称为 stream API,这种方法允许我们更高效地处理大型文件,因为它可以在不加载整个文件到内存的情况下逐步读取文件,以下是一个简单的示例:,Node.js 读取文件的方式有很多种,其中最简单的方法是使用 fs.readFile() 方法。该方法接收三个参数:文件路径、编码和将使用文件数据(以及错误)调用的回调函数。

虚拟主机
Python回调函数:实现异步编程的精髓-国外主机测评 - 国外VPS,国外服务器,国外云服务器,测评及优惠码

Python回调函数:实现异步编程的精髓

回调函数是一种在异步编程中常用的技术,它允许一个函数在另一个函数完成某个任务后被调用,这种机制使得程序可以在等待某个操作完成的同时执行其他任务,从而提高程序的效率和响应速度,本文将详细介绍Python中的 回调函数以及如何使用它们实现异步编程。,我们需要了解什么是回调函数,回调函数是一个作为参数传递给另一个函数的函数,当主函数完成某个任务后,它会调用回调函数,将任务的结果作为参数传递给回调函数,这样,我们可以在主函数执行过程中,根据需要调用不同的回调函数来处理任务的结果。, ,在Python中,我们可以使用 async def和 await关键字来定义异步函数,异步函数是一种特殊的函数,它可以在等待某个操作完成的同时执行其他任务,这使得我们可以利用多核处理器的优势,提高程序的性能。,下面是一个简单的示例,演示了如何使用回调函数实现异步编程:,在这个示例中,我们定义了一个名为 callback的回调函数,它接受一个参数 result,并将其打印出来,我们定义了一个名为 main的异步函数,它使用 await关键字等待1秒钟,然后计算出结果42,并调用回调函数 callback将结果传递给它,我们使用 asyncio.run()函数运行 main函数。,当我们运行这个程序时,会看到以下输出:, ,回调函数被调用,结果是: None,这是因为 callback函数是在主函数完成任务后才被调用的,所以它的返回值是 None,如果我们将输出语句修改为:,那么程序的输出将会是:,回调函数被调用,结果是: Hello, ,这是因为我们在回调函数中添加了一个返回语句,将字符串”Hello”作为结果返回给主函数,主函数接收到这个返回值后,将其打印出来。,总结一下,回调函数是实现异步编程的关键所在,通过将回调函数作为参数传递给异步函数,我们可以在主函数执行过程中根据需要调用不同的回调函数来处理任务的结果,这种机制使得程序可以在等待某个操作完成的同时执行其他任务,从而提高程序的效率和响应速度。,

虚拟主机
jquery如何实现Ajax请求-国外主机测评 - 国外VPS,国外服务器,国外云服务器,测评及优惠码

jquery如何实现Ajax请求

Ajax(Asynchronous JavaScript and XML)是一种在不重新加载整个网页的情况下,与服务器交换数据并更新部分网页内容的技术,jQuery是一个流行的JavaScript库,它简化了Ajax请求的编写和实现,本文将介绍如何使用jQuery实现Ajax请求。, ,我们需要在HTML文件中引入jQuery库,可以通过以下方式引入:,接下来,我们可以使用jQuery的`$.ajax()`方法来实现Ajax请求,该方法接收一个配置对象作为参数,其中包含以下属性:,1. `url`(必需):请求的目标URL。,2. `type`(可选):请求的类型,如`GET`、`POST`等,默认为`GET`。,3. `dataType`(可选):预期服务器返回的数据类型,如`json`、`xml`等,默认为`json`。,4. `data`(可选):发送到服务器的数据,以键值对的形式。,5. `success`(可选):请求成功时执行的回调函数。, ,6. `error`(可选):请求失败时执行的 回调函数。,7. `complete`(可选):请求完成(无论成功或失败)时执行的回调函数。,8. `timeout`(可选):请求超时时间(以毫秒为单位),如果未指定,则使用浏览器的默认超时时间。,9. `cache`(可选):是否使用缓存,默认为`true`。,10. `context`(可选):设置回调函数中的`this`值,默认为全局对象。,11. `xhrFields`(可选):设置XMLHttpRequest对象的属性。,下面是一个简单的示例,展示了如何使用jQuery实现Ajax请求:, ,在这个示例中,我们向“发送了一个GET请求,并期望返回JSON格式的数据,当请求成功时,我们打印返回的数据;当请求失败时,我们打印错误信息;当请求完成时,我们打印一个提示信息。,相关问题与解答:,1. 如何处理跨域请求?,答:跨域请求是指来自不同域名、端口或协议的请求,为了解决跨域问题,可以使用JSONP、CORS(跨域资源共享)或者后端代理等方式,在本教程中,我们使用的是jQuery的`$. ajax()`方法,它支持跨域请求,只需在配置对象中设置`url`属性即可,需要注意的是,某些网站可能会禁用跨域请求,因此在使用前请确保目标网站允许跨域访问。,2. 如何发送POST请求?,答:要使用jQuery发送POST请求,可以将配置对象中的`type`属性设置为`POST`,并提供一个包含要发送的数据的对象。,

虚拟主机
js中迭代是什么意思-国外主机测评 - 国外VPS,国外服务器,国外云服务器,测评及优惠码

js中迭代是什么意思

在jQuery中,迭代是指对集合中的每个元素执行相同操作的过程,这使得我们可以轻松地遍历和处理数据集中的每个项目,而无需手动编写循环代码,jQuery提供了多种方法来实现迭代,如.each()、.map()、.filter()等,本文将详细介绍这些方法及其用法。, ,我们来看一个简单的示例,假设我们有一个HTML列表:,我们想要使用jQuery遍历这个列表并为每个列表项添加一个类名,我们可以使用.each()方法来实现这个需求:,在这个示例中,我们首先通过ID选择器选中了列表中的所有列表项(`#myList li`),然后使用.each()方法对每个列表项执行一个回调函数,回调函数接收两个参数:当前迭代的索引(index)和当前迭代的元素(element),在回调函数内部,我们使用jQuery的$(element)语法来选取当前元素,并为其添加一个名为”item”的类名。,除了.each()方法外,jQuery还提供了其他一些用于迭代的方法,如:,1. .map():将一个函数应用于集合中的每个元素,并返回一个新的集合,其中包含应用函数后的结果。, ,2. .filter():根据指定的条件筛选集合中的元素,并返回一个新的集合。,3. .reduce():将集合中的元素按照指定的操作进行累积,并返回一个值。,接下来,我们来看一些相关问题与解答:,Q1: jQuery中的$.each()方法有什么用途?如何使用它?,A1:$.each()方法用于遍历集合中的每个元素并对其执行指定的操作,使用方法如下:$.each(collection, callback(indexInArray, valueOfElement));其中,collection是要遍历的集合,callback是每次迭代时要执行的回调函数,回调函数接收两个参数:当前迭代的索引(indexInArray)和当前迭代的元素(valueOfElement)。, ,Q2: jQuery中的$.map()方法有什么用途?如何使用它?,A2:$.map()方法用于将一个函数应用于集合中的每个元素,并返回一个新的集合,其中包含应用函数后的结果,使用方法如下:return $.map(collection, function(valueOfElement, indexInArray){ /* return newValue */ });其中,collection是要遍历的集合,function是应用于每个元素的函数,该函数接收两个参数:当前迭代的元素(valueOfElement)和当前迭代的索引(indexInArray)。,Q3: jQuery中的$.filter()方法有什么用途?如何使用它?,A3:$.filter()方法用于根据指定的条件筛选集合中的元素,并返回一个新的集合,使用方法如下:return $.filter(collection, [predicate]);其中,collection是要筛选的集合,predicate是一个可选的条件函数,该函数接收一个参数:当前迭代的元素(valueOfElement),并返回一个布尔值表示是否保留该元素,如果省略predicate参数,则默认保留所有元素。,

虚拟主机
ajax跨域请求解决方案-国外主机测评 - 国外VPS,国外服务器,国外云服务器,测评及优惠码

ajax跨域请求解决方案

在Web开发中,由于浏览器的同源策略限制,当使用Ajax进行跨域请求时,往往会遇到安全和权限的问题,为了解决这一问题,开发者需要采取特定的技术手段来实现跨域请求,以下是一些常用的方法来处理Ajax跨域请求问题:,JSONP, ,JSONP(JSON with Padding)是一种历史悠久的解决方案,它的基本思想是在网页中动态创建一个 <script>标签,通过这个标签向服务器请求数据,服务器响应的数据被包裹在一个调用某个JavaScript函数的字符串中,当浏览器加载并执行这个脚本时,就会触发该函数,并将数据作为参数传递给它。, 如何使用JSONP?,1、在客户端定义一个处理数据的函数。,2、通过创建 <script>标签,设置其 src属性为目标URL,并附加一个回调函数参数。,3、服务器端接收到请求后,将数据用回调函数名包裹起来,并返回。,4、浏览器加载脚本并执行,自动调用回调函数处理数据。,CORS,CORS(Cross-Origin Resource Sharing)是一个更为现代且安全的跨域解决方案,它允许服务器指定哪些来源的请求是允许的,从而放宽了同源策略的限制。, 如何实现CORS?,1、服务器需要在响应头中添加 Access-Control-Allow-Origin字段,指定允许的来源。,2、浏览器在发起请求时,会检查该字段,若匹配则允许跨域。,3、根据需求,还可以设置其他相关的CORS响应头,如 Access-Control-Allow-Methods和 Access-Control-Allow-Headers等。, ,服务器代理,前端无法控制服务器的配置,这时可以通过自己搭建一个代理服务器来解决跨域问题。, 如何搭建代理服务器?,1、创建一个服务器端的中间层,作为代理服务器。,2、前端发起请求时,不再直接请求目标服务器,而是请求代理服务器。,3、代理服务器接收到请求后,转发给目标服务器,并将结果返回给前端。,4、由于代理服务器与前端处于同一域,因此避免了跨域问题。,修改document.domain,当主域相同时,不同子域之间的页面也可以进行交互,可以通过设置 document.domain为基础主域来绕过浏览器的同源策略。, 如何使用document.domain?,1、确保所有涉及交互的页面的基础主域相同。,2、在每个页面的JavaScript代码中,设置 document.domain为主域名。, ,3、这样可以让浏览器认为这些页面属于同一域,从而可以进行数据交互。,相关问题与解答, Q1: JSONP有什么安全隐患?,A1: JSONP最大的安全隐患是它允许运行从其他域加载的任意脚本,这可能导致XSS攻击。, Q2: CORS是否支持IE8以下版本的浏览器?,A2: 不支持,CORS需要浏览器支持,IE8以下版本的浏览器并不支持CORS。, Q3: 代理服务器是否能够解决所有跨域问题?,A3: 是的,代理服务器可以解决所有跨域问题,因为它实际上就是让请求在同一个域内进行。, Q4: 是否可以同时使用JSONP和CORS?,A4: 可以,但通常不推荐这样做,CORS提供了更完善的安全机制,因此在大多数情况下,使用CORS就足够了。,

网站运维