如何在不使用CLI的情况下使用单一文件组件创建Vue.js应用程序。

An understanding of Vue’s single-file components (SFCs) and Node Package Manager (NPM) will be helpful for this article.

对Vue的单文件组件(SFC)和节点包管理器(NPM)的理解将对本文有所帮助。

A framework’s command line interface, or CLI, is the preferred method to scaffold a project. It provides a starting point of files, folders, and configuration. This scaffolding also provides a development and build process. A development process provides a way to see updates occurring as you edit your project. The build process creates the final version of files to be used in production.

框架的命令行界面(或CLI)是构建项目的首选方法。 它提供了文件,文件夹和配置的起点。 该脚手架还提供了开发和构建过程。 开发过程提供了一种查看编辑项目时发生的更新的方式。 构建过程将创建要在生产中使用的文件的最终版本。

Installing and running Vue.js (“Vue”) can be done with a script tag that points to the Vue content delivery network (CDN). No build or development process is necessary. But, if you use Vue single-file components (SFCs), you need to convert those files into something the browser can understand. The files need to be converted to Hyper-Text Markup Language (HTML), Cascading Style Sheets (CSS), and JavaScript (JS). In this case, a development and build process must be used.

可以使用指向Vue内容交付网络(CDN)的脚本标签完成Vue.js(“ Vue”)的安装和运行。 无需构建或开发过程。 但是,如果您使用Vue单文件组件(SFC),则需要将这些文件转换为浏览器可以理解的文件。 需要将文件转换为超文本标记语言(HTML),级联样式表(CSS)和JavaScript(JS)。 在这种情况下,必须使用开发和构建过程。

Instead of relying on the Vue CLI to scaffold our project and provide us with a development and build process, we will build a project from scratch. We will create our own development and build process using Webpack.

我们将不再依赖Vue CLI来搭建我们的项目并为我们提供开发和构建过程,而是从头开始构建一个项目。 我们将使用Webpack创建自己的开发和构建过程。

什么是Webpack? (What is Webpack?)

Webpack is a module bundler. It merges code from multiple files into one. Before Webpack, the user included a script tag for each JavaScript file. Although browsers are slowly supporting ES6 modules, Webpack continues to be the preferred way to build modular code.

Webpack是一个模块捆绑器。 它将来自多个文件的代码合并为一个。 在使用Webpack之前,用户为每个JavaScript文件添加了一个脚本标签。 尽管浏览器正在缓慢地支持ES6模块,但是Webpack仍然是构建模块化代码的首选方法。

Besides being a module bundler, Webpack can also transform code. For example, Webpack can take modern JavaScript (ECMAScript 6+) and convert it into ECMAScript 5. While Webpack bundles the code itself, it transforms the code with loaders and plugins. Think of loaders and plugins as add-ons for Webpack.

除了成为模块捆绑器之外,Webpack还可以转换代码。 例如,Webpack可以采用现代JavaScript(ECMAScript 6+)并将其转换为ECMAScript5。虽然Webpack 捆绑了代码本身,但它使用加载程序和插件来转换代码。 将加载程序和插件视为Webpack的附件。

Webpack和Vue (Webpack and Vue)

Single-file components allow us to build an entire component (structure, style, and function) in one file. And, most code editors provide syntax highlighting and linting for these SFCs.

单文件组件使我们可以在一个文件中构建整个组件(结构,样式和功能)。 而且,大多数代码编辑器都为这些SFC提供语法高亮和标记。

Notice the file ends with .vue. The browser doesn’t know what to do with that extension. Webpack, through the use of loaders and plugins, transforms this file into the HTML, CSS, and JS the browser can consume.

请注意,文件以.vue结尾。 浏览器不知道该扩展程序如何处理。 Webpack通过使用加载程序和插件将此文件转换为浏览器可以使用HTML,CSS和JS。

项目:使用单文件组件构建Hello World Vue应用程序。 (The Project: Build a Hello World Vue Application Using Single-File Components.)

步骤1:创建项目结构 (Step 1: Create the project structure)

The most basic Vue project will include an HTML, JavaScript, and a Vue file (the file ending in .vue). We will place these files in a folder called src. The source folder will help us separate the code we are writing from the code Webpack will eventually build.

