Node.js入门
创始人
2024-04-03 02:59:54
0

Node.js入门

    • 1.模块化简介
      • 1.1ECMAScript标准的缺陷
      • 模块化
      • CommonJS规范
      • 什么是模块?
        • 模块的引用
        • 模块的定义
        • 模块的导出
        • 模块标识
        • 练习
    • 2.模块化详解
        • 1.证明模块中得变量是局部变量不是全局变量
        • 2.证明模块中得代码是在函数中运行
        • 3.模块参数解释
        • 4.exports和module.exports解释
    • 3.包 Package
        • 包结构
        • 包描述文件
        • NPM(Node Package Manager)
        • NPM命令
        • Node搜索包得流程
    • 4.Buffer
    • 5.文件系统 fs
        • 同步和异步调用
        • 同步文件写入
        • 异步文件写入
        • 打开状态
        • 简单文件写入
        • 流式写入
        • 文件读取
          • 简单文件读取
          • 流式文件读取----方式一
          • 流式文件读取----方式二
        • 其他函数

1.模块化简介

1.1ECMAScript标准的缺陷

  • 没有模块系统(从ES6开始已经有模块化了)
    • 模块化就是将一个完整的程序文件分成一个个小程序
    • 模块化能够降低程序之间的耦合度,方便代码复用,扩展
  • 标准库较少
    • 官方出的标准库少,很多都是第三方开源社区开发人员开发的,
  • 没有标准接口
  • 缺乏管理系统
    • 下jquery要去jquery官网,下其他的都要去官网,没有统一的管理系统

模块化

  • 如果程序设计的规模达到了一定程度,则必须对其进行模块化
  • 模块化可以有多种形式,但至少应该提供额能够将代码分割为多个源文件的机制
  • CommonJS的模块功能可以帮我们解决该问题

CommonJS规范

  • CommonJS规范的提出,主要是为了弥补当前JS没有标准的缺陷
  • CommonJS规范为JS指定了一个美好的愿景,希望JS能够在任何地方运行
  • CommonJS对模块的定义十分简单
    • 模块引用
    • 模块定义
    • 模块标识

什么是模块?

- 模块化- ES5中没有原生支持模块化,我们只能通过script标签引入js文件来实现模块化- 在node中为了对模块管理,引入了CommonJS规范- 模块的引用- 使用 require()函数来引入一个外部的模块,require()可以传递一个文件的路径作为参数,node将会自动根据该路径来引入外部模块,这里的路径,若是相对路径则必须要以.或者..开头- 例子:var 变量 = require("模块的标识");- 模块的定义- 在node中一个js文件就是一个模块,定义一个模块就是创建一个js文件- 默认情况下在js文件中编写的内容,都是运行在一个独立的函数中,不是全局作用域因此一个模块中的变量和函数外部的模块无法访问- 导出变量和函数- 使用 exports - 例子:exports.属性 = 属性值;exports.方法 = 函数;- 使用module.exports- 例子:module.exports.属性 = 属性值;module.exports.方法 = 函数;module.exports = {};- 模块的标识- 模块的标识就是模块的名字或路径我们node通过模块的标识来寻找模块的对于核心模块(npm中下载的模块),直接使用模块的名字对其进行引入var fs = require("fs");var express = require("express");对于自定义的文件模块,需要通过文件的路径来对模块进行引入路径可以是绝对路径,如果是相对路径必须以./或 ../开头var router = require("./router");

模块的引用

模块A:moduleA.js

console.log("module A")

模块B:moduleB.js

在模块A中引入模块B

// 使用 require()函数来引入一个外部的模块,require()可以传递一个文件的路径作为参数,
// node将会自动根据该路径来引入外部模块,这里的路径,若是相对路径则必须要以.或者..开头
require("./moduleA.js")

模块的定义

在node中一个js文件就是一个模块,定义一个模块就是创建一个js文件

模块A:moduleA.js

// 默认情况下在js文件中编写的内容,都是运行在一个独立的函数中,不是全局作用域
// 因此一个模块中的变量和函数外部的模块无法访问
console.log("module A")
var x = 1
var y = 2// Node中模块的代码相当于如下:(function(){console.log("module A")var x = 1var y = 2
})()

模块B:moduleB.js

// 引入moduleA.js模块
var md = require("./moduleA.js")
console.log(md.x)   // 输出undefined

模块的导出

