关闭

webpack+vue+vue-router创建项目具体(备注:供自己学习时以备随时可以查看用而整理,首发地址:http://blog.csdn.net/fungleo/article/detail)

标签: webpackvuevue-router
388人阅读 评论(0) 收藏 举报
分类:

1 安装好nodejs 之后=>输入命令node -v,有版本号出来说明npm也已经安装好

2 vue-cil是vue的脚手架工具  npm install -g vue-cli , 把当前目录定位到你准备存放项目的地方,

新建一个自己的vue项目 vue init webpack vuetest输入这个命令之后,会出现一些提示,是什么不用管,一直按回车即可。

3 cd vuetest 然后安装npm :npm install (注:ctrl+c快捷键可以停止当前进程,cls可以把cmd清屏)

4 npm run dev 可以让当前构架好的项目跑起来 

目录/文件 说明
build 这个是我们最终发布的时候会把代码发布在这里,在开发阶段,我们基本不用管。
config 配置目录,默认配置没有问题,所以我们也不用管
node_modules 这个目录是存放我们项目开发依赖的一些模块,这里面有很多很多内容,不过高兴的是,我们也不用管
src 我们的开发目录,基本上绝大多数工作都是在这里开展的
static 资源目录,我们可以把一些图片啊,字体啊,放在这里。
test 初始测试目录,没用,删除即可
.xxxx文件 这些是一些配置文件,包括语法配置,git配置等。基本不用管,放着就是了
index.html 首页入口文件,基本不用管,如果是开发移动端项目,可以在head区域加上你合适的meta
package.json 项目配置文件。前期基本不用管,但是你可以找一下相关的资料,学习一下里面的各项配置。至少,要知道分别是干嘛的。初期就不管了。
README.md 不用管

如上,基本上就是这么个情况。重要的,还是src文件夹。

5 App.vue是项目入口文件。当然,我们需要改造,改造成我们可以使用的样子的。

 main.js这是项目的核心文件。全局的配置都在这个文件里面配置。

6 参照博主的观点和构架,可以把src里面的弄成这样(用 http://cnodejs.org/api 这里公开的api来做项目)

文件\目录 说明
component 组件文件夹我们写的一些公用的内容可以放在这里的。
config 核心配置文件夹
frame 存放自路由的文件夹
page 项目模板文件夹,所有的页面文件全部存放与此,后面会根据需要来建立各种子目录
style 样式存放目录

我们在src/page目录下面新建两个文件,分别是index.vuecontent.vue

代码分别是

//index.vue
<template>
  <div>index</div>
</template>

//content.vue
<template>
  <div>content</div>
</template>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

7 这里,我们只要先把基础的内容写好就是了。我就用两个单词代表我们的页面。

安装VueRouter2

接下来,我们需要安装VueRouter2到我们的项目。参考文档见VueRouter2安装文档

在终端中,我们把当前目录跳转到我们的项目,然后执行npm install vue-router -D命令。如下:

cd ~/Sites/MyWork/vuedemo
npm install vue-router -D
  • 1
  • 2
  • 1
  • 2

我们查阅文档,会知道,命令是npm install vue-router,那为什么我后面加一个-D的参数呢?这个是为了让我们的安装的vue-router这个插件写入到package.json配置文件中。以便于下次再其他地方安装的时候,可以一并安装进去,否则,还得再安装一遍。

配置 main.js

通过在终端中执行命令,我们已经安装好路由了。下面,我们需要在src/main.js文件中进行配置。 
整理代码如下:

// 引用 vue 没什么要说的
import Vue from 'vue'
// 引用路由
import VueRouter from 'vue-router'
// 光引用不成,还得使用
Vue.use(VueRouter)
// 入口文件为 src/App.vue 文件 所以要引用
import App from './App.vue'
// 引用路由配置文件
import routes from './config/routes'
// 使用配置文件规则
const router = new VueRouter({
  routes
})
// 跑起来吧
new Vue({
  router,
  el: '#app',
  render: (h) => h(App)
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

上面的配置文件中的一部分在官方文档里面也找不到,这是我整理出来的,不用管,全部复制过去吧!

配置 App.vue

入口文件肯定和默认的不一样,我的配置文件如下:

<template>
  <div>
    <router-view
      class="view"
      keep-alive
      transition
      transition-mode="out-in">
    </router-view>
  </div>
</template>

<script>
export default {
  components: {}
}
</script>

<style lang="scss">
  @import "./style/style";
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

就只是一个单纯的路由入口页面。比较特殊的是,下面我 import了一个scss文件。我喜欢把css独立出来,而不是写在一起,所以我之前在src目录下面建立了一个style的文件,里面放scss文件。

我建议你先跟着我走,回头自己根据自己的习惯调整。

配置 routes.js

下面我们配置路由文件。

// 引用模板
import index from '../page/index.vue'
import content from '../page/content.vue'
// 配置路由
export default [
  {
    path: '/',
    component: index
  },
  {
    path: '/content',
    component: content
  },
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

如上,我们引用模板,然后再配置路由,这里,我们没有涉及自路由的内容,我们先这样配置上。然后,我们就可以在终端里面输入 npm run dev 来看我们做的效果了。

配置运行端口

如果没有跑起来,提示下面的错误,就表明默认的端口8080被占用了。一般不会被占用,但是也有可能被占用。所以,我们这边来学习一下如何配置运行端口。

# 端口被占用的提示
Error: listen EADDRINUSE :::8080
    at Object.exports._errnoException (util.js:953:11)
    at exports._exceptionWithHostPort (util.js:976:20)
    at Server._listen2 (net.js:1253:14)
......
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

打开项目根目录下/config/index.js配置文件,找到

dev: {
  env: require('./dev.env'),
  port: 8080,
  assetsSubDirectory: 'static',
  assetsPublicPath: '/',
  proxyTable: {},
  // CSS Sourcemaps off by default because relative paths are "buggy"
  // with this option, according to the CSS-Loader README
  // (https://github.com/webpack/css-loader#sourcemaps)
  // In our experience, they generally work as expected,
  // just be aware of this issue when enabling this option.
  cssSourceMap: false
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

如上,把 port 后面的端口改成其他数字,如9000 即可。

关闭格式检查插件eslint

如上,我们再次运行 npm run dev 跑起来,结果发现命令行里面错误一片。。。很多人在这里就都晕了。。。没关系,其中大部分错误都是格式造成的,并不是很重要的错误,但是这样的提示很不爽。因此,我们把检查错误插件eslint给关闭掉。

打开根目录下面的/build/webpack.base.conf.js文件,找到如下代码:

preLoaders: [
  {
    test: /\.vue$/,
    loader: 'eslint',
    include: projectRoot,
    exclude: /node_modules/
  },
  {
    test: /\.js$/,
    loader: 'eslint',
    include: projectRoot,
    exclude: /node_modules/
  }
],
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

全部注释掉,如下

// preLoaders: [
//   {
//     test: /\.vue$/,
//     loader: 'eslint',
//     include: projectRoot,
//     exclude: /node_modules/
//   },
//   {
//     test: /\.js$/,
//     loader: 'eslint',
//     include: projectRoot,
//     exclude: /node_modules/
//   }
// ],
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

回头,调整格式的时候可以再打开。先关掉,解决核心错误,再来考虑这些格式错误。

安装sass-loader以及node-sass插件

然后我们再跑,这回错误肯定少多了,但是还是有错误。如果你上面是严格按照我的代码来的,这里应该会提示缺少sass-loader组件错误。

没关系,缺什么,就安装什么,我们输入 npm install sass-loader -D进行安装。

如上图所示,就安装好了。

安装好了再跑,这回又提示我们缺少node-sass插件。折磨疯了吧?没关系,缺啥,安啥。

输入命令npm install node-sass -D进行安装。

安装结果不截图,然后,我们运行npm run dev,如果不出意外的话,应该能够顺利的跑起来了。

我们在地址栏后面输入http://localhost:9000/#/content应该就能访问到我们配置的内容页面的模板了,如下图所示:

通过前面几篇教程,我们已经顺利搭建起来了,并且已经组建好路由了。本章节,我们需要做一个列表页面,然后利用获取 http://cnodejs.org/api 的公开API,渲染出来。

制作列表页面

我们打开src/page/index.vue文件,在这里写入下面的代码:

<template>
  <div>
    <h1 class="logo">cnodejs Api Test</h1>
    <ul class="list">
      <li v-for="item in lists" v-text="item.title"></li>
    </ul>
  </div>
</template>
<script>
export default {
  data() {
    return {
      lists:[{
        id:1,
        title:"test title 1"
      },{
        id:2,
        title:"test title 2"
      }]
    }
  }
}
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

如上,我们通过自己写的两组数据,很轻松的将页面渲染成功了。通过浏览器,我们可以看到效果

配合点css

这里,我着重强调的不是css如何去写,而是我的组织项目的结构,我感觉我组织得还是很不错的。

新建文件, src/style/scss/_index.scss

输入下面的内容

.logo {color: red;}
.list {
  line-height: 2;
  li {border-bottom: 1px solid #ddd;}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

然后在 src/style/style.scss中输入

@import "scss/index";
  • 1
  • 1

然后,我们就可以在浏览器中,看到带样式的列表了。

我的习惯是,一个文件,一个样式,文件位于src/page/文件夹下面,样式位于src/style/scss下面。文件和样式同名。如果文件位于子目录,如src/page/user/pay.vue,那么,对应的scss文件就是src/style/scss/user/_pay.scss这样。

每一个团队的规范都是不一样的,都是各有所长的,重要的是,条理性。

调用api.js

在第二节中,我们在src/config目录下面建立了一个api.js的空文件。在第三节中没有使用。本节,我们要开始使用了。

首先,我们编辑 src/main.js ,引用 src/config/api.js。如下:

import api from './config/api'
Vue.prototype.$api = api
  • 1
  • 2
  • 1
  • 2

插入这两行代码,就引用好了api.js,并且,把它绑定到了全局,然后我们就可以在各种地方使用这个文件了。虽然这个文件是空的。

可能部分朋友不知道插入到文件的哪里去。我这里放上main.js的全部代码:

// 引用 vue 没什么要说的
import Vue from 'vue'
// 引用路由
import VueRouter from 'vue-router'
// 光引用不成,还得使用
Vue.use(VueRouter)
// 入口文件为 src/App.vue 文件 所以要引用
import App from './App.vue'
// 引用路由配置文件
import routes from './config/routes'
// 引用API文件
import api from './config/api'
// 将API方法绑定到全局
Vue.prototype.$api = api
// 使用配置文件规则
const router = new VueRouter({
  routes
})
// 跑起来吧
new Vue({
  router,
  el: '#app',
  render: (h) => h(App)
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

安装superagent组件

要请求接口,就必须有相对应的组件。如果你使用过jQuery,应该熟悉其中的AJAX方法。当然,在vue中,我们就不考虑使用jquery了。我们使用superagent这个组件。

安装非常简单,我们首先跳转到项目根目录,然后输入 npm install superagent -D进行安装。

编写api.js文件

有了工具了,我们就需要来编写api.js文件,使它可以完成我们想要的工作。

// 配置API接口地址
var root = 'https://cnodejs.org/api/v1';
// 引用superagent
var request = require('superagent');
// 自定义判断元素类型JS
function toType(obj) {
  return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
// 参数过滤函数
function filter_null(o) {
  for (var key in o) {
    if (o[key] == null) {
      delete o[key]
    }
    if (toType(o[key]) == 'string') {
      o[key] = o[key].trim()
      if (o[key].length == 0) {
        delete o[key]
      }
    }
  }
  return o
}
/*
  接口处理函数
  这个函数每个项目都是不一样的,我现在调整的是适用于
  https://cnodejs.org/api/v1 的接口,如果是其他接口
  需要根据接口的参数进行调整。参考说明文档地址:
  https://cnodejs.org/topic/5378720ed6e2d16149fa16bd
*/
function _api_base(method, url, params, success, failure) {
  var r = request(method, url).type('text/plain')
  if (params) {
    params = filter_null(params);
    if (method === 'POST' || method === 'PUT') {
      if (toType(params) == 'object') {
        params = JSON.stringify(params);
      }
      r = r.send(params)
    } else if (method == 'GET' || method === 'DELETE') {
      r = r.query(params)
    }
  }
  r.end(function(err, res) {
    if (err) {
      alert('api error, HTTP CODE: ' + res.status);
      return;
    };
    if (res.body.success == true) {
      if (success) {
        success(res.body);
      }
    } else {
      if (failure) {
        failure(res.body);
      } else {
        alert('error: ' + JSON.stringify(res.body));
      }
    }
  });
};
// 返回在vue模板中的调用接口
export default {
  get: function(url, params, success, failure) {
    return _api_base('GET', root + '/' + url, params, success, failure)
  },
  post: function(url, params, success, failure) {
    return _api_base('POST', root + '/' + url, params, success, failure)
  },
  put: function(url, params, success, failure) {
    return _api_base('PUT', root + '/' + url, params, success, failure)
  },
  delete: function(url, params, success, failure) {
    return _api_base('DELETE', root + '/' + url, params, success, failure)
  },
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76

这个文件就有点狂拽酷炫吊炸天了。目前,我们测试cnodejs.org的接口,我调整得可以使用。实际上在其他的接口项目中,这个是需要调整的,要调整到你的项目合适的代码。主要是根据接口返回的内容进行各种判断和处理,其中主要的框架代码是不用动的。

如果你JS基础过硬,一看就懂,如果不行,就慢慢看,慢慢理解吧。反正我基础不成,也看着理解了。

模板中调用api接口试试

编辑src/page/index.vue文件,代码如下:

<template>
  <div>
    <h1 class="logo">cnodejs Api Test</h1>
    <ul class="list">
      <li v-for="item in lists" v-text="item.title"></li>
    </ul>
  </div>
</template>
<script>
export default {
  data() {
    return {
      lists:[]
    }
  },
  created () {
    // 组件创建完后获取数据,这里和1.0不一样,改成了这个样子
    this.get_data()
  },
  methods: {
    get_data: function(params) {
      var v = this
      if (!params) params = {}
      // 我们这里用全局绑定的 $api 方法来获取数据,方便吧~
      v.$api.get('topics', params, function(r) {
        v.lists = r.data
      })
    },
  },
}
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

保存后,我们在浏览器中,就可以看到渲染出来的列表了。如下图所示:



本章讲一下如何配置子路由,因为我们的项目不可能只有一个页面,而是由众多页面构成的。

新建子路由页面

在第二节中,我们新建了一个src/frame/subroute.vue的子页面。当时是留空放在那里的。这里,我们给它填写上内容,代码如下:

<template>
<div>
    <router-view></router-view>
</div>
</template>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

好,我们的子路由页面就构建好了。

新建子页面

我们在src/page文件夹下新建文件夹user,然后在里面新建三个文件index.vueinfo.vuelove.vue。代码内容分别如下:

// src/page/user/index.vue
<template>
  <div>user index page</div>
</template>

// src/page/user/info.vue
<template>
  <div>user info page</div>
</template>
// src/page/user/love.vue
<template>
  <div>user love page</div>
</template>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

好,很简单,三个子页面分别有内容就是了,只是作为演示。

配置routes.js文件

打开src/config/routes.js文件,这个文件就是配置所有路由的文件。首先,在顶部插入下面的代码,引用子路由文件

// 引入子路由
import Frame from '../frame/subroute.vue'
  • 1
  • 2
  • 1
  • 2

然后,我们需要引入我们前面写的俩子页面模板。代码如下:

// 引入子页面
import userIndex from '../page/user/index.vue'
import userInfo from '../page/user/info.vue'
import userLove from '../page/user/love.vue'
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

引入好这些文件之后,我们就开始配置子路由了。

{
  path: '/user',
  component: Frame,
  children: [
    {path: '/',component: userIndex},
    {path: 'info',component: userInfo},
    {path: 'love',component: userLove}
  ],
},
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

如上,新建一个 user的顶级路由节点,把component设置为Frame,然后添加子路由节点children,然后下面分别设置。

我的项目的整体代码演示如下:

// 引入子路由
import Frame from '../frame/subroute.vue'
// 引用模板
import index from '../page/index.vue'
import content from '../page/content.vue'
// 引入子页面
import userIndex from '../page/user/index.vue'
import userInfo from '../page/user/info.vue'
import userLove from '../page/user/love.vue'
// 配置路由
export default [
  {
    path: '/',
    component: index
  },
  {
    path: '/content',
    component: content
  },
  {
    path: '/user',
    component: Frame,
    children: [
      {path: '/',component: userIndex},
      {path: 'info',component: userInfo},
      {path: 'love',component: userLove}
    ],
  },
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

好,我们通过浏览器访问以下,截图如下:

如上,我们就很顺利的搞好这个子路由了。






0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:5696次
    • 积分:257
    • 等级:
    • 排名:千里之外
    • 原创:20篇
    • 转载:7篇
    • 译文:0篇
    • 评论:0条
    文章分类