最基本的Vue项目将包括HTML,JavaScript和Vue文件(该文件以.vue结尾)。 我们将这些文件放在名为 src文件夹中 源文件夹将帮助我们将正在编写的代码与Webpack最终生成的代码分开。

Since we will be using Webpack, we need a Webpack configuration file.

由于我们将使用Webpack,因此我们需要一个Webpack配置文件。

Additionally, we will use a compiler called Babel. Babel allows us to write ES6 code which it then compiles into ES5. Babel is one of those “add-on features” for Webpack. Babel also needs a configuration file.

此外,我们将使用称为Babel的编译器。 Babel允许我们编写ES6代码,然后将其编译为ES5。 Babel是Webpack的“附加功能”之一。 Babel还需要一个配置文件。

Finally, since we are using NPM, we will also have a node_modules folder and a package.json file. Those will be created automatically when we initialize our project as an NPM project and begin installing our dependencies.

最后,由于我们使用的是NPM,所以我们还将有一个node_modules文件夹package.json文件。 当我们将项目初始化为NPM项目并开始安装依赖项时,将自动创建它们。

To get started, create a folder called hello-world. From the command line, change to that directory and run npm init. Follow the on-screen prompts to create the project. Then, create the rest of the folders (except for node_modules) as described above. Your project structure should look like this:

首先,创建一个名为hello-world的文件夹。 在命令行中,转到该目录并运行npm init 。 按照屏幕上的提示创建项目。 然后,如上所述创建其余文件夹( node_modules除外) 。 您的项目结构应如下所示:

步骤2:安装依赖项 (Step 2: Install the dependencies)

Here is a quick rundown of the dependencies we are using:

这是我们正在使用的依赖项的简要概述:

vue: The JavaScript framework

vue :JavaScript框架

vue-loader and vue-template-compiler: Used to convert our Vue files into JavaScript.

vue-loader和vue-template-compiler :用于将我们的Vue文件转换为JavaScript。

webpack: The tool that will allow us to pass our code through some transformations and bundle it into one file.

webpack :该工具将允许我们通过一些转换传递代码并将其捆绑到一个文件中。

webpack-cli: Needed to run the Webpack commands.

webpack-cli:需要运行Webpack命令。

webpack-dev-server: Although not needed for our small project (since we won’t be making any HTTP requests), we will still “serve” our project from a development server.

webpack-dev-server :尽管我们的小型项目不需要(因为我们不会发出任何HTTP请求),但我们仍将通过开发服务器“服务”我们的项目。

babel-loader: Transform our ES6 code into ES5. (It needs help from the next two dependencies.)

babel-loader :将我们的ES6代码转换为ES5。 (它需要以下两个依赖项的帮助。)

@babel/core and @babel/preset-env: Babel by itself doesn’t do anything to your code. These two “add-ons” will allow us to transform our ES6 code into ES5 code.

@ babel / core和@ babel / preset-env :Babel本身对您的代码没有任何作用。 这两个“附加组件”将使我们能够将ES6代码转换为ES5代码。

css-loader: Takes the CSS we write in our .vue files or any CSS we might import into any of our JavaScript files and resolve the path to those files. In other words, figure out where the CSS is. This is another loader that by itself won’t do much. We need the next loader to actually do something with the CSS.

css-loader:使用我们在.vue编写CSS 文件或任何我们可能会导入任何JavaScript文件CSS并解析这些文件的路径。 换句话说,找出CSS的位置。 这是另一个本身不会做很多事情的装载机。 我们需要下一个加载器来对CSS进行实际处理。

vue-style-loader: Take the CSS we got from our css-loader and inject it into our HTML file. This will create and inject a style tag in the head of our HTML document.

vue-style-loader :从css-loader获取css-loader并将其注入HTML文件中。 这将在HTML文档的头部创建并注入样式标签。

html-webpack-plugin: Take our index.html and inject our bundled JavaScript file in the head. Then, copy this file into the dist folder.

html-webpack-plugin :以我们的index.html并将我们捆绑JavaScript文件注入头部。 然后,将此文件复制到dist 夹。

rimraf: Allows us, from the command line, to delete files. This will come in handy when we build our project multiple times. We will use this to delete any old builds.

rimraf :允许我们从命令行删除文件。 当我们多次构建项目时,这将派上用场。 我们将使用它来删除所有旧版本。