模块A:moduleA.js

// 我们可以通过exports来向外部暴露变量和方法,只需要将需要暴露给外部的变量或方法设置为exports的属性即可
console.log("module A")
exports.x = "module A 的x"
exports.y = "module A 的y"
exports.fn = function(){}// Node中模块的代码相当于如下:(function(){console.log("module A")exports.x = "module A 的x"exports.y = "module A 的y"
})()

模块B:moduleB.js

// 引入moduleA.js模块
var md = require("./moduleA.js")
console.log(md)   
/*输出:module A{ x: 'module A 的x', y: 'module A 的y', fn: [Function (anonymous)] }
*/ 

模块标识

模块的标识就是模块的名字或路径,使用require()引入模块时,使用得就是模块标识,我们可以通过模块标识来找到指定得模块

模块可分为两类

  • 1.核心模块:
    • 由node引擎提供得模块,直接使用模块的名字对其进行引入
    • var fs = require(“fs”); var express = require(“express”);
  • 2.文件模块
    • 由用户自己创建得模块
    • 文件模块得标识就是文件得路径,可以是绝对路径或者是相对路径
    • 对于自定义的文件模块,需要通过文件的路径来对模块进行引入路径可以是绝对路径,如果是相对路径必须以./或 …/开头
    • var router = require(“./router”);

练习

定义一个模块math

  • 在该模块中提供两个方法
    • add(x, y) 求两个数得和
    • mul(x, y) 求两个数得积
exports.add = function(a,b){return a+b
}
exports.mul = function(a,b){return a*b
}
var math = require("./math")
console.log(math.add(1,2))
console.log(math.mul(2,3))

2.模块化详解

默认情况下在js文件中编写的内容,都是运行在一个独立的函数中,不是全局作用域
因此一个模块中的变量和函数外部的模块无法访问

1.证明模块中得变量是局部变量不是全局变量

/*** 在node中有一个全局对象global,他得作用和网页中得window类似,* 在全局中创建得变量都会作为global得属性保存* 在全局中创建得函数都会作为global得方法保存*/
var a = 10
console.log(global.a)  // undefined
// 在模块中如果不用var声明得变量,那么变量就是全局变量
a = 10
console.log(global.a)  // 10

2.证明模块中得代码是在函数中运行

arguments是伪数组,是封装在函数中获取参数的,全局中没有arguments

a = 10
// console.log(global.a) 
console.log(arguments.length)   // 输出5

arguments.callee:保存的是当前执行的函数对象

a = 10
console.log(arguments.callee)  // [Function (anonymous)]
a = 10
console.log(arguments.callee+"") // 输出内容如下function (exports, require, module, __filename, __dirname) {
a = 10
console.log(arguments.callee+"")
}

当node在执行模块中的代码时,会在自己编写代码包裹进函数中,作为函数体,因此模块中的变量都是局部变量

3.模块参数解释

exports,

  • 该对象用来将变量或者函数暴露到外部

require,:

  • 函数,用来引入外部的模块

module:

  • module代表当前模块本身
  • export就是module的属性
  • 既可以使用exports导出,也可以使用module.exports

__filename:

  • 当前模块的完整路径

__dirname:

  • 当前模块所在的文件夹目录

4.exports和module.exports解释

exports和module.exports

  • exports

    • 通过exports只能使用点的方式来向外暴露内部变量

    • exports.XXX = yyy

  • module.exports

    • module.exports既可以通过点的方式,也可以之间赋值
    • module.exports.XXX = YYY
    • module.exports = { }
// module.exports.name = "swk"
// module.exports.age = 18
// module.exports.sayNAme = function(){
//     console.log("我是孙悟空")
// }// exports = {} 这里如果直接使用exports就不能暴露
module.exports = {name:'swk',age:18,sayNAme(){console.log("123")}
}
var md = require("./helloModule")
md.sayNAme()

3.包 Package

CommonJS的包规范允许我们将一组相关的模块组合到一起,形成一组完整的工具

CommonJS的包规范由包结构和包描述文件两部分组成

包结构

  • 用于组织包中的各种文件

包描述文件

  • 描述包的相关信息,以供外部读取分析

包结构

包实际上就是一个压缩文件,解压以后还原伪目录。符合规范的目录应该包含如下文件:

  • package.json 描述文件 (必须部分)
  • bin 可执行二进制文件 (非必须部分)
  • lib js代码 (非必须部分)
  • doc 文档 (非必须部分)
  • test 单元测试 (非必须部分)