Let’s install these dependencies now. From the command line, run:

现在安装这些依赖项。 从命令行运行:

npm install vue vue-loader vue-template-compiler webpack webpack-cli webpack-dev-server babel-loader @babel/core @babel/preset-env css-loader vue-style-loader html-webpack-plugin rimraf -D

Note: The “-D” at the end marks each dependency as a development dependency in our package.json. We are bundling all dependencies in one file, so, for our small project, we have no production dependencies.

注意: 末尾的“ -D”将每个依赖项标记为我们的package.json中的开发依赖项。 我们将所有依赖项捆绑在一个文件中,因此,对于我们的小型项目,我们没有生产依赖项。

步骤3:创建文件(Webpack配置文件除外)。 (Step 3: Create the files (Except for our Webpack configuration file).)

Up to this point, nothing should look too foreign. I’ve kept each file very basic. I’ve only added minimal CSS and JS to see our workflow in action.

到目前为止,没有什么看起来太陌生。 我把每个文件都保留得很基本。 我仅添加了最少CSS和JS来查看我们的工作流程。

步骤4:指示Webpack做什么 (Step 4: Instructing Webpack what to do)

All the configuration Webpack needs access to is now present. We need to do two final things: Tell Webpack what to do and run Webpack.

Webpack需要访问的所有配置现在都已存在。 我们需要做两件事:告诉Webpack做什么并运行Webpack。

Below is the Webpack configuration file (webpack.config.js). Create this file in the projects root directory. Line-by-line we’ll discuss what is occurring.

以下是Webpack配置文件( webpack.config.js )。 在项目根目录中创建此文件。 我们将逐行讨论正在发生的事情。

Lines 1 and 2: We are importing the two plugins we use below. Notice, our loaders don’t normally need to be imported, just our plugins. And in our case, the vue-loader (which we use in line 9) also needs a plugin to work (however, Babel, for example, does not).

第1行和第2行:我们正在导入下面使用的两个插件。 请注意,通常不需要导入我们的加载器,只需导入我们的插件即可。 在我们的情况下 vue-loader (我们在第9行中使用)也需要一个插件才能工作(例如,Babel不需要)。

Line 4: We export our configuration as an object. This gives us access to it when we run the Webpack commands.

第4行:我们将配置导出为对象。 这使我们可以在运行Webpack命令时对其进行访问。

Line 5: This is our entry module. Webpack needs a place to start. It looks in our main.js file and then starts to comb through our code from that point.

第5行:这是我们的输入模块。 Webpack需要一个起点。 它会在我们的main.js文件中查找,然后从main.js开始梳理我们的代码。

Line 6 and 7: This is the module object. Here, we primarily pass in an array of rules. Each rule tells Webpack how to handle certain files. So, while Webpack uses the entry point of main.js to start combing through our code, it uses the rules to transform our code.

第6和7行:这是模块对象。 在这里,我们主要传递一系列规则。 每个规则都告诉Webpack如何处理某些文件。 所以,虽然使用的WebPack的切入点main.js开始通过我们的代码梳理,它使用规则来改变我们的代码。

Line 8 (rule): This rule instructs Webpack to use the babel-loader on any files which end with .js. Remember, Babel will transform ES6+ to ES5.

第8行(规则):此规则指示Webpack在任何以.js结尾的文件上使用babel-loader 记住,Babel会将ES6 +转换为ES5。

Line 9 (rule): This rule instructs Webpack to use vue-loader (and don’t forget the associated plugin on line 17) to transform our .vue files into JavaScript.

第9行(规则):此规则指示Webpack使用vue-loader (也请不要忘记第17行的关联插件)将.vue文件转换为JavaScript。

Line 10 (rule): Sometimes we want to pass a file through two loaders. Counterintuitively, Webpack will pass the file from right to left instead of left to right. Here we are using two loaders and saying to Webpack: “get my CSS from my Vue file or any JavaScript files(css-loader) and inject it into my HTML as a style tag (vue-style-loader).

第10行(规则):有时我们想通过两个加载器传递文件。 与直觉相反,Webpack将文件从右向左传递,而不是从左向右传递。 在这里,我们使用两个加载器,对Webpack说:“从我的Vue文件或任何JavaScript文件( css-loader )中获取我CSS,并将其作为样式标签( vue-style-loader )注入到HTML中。

Lines 11 and 12: Close out our rules array and module object.

第11和12行:关闭规则数组和模块对象。

Lines 13: Create a plugins array. Here we will add the two plugins we need.

第13行:创建一个插件数组。 在这里,我们将添加我们需要的两个插件。

Line: 14 -16 (plugin): The HtmlWebpackPlugin takes the location of our index.html file and adds our bundled JavaScript file to it via a script tag. This plugin will also copy the HTML file to our distribution folder when we build our project.

行:14 -16(插件): HtmlWebpackPlugin占据我们index.html文件的位置,并通过script标签向其中添加捆绑JavaScript文件。 在构建项目时,此插件还将HTML文件复制到我们的分发文件夹中。

Line 17 (plugin): The VueLoaderPlugin works with our vue-loader to parse our .vue files.

第17行(插件): VueLoaderPlugin与我们的vue-loader一起解析我们的.vue文件。

Line 18: Close out the plugins array.

第18行:关闭插件数组。

Line 19: Close out the Webpack object that we are exporting.

第19行:关闭我们要导出的Webpack对象。

步骤5:设置我们的package.json文件,以便我们可以运行Webpack (Step 5: Setting up our package.json file so we can run Webpack)

Our configuration is complete, now we want to see our application. Ideally, as we make changes to our application, the browser would update automatically. This is possible with webpack-dev-server.

我们的配置已完成,现在我们要查看我们的应用程序。 理想情况下,当我们对应用程序进行更改时,浏览器将自动更新。 使用webpack-dev-server可以做到这一点。

Delete the test script in our package.json file, and replace it with a script to serve our application:

删除我们的package.json文件中的test脚本,并将其替换为服务于我们的应用程序的脚本:

The name of this command is your choice. I chose to call mine serve since we will be serving our application.

您可以选择此命令的名称。 我选择致电我的serve因为我们将为我们的应用程序提供服务

From our terminal or command line, we can run npm run serve and that in turn will run webpack-dev-server --mode development .

在终端或命令行中,我们可以运行npm run serve ,然后将运行webpack-dev-server --mode development

The --mode development is what’s called a flag or option. We haven’t talked about this, but it essentially instructs Webpack that you are in development mode. We can also pass in --mode production which we will do when we build our project. These aren’t necessarily required for Webpack to work. Without these, you will get a warning message telling you to provide a mode when you run Webpack .

--mode development是所谓的标志或选项。 我们还没有讨论过,但是从本质上讲它指示Webpack您处于开发模式。 我们还可以传递--mode production ,这是我们在构建项目时将执行的--mode production Webpack不一定需要这些。 没有这些,您将收到一条警告消息,告诉您在运行Webpack时提供一种模式。

I say “necessarily required” because Webpack will minimize our code in production mode but not in development. So, don’t think those commands don’t do anything–they do.

我说“必需的”是因为Webpack将在生产模式下而不是在开发模式下最小化我们的代码。 因此,不要认为这些命令没有做任何事情,而是会做任何事情。

Let’s run npm run serve and see what happens.

让我们运行npm run serve看看会发生什么。

When we run npm run serve we get some output in our terminal. And, if everything goes well:

当我们运行npm run serve我们会在终端中得到一些输出。 而且,如果一切顺利:

And if we scroll up a bit:

如果我们向上滚动一点:

Point your browser to http://localhost:8080. You will see your Blue Hello World message in Roboto font.

将浏览器指向http://localhost:8080 。 您将看到Roboto字体的Blue Hello World消息。

Now, let’s update the project and change the message to Hello Universe. Notice that the webpage refreshes automatically. That’s great, right? Can you think of a downside?

现在,让我们更新项目并将消息更改为Hello Universe 。 请注意,网页会自动刷新。 很好,对吗? 您能想到不利之处吗?

Let’s change the application just a bit and include an input which we will bind a variable to (with v-model). We will output the variable in an <h2>tag below the input. I’ve also updated the styling section to style the message now. Our App.vue file should look like this:

让我们稍微更改一下应用程序,并包含一个输入,我们将把变量绑定到(使用v-model )。 我们将在输入下方的<h2>标记中输出变量。 我还更新了样式部分,以立即对消息进行样式设置。 我们的应用App.vue 文件应如下所示:

When we serve our application, we will have an input with a message of Hello World below it. The input is bound to the message variable, so as we type, we change the <h2> content. Go ahead, type into the input to change the <h2>content.

当我们为应用程序提供服务时,我们将在其下方输入一个带有Hello World消息的输入。 输入绑定到message变量,因此在键入时,我们更改了<h2>内容。 继续,输入内容以更改<h2>内容。

Now go back to your editor, and below the <h2>tag, add the following:

现在回到编辑器,在<h2>标记下面,添加以下内容:

<h3>Some Other Message</h3>

<h3>Some Other Message</h3>

Save your App.vue and watch what happens.

保存您的App.vue并观察会发生什么。

The h2 we just updated by typing in our input reverted back to Hello World. This is because the browser actually refreshes, and the script tag and page are loaded again. In other words, we were not able to maintain the state of our application. This may not seem like a big deal, but as you are testing your application and adding data to it, it will be frustrating if your app “resets” every time. Fortunately, Webpack offers us a solution called Hot Module Replacement.

我们刚刚通过输入输入更新的h2还原为Hello World 。 这是因为浏览器实际上会刷新,并且脚本标签和页面会再次加载。 换句话说,我们无法维护应用程序的状态。 这似乎没什么大不了,但是当您测试应用程序并向其中添加数据时,如果您的应用程序每次都“重置”,那将很令人沮丧。 幸运的是,Webpack为我们提供了一种称为“热模块更换”的解决方案。

The hot module replacement is a plugin provided by Webpack itself. Up until this point, we have not used the Webpack object itself in our configuration file. However, we will now import Webpack so we can access the plugin.

热模块替换是Webpack本身提供的插件。 到目前为止,我们还没有在配置文件中使用Webpack对象本身。 但是,我们现在将导入Webpack,以便我们可以访问插件。

In addition to the plugin, we will pass one additional option to Webpack, the devServer option. In that option, we will set hot to true. Also, we will make an (optional) update to our build workflow: We will open the browser window automatically when we run npm run serve. We do this by setting open to true which is also inside the devServer option.

除了插件之外,我们还将传递一个附加选项给Webpack devServer选项。 在该选项中,我们将hot设置为true 。 另外,我们将对构建工作流程进行(可选)更新:运行npm run serve时,我们将自动打开浏览器窗口。 我们通过在devServer选项devServer open设置为truetrue

Notice that we’ve imported Webpack so we could access the hotModuleReplacementPlugin. We’ve added that to the plugins array, and then told Webpack to use it with hot: true. We open the browser window automatically when we serve the application with open: true.

注意,我们已经导入了Webpack,因此我们可以访问hotModuleReplacementPlugin 。 我们已经将其添加到plugins数组中,然后告诉Webpack将它与hot: true一起使用。 当我们使用open: true为应用程序提供服务时,我们会自动打开浏览器窗口。

Run npm run serve:

运行npm run serve

The browser window should open, and if you open your dev tools, you should notice a slight change in the output. It now tells us hot module replacement is enabled. Let’s type in our input to change the <h2> content. Then, change theh3 tag to read: One More Message.

应该会打开浏览器窗口,并且如果您打开开发工具,则应该注意到输出中的微小变化。 现在,它告诉我们启用了热模块更换。 让我们输入内容以更改<h2>内容。 然后,将h3标签更改为: One More Message

Save your file and notice what happens.

保存文件并注意会发生什么。

The browser doesn't refresh, but our <h3>change is reflected! The message we typed in the input remains, but the h3 updates. This allows our application to keep it’s state while we edit it.

浏览器不会刷新,但是会反映出我们的<h3>更改! 我们输入的消息仍然存在,但是h3更新。 这允许我们的应用程序在编辑时保持其状态。

步骤7:建立专案 (Step 7: Building our project)

So far, we’ve served our application. But, what if we want to build our application so we can distribute it?

到目前为止,我们已经为我们的应用程序提供了服务。 但是,如果我们要构建应用程序以便可以分发它该怎么办?

If you noticed, when we serve our application, no files are created. Webpack creates a version of these files that only exist in temporary memory. If we want to distribute our Hello World app to our client, we need to build the project.

如果您注意到,在我们为我们的应用程序提供服务时,不会创建任何文件。 Webpack创建这些文件的版本,该版本仅存在于临时内存中。 如果我们想将Hello World应用程序分发给客户,则需要构建项目。