包描述文件

包描述文件用于表达非代码相关的信息,它是一个JSON格式的文件-package.json位于包的根目录下,是包的重要组成部分。

package.json中的字段
name ,description,version、 keywords、maintainers、contributors、bugs、
licenses、repositories、dependencies、homepage、os、cpu、engine、builtin、directories、implements、scripts、author、bin、main、devDependencies。

NPM(Node Package Manager)

  • CommonJS包规范是理论,NPM是其中一种实践。
  • 对于Node而言,NPM帮助其完成了第三方模块的发布、安装和依赖等。借助NPM,Node与第三方模块之间形成了很好的一个生态系统。

NPM命令

	- npm的命令- npm -v 查看npm的版本- npm version 查看所有模块的版本- npm search 包名 搜索包- npm init 创建package.json- npm install / i 包名 安装包- npm remove / r 包名 删除包- npm remove / r 包名 --save 删除包并删除依赖- npm install 包名 --save 安装包并添加到依赖中 *****- npm install 下载当前项目所依赖的包- npm install 包名 -g 全局安装包(全局安装的包一般都是一些工具)

Node搜索包得流程

node在使用模块名字来引入模块时,它会首先在当前目录的node_modules中寻找是否含有该模块
如果有则直接使用,如果没有则去上一级目录的node_modules中寻找
如果有则直接使用,如果没有则再去上一级目录寻找,直到找到为止直到找到磁盘的根目录,如果依然没有,则报错

4.Buffer

从结构上看Buffer非常像一个数组,它的元素为16进制的两位数。

实际上一个元素就表示内存中的一个字节。汉字占两个字节。

实际上Buffer中的内存不是通过JavaScript分配的,而是在底层通过C++申请的。

也就是我们可以直接通过Buffer来创建内存中的空间。

/*Buffer(缓冲区)-Buffer的结构和数组很像,操作的方法也和数组类似-数组中不能存储二进制的文件,而buffer就是专门用来存储二进制数据-使用buffer不需要引入模块,直接使用即可-在buffer中存储的都是二进制数据,但是在显示时都是以16进制的形式显示- buffer中每个元素得范围是从00 - ff  - Buffer的大小一旦确定,则不能修改,Buffer实际上是对底层内存的直接操作
*/
var str = "hello atguigu"
// 将一个字符串保存到buffer中
var buf = Buffer.from(str)
console.log(buf.length)  // 13  占用内存大小
console.log(str.length)  // 13  字符串得长度
console.log(buf)  // // 创建一个指定大小的buffer
// buffer构造函数都是不推荐使用的
var buf2 = new Buffer(1024)  // 创建一个1024字节的buffer// 创建一个10字节的buffer
var buff3 = Buffer.alloc(10)
buff3[0] = 88
buff3[3] = 55
buff3[5] = 0xaa
console.log(buff3)  // // Buffer.allocUnsafe(size)  创建一个指定大小的buffer,但是buffer中可能有敏感数据
var buf4 = Buffer.allocUnsafe(10)
console.log(buf4)/**Buffer.from(str)   将一个字符串转为bufferBuffer.alloc(size)  创建一个指定大小的BufferBuffer.allocUnsafe(size)  创建一个指定大小的buffer,不清除原来内存中的数据,可能读到敏感数据buf.toString()   将缓冲区中的数据转换为字符串*/var b5 = Buffer.from("我是一段文本数据")
console.log(b5, b5.toString())

5.文件系统 fs

  • 在Node中,与文件系统的交互是非常重要的,服务器的本质就将本地的文件发送给远程的客户端

  • 文件系统简单来说就是通过Node来操作系统中的文件

  • Node通过fs模块来和文件系统进行交互该模块提供了一些标准文件访问API来打开、读取、写入文件,以及与其交互。

  • 要使用fs模块,首先需要对其进行加载 const fs = require(“fs”);

同步和异步调用

  • fs模块中所有的操作都有两种形式可供选择同步和异步。
  • 同步文件系统会阻塞程序的执行,也就是除非操作完毕,否则不会向下执行代码。
  • 异步文件系统不会阻塞程序的执行,而是在操作完成时,通过回调函数将结果返回。

同步文件写入

/*** 文件系统(File system)-文件系统简单来说就是通过Node来操作系统中的文件-使用文件系统,需要先引入fs模块,fs是核心模块,直接引入不需要下载同步文件的写入-手动操作的步骤1.打开文件fs.opensync(path, flags [, mode])- path要打开文件的路径- flags 打开文件要做操作的类型r只读的w可写的- 返回值该方法会返回一个文件的描述符作为结果,我们可以通过该描述符来对文件进行各种操作2.向文件中写入内容fs.writeSync(fd, string[, position[, encoding]])- fd 文件描述符,需要传递要写入文件的描述符- string 要写入的内容- position 写入的起始位置- encoding 写入的编码,默认为utf-83.保存并关闭文件fs.closeSync(fd)- fd 要关闭文件的描述符*/var fs = require("fs")
// 打开文件
var fd = fs.openSync("hello.txt", "w")
// 向文件中写入内容
fs.writeSync(fd, "今天天气真不错")// 关闭文件
fs.closeSync(fd)

异步文件写入

/*** 异步文件写入* 1.异步打开文件*      fs.open(path,flags[, mode], callback)*      - 用来打开一个文件*      - 异步调用的方法,结果都是通过回调函数的参数返回的*      - 回调函数的两个参数*          err 错误对象,如果没有错误则为null*          fd 文件描述符* 2.异步写入*      fs.write(fd, string[, position[, encoding]], callback)*          - 用来异步写入文件* * 3.异步关闭*  fs.close(fd, callback)*/
var fs = require("fs")// 打开文件
fs.open("hello2.txt", "w", function(err, fd){// 判断是否出错if(!err){// 如果没有出错,则对文件进行写入操作fs.write(fd, "异步写入的内容",function(err){if(!err){console.log("异步写入成功")}// 关闭文件fs.close(fd, function(err){if(!err){console.log("文件已关闭")}})})}else{console.log(err)}
})

打开状态

r 读取文件,文件不存在则出现异常
r+ 读写文件,文件不存在则出现异常
rs 在同步模式下打开文件用于读取
rs+ 在同步模式下打开文件用于读写
w 打开文件用于写操作,如果不存在则创建,如果存在则截断
wx 打开文件用于写操作如果存在则打开失败
w+ 打开文件用于读写,如果不存在则创建,如果存在则载断
wx+ 打开文件用于读写,如果存在则打开失败
a 打开文件用于追加,如果不存在则创建
ax 打开文件用于追加,如果路径存在则失败
a+ 打开文件进行读取和追加,如果不存在则创建该文件
ax+ 打开文件进行读取和追加,如果路径存在则失败

简单文件写入

/*** 简单文件写入* fs.writeFile(file, data[, options], callback)* fs.writeFileSync(file, data[, options])*  - file  要操作的文件的路径*  - data  要写入的数据*  - options   选项,可以对写入进行一些设置*  - callback  当写入完成后要执行的函数*/// 引入fs模块
var fs = require("fs")// fs.writeFile("h3.txt", "通过writeFile写入的内容", {flag:'w'},function(err){
//     if(!err){
//         console.log("写入成功")
//     }
// })fs.writeFileSync("h4.txt", "通过writeFileSync写入", {flag:'a+'})

流式写入

/*** 同步,异步,简单文件的写入都不适合大文件的写入,性能较差,容易导致内存溢出*/var fs = require("fs")/*** 流式文件写入* * 创建一个可写流*  fs.createWriteStream(path[, options])*      - 可以用来创建一个可写流*      - path:文件路径*      - options 配置的参数*//*** 可以通过监听流的open和close事件来监听流的打开和关闭* on(事件字符串,回调函数)*  - 可以为对象绑定一个事件* * once(事件字符串,回调函数)*  - 可以为对象绑定一个一次性事件,该事件将会触发一次以后自动失效*/// 创建一个可写流
var ws = fs.createWriteStream("h5.txt")ws.once("open", ()=>{console.log("流打开了")
})
ws.once("close", ()=>{console.log("流关闭了")
})
// 通过ws向文件中输出内容
ws.write("通过可写流写入文件的内容")
ws.write("通过可写流写入文件的内容")
ws.write("通过可写流写入文件的内容")// 关闭流  不能用ws.close(),这相当于流数据还没写完就断开了
ws.end()

文件读取