This is very simple. Just like before, we will create a script in our package.json file to tell Webpack to build our project. We will use webpack as the command instead of webpack-dev-server. We will pass in the --mode production flag as well.

这很简单。 就像以前一样,我们将在package.json文件中创建一个脚本,以告诉Webpack构建我们的项目。 我们将使用webpack代替webpack-dev-server作为命令。 我们也将传递--mode production标记。

We will also use the rimraf package first to delete any previous builds we may have. We do this simply by rimraf dist.

我们还将首先使用rimraf软件包删除我们可能拥有的任何以前的版本。 我们只是通过rimraf dist做到这一点。

dist is the folder Webpack will automatically create when it builds our project. “Dist” is short for distribution–i.e. we are “distributing” our applications code.

dist 是Webpack在构建项目时将自动创建的文件夹。 “ Dist”是分发的缩写,即我们正在“分发”我们的应用程序代码。

The rimraf dist command is telling the rimraf package to delete the dist directory. Make sure you don’t rimraf src by accident!

rimraf dist命令告诉 rimraf软件包删除dist目录。 确保您不是 rimraf src

Webpack also offers a plugin that will accomplish this cleaning process called clean-webpack-plugin. I chose dist show an alternative way.

Webpack还提供了一个名为clean-webpack-plugin的插件,可以完成此清理过程。 我选择了dist show另一种方式。

Our package.json file should look like this:

我们的package.json文件应如下所示:

There are three things to notice:

有三件事要注意:

  1. I’ve created a separate clean script so we can run it independently of our build script.

    我创建了一个单独的clean脚本,因此我们可以独立于构建脚本运行它。

  2. npm run build will call the independent clean script we’ve created.

    npm run build将调用我们创建的独立clean脚本。

  3. I have && between npm run clean and webpack. This instruction says: “run npm run clean first, then run webpack”.

    我在npm run cleanwebpack之间有&& 。 该说明说:“先运行npm run clean然后再运行webpack ”。

Let’s build the project.

让我们构建项目。

npm run build

npm run build

Webpack creates a dist directory, and our code is inside. Since our code makes no HTTP requests, we can simply open our index.html file in our browser and it will work as expected.

Webpack创建一个dist目录,我们的代码在其中。 由于我们的代码没有HTTP请求,因此我们只需在浏览器中打开index.html文件即可正常工作。

If we had code that was making HTTP requests, we would run into some cross-origin errors as we made those requests. We would need to run that project from a server for it to work.

如果我们有发出HTTP请求的代码,那么在发出这些请求时就会遇到一些跨域错误。 我们需要从服务器运行该项目才能使其工作。

Let’s examine the index.html that Webpack created in the browser and the code editor.

让我们检查一下Webpack在浏览器和代码编辑器中创建的index.html

If we open it in our editor or take a look at the source code in our dev tools you will see Webpack injected the script tag. In our editor though, you won’t see the styles because the style tag is injected dynamically at runtime with JavaScript!

如果我们在编辑器中打开它,或者在开发工具中查看源代码,您将看到Webpack注入了script标记。 但是,在我们的编辑器中,您将看不到样式,因为样式标记是在运行时使用JavaScript动态注入的!

Also, notice our development console information is no longer present. This is because we passed the --production flag to Webpack.

另外,请注意我们的开发控制台信息不再存在。 这是因为我们将--production标志传递给了Webpack。

结论 (Conclusion)

Understanding the build process behind the frameworks you use will help you to better understand the framework itself. Take some time to try to build an Angular, React or another Vue Project without the use of the respective CLIs. Or, just build a basic three-file site (index.html, styles.css, and app.js), but use Webpack to serve and build a production version.

了解所使用的框架背后的构建过程将有助于您更好地了解框架本身。 花一些时间尝试在不使用各自的CLI的情况下构建Angular,React或另一个Vue项目。 或者,仅构建一个基本的三文件站点(index.html,styles.css和app.js),但是使用Webpack来提供和构建生产版本。

Thanks for reading!

谢谢阅读!

woz

沃兹

翻译自: https://www.freecodecamp.org/news/how-to-create-a-vue-js-app-using-single-file-components-without-the-cli-7e73e5b8244f/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值