/*** 1.同步文件读取* 2.异步文件读取* 3.简单文件读取*  fs.readFile(path[, options], callback)*      - path   要读取的文件路径*      - options  读取的选项*      - callback 回调函数,通过回调函数将读取的内容返回(err, data)*           err 错误对象*          data 读取到的数据* 4.流式文件的读取* */
简单文件读取
var fs = require("fs")// 简单文件读取
// fs.readFile("h3.txt",(err, data)=>{
//     if(!err)
//         console.log(data.toString())
// })
流式文件读取----方式一
// 流式文件读取
var fs = require("fs")
// 创建一个可读流
var rs = fs.createReadStream("q_2.jpg")
// 创建一个可写流
var ws = fs.createWriteStream("q_2.jpg")
// 监听流的开启和关闭
rs.once("open", ()=>{console.log("可读流打开了")
})
rs.once("close", ()=>{console.log("可读流关闭了")// 关闭可写流ws.end()
})ws.once("open", ()=>{console.log("可写流打开了")
})
ws.once("close", ()=>{console.log("可写流关闭了")
})
// 如果要读取一个可读流中的数据,必须要为可读流绑定一个data事件,
// data事件绑定完毕,他会自动开始读取数据,读取之后会自动关闭
rs.on("data", (data)=>{console.log(data)ws.write(data)
})
流式文件读取----方式二
var fs = require("fs")
// 创建一个可读流
var rs = fs.createReadStream("q_2.jpg")
// 创建一个可写流
var ws = fs.createWriteStream("q_21.jpg")
// 监听流的开启和关闭
rs.once("open", ()=>{console.log("可读流打开了")
})
rs.once("close", ()=>{console.log("可读流关闭了")
})ws.once("open", ()=>{console.log("可写流打开了")
})
ws.once("close", ()=>{console.log("可写流关闭了")
})
// pipe()可以将可读流中的内容,直接输出到可写流中
rs.pipe(ws)

其他函数

  • 验证路径是否存在

    • fs.exists(path , callback)
    • fs.existsSync(path)
  • 获取文件信息

    • fs.stat(path, callback)-

    • fs.statSync(path)

  • 删除文件

    • fs.unlink(path, callback)
    • fs.unlinkSync(path)
  • 列出文件

    • fs.readdir(path[, options], callback)

    • fs.readdirSync(path[, options])

  • 截断文件

    • fs.truncate(path, len,callback)
    • fs.truncateSync(path, len)
  • 建立目录

    • fs.mkdir(path[, mode], callback)
    • fs.mkdirSync(path[, mode])
  • 删除目录

    • fs.rmdir(path, callback)
    • fs.rmdirSync(path)
  • 重命名文件和目录

    • fs.rename(oldPath,newPath, callback)
    • fs.renameSync(oldPath, newPath)
  • 监视文件更改写入

    • fs.watchFile(filename[, options],listener)
var fs = require("fs");
/*** fs.existsSync (path)*  检查一个文件是否存在*/
var isExists = fs.existsSync("a.mp3")
console.log(isExists)/*fs.stat(path, callback )fs.statSync(path)-获取文件的状态-它会给我们返回一个对象,这个对象中保存了当前对象状态的相关信息
*/
fs.stat("a.mp3", function (err, stat) {/**stats.sizestats.isFile()stats.isDirectory()stats.isBlockDevice()stats.isCharacterDevice()stats.isSymbolicLink()(仅对fs.lstat()有效)stats.isFIFO()stats.isSocket()*/console.log(stat);
});/*** fs.unlink (path, callback )* fs.unlinkSync(path)*  -删除文件*/fs.unlinkSync("hello.txt");/*fs.readdir(path[ , options] , callback )fs.readdirSync(path[ , options] )-读取一个目录的目录结构- files是一个字符串数组,每一个元素就是一个文件夹或文件的名字
*/fs.readdir(".", function (err, files) {if (!err) {console.log(files);}
});/*** fs.truncate (path, len, callback )* fs.truncatesync(path, len)-截断文件,将文件修改为指定的大小*/
fs.truncateSync("hello2.txt", 10);/*fs.mkdir(path[, mode] , callback )fs.mkdirSync(path [ , mode] )- 创建一个目录fs.rmdir(path, callback )fs.rmdirSync(path)- 删除一个目录
*/
// 创建一个文件夹
fs.mkdirSync("hello");
// 删除一个文件夹
fs.rmdirSync("hello");/*fs.rename (oldPath, newPath, callback )fs.renameSync(oldPath, newPath)-对文件进行重命名- 参数:oldPath 旧的路径newPath 新的路径callback回调函数
*/fs.rename("a.mp3", "笔记.mp3", function (err) {if (!err) {console.log("修改成功")}
})/*fs.watchFile(filename[ , options] , listener)-监视文件的修改-参数:filename要监视的文件的名字options配置选项listener回调函数,当文件发生变化时,回调函数会执行在回调函数中有两个参数:curr 当前文件的状态prev 修改前文件的状态这两个对象都是stat对象
*/
fs.watchFile("hello2.txt",{interval:1000}, function (curr, prev) {console.log("文件发生变化了~~~");console.log("修改前文件大小:",prev.size)console.log("修改后文件大小:",curr.size)
});

相关内容

热门资讯

小仓鼠在笼子里一动不动的是怎么... 小仓鼠在笼子里一动不动的是怎么回事?小仓鼠应该是生病了,建议尽快处理,找兽医看看,他们最专业。目前应...
扬州何园的寻访感受 扬州何园的寻访感受 你好,请参考: 初见何园,似乎有种似曾相识的感觉,或许意识到这种想...
童年傻事作文---速来 童年傻事作文---速来童年傻事 童年是多么美好,童年的生活令人向往,童年的天空总是那么蓝,而童...
家庭幽默大赛老韩头一家幽默服装... 家庭幽默大赛老韩头一家幽默服装秀家庭幽默大赛老韩头一家幽默服装秀这都被他看出来了  今天晒内裤了,室...
乐器名称 乐器名称我在小提琴协奏曲《梁祝》的视频里这种乐器不知叫什么名字,请懂音乐和乐器的朋友给予解答,谢谢。...
电视剧《老马家的幸福往事》中的... 电视剧《老马家的幸福往事》中的马鸣和徐丽娜在马鸣的大学里的图书馆里偷书时用留声机听的歌是什么名字的请...
流鬼的介绍 流鬼的介绍 流鬼,是古代民族,分布在今俄罗斯勘察加半岛,有数万人。
请问为爱所困火吗 请问为爱所困火吗一般般。爱情偶像剧。此剧上一年开播,还上了微博热搜榜我认为很火,为爱所困第二部还有不...
什么是手诊 什么是手诊手诊的概念就是指通过人体手的纹路形态、变化、规律等方式,对人体器官的演变作出推理的一种防治...
双子星公主法和希的有几集,第一... 双子星公主法和希的有几集,第一部第二部都要,如果知道第三部也透露一点,请求不要编,法和希最后怎样了拜...
王熙凤简介 王熙凤简介《红楼梦》中人物,贾琏之妻,王夫人的内侄女。长着一双丹凤三角眼,两弯柳叶吊梢眉,身量苗条,...
大学生应从哪些方面进行自我探索 大学生应从哪些方面进行自我探索兴趣、能力、价值观、性格,这四个是最主要的方面,其中价值观是核心
谁有好看的卡通人物的电脑背景! 谁有好看的卡通人物的电脑背景!卡通人物的背景要清色! 看得清 要男生的 我有Clannad主题...
幼儿园小班孩子座位固定好还是经... 幼儿园小班孩子座位固定好还是经常换好?我家孩子座位老换,我觉得不好,大家觉得呢?... 我家孩子座...
我的爸爸的作文 我的爸爸的作文我的父亲 人们常说父爱如山,可在我看来,我的父亲对我的爱,并非完全如山那样严峻,有时却...
潘朵拉之心第二季动漫什么时候出 潘朵拉之心第二季动漫什么时候出动画只出了第一季 没有要出第二季的消息 可能性估计很小目前漫画还在连载...
时不我待是什么意思 时不我待是什么意思时不我待的意思是时间不等待人,要抓紧时间,不要虚度光阴。出处:日月逝矣,岁不我与。...
葫芦小金刚里大娃怎么被抓的 葫芦小金刚里大娃怎么被抓的掉泥潭被捉的
有一部小说叫穿越千年来爱你还是... 有一部小说叫穿越千年来爱你还是什么的有一部小说叫穿越千年来爱你还是什么的内容讲的是一个女的在路上走着...
火影忍者力 米娜是红眼吗 火影忍者力 米娜是红眼吗红眼?首先这几集是原创,非岸本创作。在岸本的剧情结构里面只有木叶白眼、写轮眼...