Vue面试题收集

2019-05-17 admin

1.说说MVVM设计模式

    • M: Model(模型), vue中是data(为view提供数据) (Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。)
    • V: View(视图), vue中是模板页面(显示data中的数据) (View 代表UI 组件,它负责将数据模型转化成UI 展现出来。)
    • VM: ViewModel(视图模型), vue中是Vue实例对象(管理者: 数据绑定/DOM监听) (ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个同步View 和 Model的对象,连接Model和View)。
    • MVVM架构下,ViewModel 之间并没有直接的联系,而是通过ViewModel进行交互,ModelViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
  • ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而ViewModel 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理

2.说说你对计算属性的理解

  • 什么时候用计算属性?

    • 模板显示要显示的数据是根据n个已有的相关数据进行计算来确定
    • getter: get方法, 当读取属性值时/相关数据发生了改变自动调用, 根据相关数据进行计算并返回结果, this就是vm
    • setter: set方法, 当修改了当前属性的值自动调用, 监视属性值的变化去更新相关数据, this就是vm
  • 在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可能多次使用的情况下,尽量采取计算属性的方式

  • 好处:

    • ①使得数据处理结构清晰;
    • ②依赖于数据,数据更新,处理结果自动更新;
    • ③计算属性内部this指向vm实例;
    • ④在template调用时,直接写计算属性名即可;
    • ⑤常用的是getter方法,获取数据,也可以使用set方法改变数据;
    • ⑥相较于methods,不管依赖的数据变不变,methods都会重新计算,但是依赖数据不变的时候computed从缓存中获取,不会重新计算。

3.说说回调函数的判断及相关问题

  • 条件:

    • 是你定义的
    • 你没有调用
    • 但最终执行了(在后面的某个阶段或者某个条件下)
  • 关于回调函数相关的3个问题

    • 什么时候调用
    • 用来做什么的
    • this是谁 (只要是vue控制的回调函数 ,this都是vm

4.说说2种类型的数据容器

1.对象

  • 属性值才是我们要存的数据
  • 属性名是数据的标识名称,根据标识名来操作数据

2.数组

元素的下标就是数据的标识名称。根据标识名来操作数据

选择哪种容器?

  • 一般有序的用数组,不强调顺序的用对象
  • 如果有需要根据标识数据查找数据,用对象容器比用数组容器效率高

5.git的6个基本操作

  1. 创建本地仓库
  2. 创建远程仓库
  3. 将本地仓库的代码推送到远程仓库
  4. 如果本地代码有更新,提交到本地仓库,推送到远程仓库
  5. 如果远程仓库有更新,拉取到本地仓库
  6. 将本地仓库克隆到本地

6.data中的数组与对象属性不同处理

  • 数组:重写数组更新数组元素的方法,只要调用数组的这些方法,就会更新相应的界面
  • 对象:对对象中的属性进行setter监视,只要设置了新的属性值,就会更新相应的界面

7.区别compute于method和watch

  • computedmethodcomputed有缓存可以避免重复计算,而method不可以

  • computedwatch

    • get():可以监视所有依赖数据,编码简洁,但只能同步计算产生一个需要显示的结果数据
    • watch:可以监视所有依赖数据,编码麻烦,,可以进行异步/长时间处理后更新数据显示

8.函数的两个角色,方法与属性,方法与函数

  • 函数的两个角色:

    • 函数:通过()调用
    • 对象:通过.操作属性或方法,此时可以称之为函数对象
  • 方法与属性

  • 方法与函数

    • 在对象内定义的常称为方法,通过对象调用的常称为方法,其他常称为函数

9.写出7个指令及其作用

  • v-text: 设置标签体文本
  • v-html: 设置标签体子标签
  • v-if/v-else/v-show: 显示/隐藏
  • v-for: 遍历显示列表
  • v-bind: 强制绑定表达式, 简写:
  • v-on: 绑定事件监听, 简写@
  • v-model: 双向数据绑定
  • ref:为某个元素注册一个唯一标识,vue对象通过$els属性访问这个标识

10. 写出vue 7个配置选项及其作用

  • el: 最外层元素选择器
  • props: 声明接收哪些属性
  • data: 状态数据
  • computed: 计算属性
  • methods: 事件回调函数
  • watch: 监视属性变化
  • directives: 注册局部指令
  • filters: 注册局部过滤器
  • components: 配置组件

11. 说说vue的生命周期

  • 1.初始化

    • beforeCreate()
    • created()
    • beforeMount()
    • mounted(): 异步任务(发ajax请求/启动定时器)
  • 2.更新

  • 3.死亡

    • beforeDestroy(): 收尾工作(清除定时器)
    • destroyed()

12. 说说项目开发中常用的ES6新语法

  • 定义变量/常量: const/let

  • 解构赋值: let {a, b} = this.props / import {aa} from 'xxx' / function f ({name}) {}

  • 对象的简洁表达: {a, b, c () {}}

  • 箭头函数:

    • 组件的自定义方法: xxx = () => {}

    • 匿名函数作为实参

    • 优点:

      • 简洁
      • 没有自己的this,使用引用this查找的是外部this
  • 扩展运算符: …

  • 类: class/extends/constructor/super

  • ES6模块化: export/default/import

  • 异步: promise, async/await

13. 比较函数的call()/apply()/bind()

  • 1). call(obj, param1, param2)/apply(obj, [[param1, param2])

    • 调用/执行函数

    • 只是强制指定函数中的this为第一个参数指定的对象

      • 如果函数执行需要传参数, call是依次传递, apply需要封装成数组传递
  • 2). bind()

    • 返回一个新函数, 不会自动执行, 需要手动执行
    • 强制指定函数中的this为第一个参数指定的对象
    • 新函数内部会原样调用原函数

14. babel的插件和预设

    未来版本 ECMAScript 标准经历五个阶段:Strawman(稻草人),Proposal(提议),Draft(草案),Candidate(候选)以及 Finished (完成)
    也就是对应 stage0、stage1、stage2、stage3、stage4 五个阶段
    babel常用的预设包:
        es2015:包含 es2015 语法标准所有相关插件
        es2016:包含 es2016 语法标准所有相关插件
        es2017:包含 es2017 语法标准所有相关插件
        latest:包含从 2015 开始历年语法标准所有相关插件
        env:在 latest 基础上提供环境配置能力,比如可以配置只支持某一个浏览器的某几个版本,会自动按需启用、禁用插件
        stage-0:包含处于标准提案 stage 0 阶段的语法所有相关插件
        stage-1:包含处于标准提案 stage 1 阶段的语法所有相关插件
        stage-2:包含处于标准提案 stage 2 阶段的语法所有相关插件
        stage-3:包含处于标准提案 stage 3 阶段的语法所有相关插件
    预设包与插件包的关系
        一个插件包只能解析1种语法
        预设包是n个插件包的的集合包
    babel的配置: .babelrc
        {
          presets: [], // 配置所有需要的预设包
          plugins: [], // 配置额外需要的插件包
        }

15. props和v-model

  • 问题: v-model指向父组件传入的属性, 会导致直接更新父组件的数据, 这违背了组件化开发单向数据流的基本原则

  • 解决:

    • 方法1: data + watch
    • 方法2: 计算属性get + set

16.说说vue组件间通信的几种方式

  • 1.props:

    • 父子组件间通信的基本方式

    • 属性值的两大类型:

      • 一般:父组件 -->子组件
      • 函数:子组件 -->父组件
    • 隔层组件间传递:必须逐层传递(麻烦)

    • 兄弟组件间:必须借助父组件(麻烦)

  • 2.Vue自定义事件

    • 方式一:

      • 给子组件标签绑定事件监听
      • 子组件向父组件的通信方式
      • 功能类似于function props
      • 不适合隔层组件和兄弟组件间的通信
    • 方式二:通过单独的vm对象绑定监听/分发事件

  • 3.消息订阅和发布(pubsub-js)

  • 4.vuex

    • 多组件共享状态(数据的管理)
    • 组件间的关系也没有限制
    • 功能比pubsub强大,更适用于vue项目
  • 5.slot

    • 父组件向子组件通信
    • 通信是带数据的标签
    • 注意:标签是在父组件中解析

17.组件化编码流程和2个重要问题

  • 流程

  • 2个问题

    • 1.数据保存在哪个组件中? //哪个组件需要还是哪些组件需要
    • 2.更新数据的方法定义在哪个组件? //与数据同在一个组件

18.详细说明如何判断函数中的this

  • 正常情况:执行函数的方式决定了函数中的this

    • 1.直接调用:fn() - ->window
    • 2.new调用: new fn() - ->新创建的对象
    • 3.对象调用: obj.fn() - ->obj对象
    • 4.call/apply调用 :fn.call(obj) - -> 第一个参数指定的对象
  • 特别情况:

    • bind()返回的函数:fn2 = fn.bind(obj) - -> fn2()第一个参数指定的对象

    • 箭头函数:

      • 定时器回调/ajax回调/数组遍历相关方法回调 - ->window
      • dom事件监听回调 - - > dom元素
      • 组件生命周期回调 - - > 组件对象
  • 在开发中我们经常会利用箭头函数/bind()来改变this 的指向

19.关于2个引用变量指向同一个对象的2个问题

  • 两个引用变量指向同一个对象,通过一个引用变量改变对象内部的数据,另一个引用变量看到的新的
  • 两个引用变量指向同一个对象,让一个引用变量指向一个新的对象,另一个引用变量看到的还是原来的对象

20.说说读取表达式a.b的值的查找流程

  • 先查找a,沿着作用域链中,找不到报错(变量未定义)
  • 找到后查找对象上的b属性,查找原型链,如果找不到返回undefined

21.说说vue项目中如何与后台通信

  • 1.通过ajax请求与后台通信

  • 2.常用的库:

    • vue-resource:vue的插件,用于vue1.x
    • axios: 独立的第三方库,用于vue2.x
    • fetch: 较新的原生方式,但需要引入兼容包:fetch.js
  • 3.执行请求代码的时机

    • 初始化异步显示:mounted()
    • 特点用户操作后异步显示:事件回调函数或相关函数中

22.说说你对事件处理机制的理解

  • Dom事件:

    • 绑定事件监听

    • 回调函数: 接收包含相关数据的event, 处理事件

  • 自定义事件(如vue自定义事件/pubsub等)

    • 绑定事件监听

      • 事件名(类型): 任意
      • 回调函数: 通过形参接收数据, 在函数体处理事件
    • 触发(emit)/分发(dispatch)事件(编码)

      • 事件名(类型): 与绑定的事件监听的事件名一致
      • 数据: 会自动传递给回调函数

23.async/await 的作用和使用

  • 1.作用:

    • 简化promise的使用(不再使用then()/catch()来指定成功或者失败的回调函数)
    • 以同步编码的方式实现异步流程(没有回调函数)
  • 2.哪里使用await?

    • 在返回promise对象的表达式左侧,为了直接得到异步返回的结果,而不是promise对象
  • 3.哪里使用async?

24.GET请求的2种请求参数

    1. query参数:
    • 路由path: /register
    • 请求path: /register?username=xxx&password=yyy
    • 获取参数: req.query.username
    1. param参数:
    • 路由path: /register/:username/:password
    • 请求path: /register/xxx/123
    • 获取参数: req.params.username

25.vm对象与组件对象的关系

  • 1.组件对象是Vue的子类型对象,Vue原型对象上的属性/方法所有组件对象都可以访问
  • 2.一旦将某个数据或行为添加到Vue原型对象上,那所有组件中都可通过this轻松访问
  • 3.事件总线(EventBus)对象的存储:Vue.prototype.$eventBus = new Vue(),在组件中直接访问:this.$eventBus

26.vue-router提供了哪些语法

  • 1.1个函数:

    • VueRouer:路由构建函数,用于创建路由器对象,配置路由
  • 2.2个对象:

    • $route:代表当前路由的对象,包含当前路由相关信息(path,params参数,query参数)
    • $router:代表路由器对象,包含控制路由跳转的方法(push/replce/back())
  • 3.2个标签:

    • router-link>:路由链接,生成路由链接
    • router-view>:路由视图,显示当前路由组件

27.说说vue的数据代理

  • 通过一个对象(vm)代理对另一个对象(data)中属性的操作(读/写)

  • 好处:更方便的操作data中的数据

  • 基本实现流程:

    • 通过Object.defineProperty()给vm添加与data对象的属性对应的属性描述符
    • 所有添加的属性都包含getter/setter
    • 在getter/setter内部去操作data中对应的属性数据

28.说说vue模板解析

  • 1.目的

  • 2.整体流程

    • 将el的所有子节点取出,添加到一个新建的文档fragment对象中
    • 对fragment中的所有层次子节点递归进行编译解析处理
    • 将解析后的fragment添加到el中显示
  • 3.编译/解析包含大括号表达式的文本节点:textNode.textContent = value

  • 4.编译事件指令:elementNode.addEventListener(‘eventName’,callback)

  • 5.编译一般指令:elementNode.xxx = value

29.说说数据绑定的理解和基本原理

  • 作用;实现数据的更新显示

  • 基本原理:数据劫持 + 订阅者 - 发布者

    • 在observe中,通过Object.defineProperterty()给data 中所有属性添加setter/getter,实现数据劫持
    • 为每个data中的属性创建一个对应的dep对象(订阅器)
    • 为模板中的每个表达式创建对应的watcher对象(订阅者),并关联到对应的dep上
    • 一旦data中的数据发生变化,setter(发布者)会通过dep对象通知所有关联的watcher,watcher收到通知后就更新对应的节点

30.vue实现数据双向绑定的原理

  • 双向数据绑定是建立在单向数据绑定的基础上的,所以先简单说清楚单向数据绑定,再说双向

  • vue单向数据绑定的实现:

    • 数据劫持 + 订阅者 - 发布模式的方式
    • 通过Object.defineProperty()来劫持/监视data中的属性,在数据变动时发布消息给所有订阅者,每个订阅者去更新对应的DOM节点
    • 双向数据绑定:给元素绑定input监听,一旦输入改变了,将最新的值保存到对应的属性上

31.请说说你对vue生命周期的理解

  • vue生命周期分为8个阶段:创建前/后,载入前/后,更新前/后,销毁前/后
  • beforeCreate(创建前) 在数据观测和初始化事件还未开始
  • created(创建后) 完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来
  • beforeMount(载入前) 在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。
  • mounted(载入后) 在el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。
  • beforeUpdate(更新前) 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
  • updated(更新后) 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
  • beforeDestroy(销毁前) 在实例销毁之前调用。实例仍然完全可用。
  • destroyed(销毁后) 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

什么vue是生命周期?

  • Vue实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom -> 渲染、销毁等一系列过程,称之为Vue的生命周期

vue生命周期的作用是什么?

  • 它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑

第一次页面加载会触发哪几个钩子?

  • 会触发beforeCreate(创建前)、created(创建后)、beforeMoun(载入前)、mounted(载入后)这几个 。

DOM渲染在哪个周期就已经完成了

  • DOM渲染在mounted(载入后)中就已经完成了

32.Vue的路由实现:hash模式和history模式

  • hash模式: 在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取。特点:hash虽然在URL中,但不被包括在HTTP请求中,用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 http://www.xxx.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。
  • history模式:history采用HTML的新特性,且提供了两个新方法,pushState(),replacState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 http://www.xxx.com/items/id。后端如果缺少对 /items/id 的路由处理,将返回 404 错误。Vue-Router 官网里如此描述:“不过这种模式要玩好,还需要后台配置支持……所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。”

33.vue路由的钩子函数

  • 首页可以控制导航跳转,beforeEach,afterEach等,一般用于页面title的修改。一些需要登录才能调整页面的重定向功能
  • beforeEach主要有三个参数to、from、next:
  • to:route即将进入的目标路由对象
  • from:route当前导航正要离开的路由
  • next:function一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转

34.vuex是什么?怎么使用?哪种功能场景使用它?

35.vue中key值的作用?

  • 当Vue.js用v-for正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue将不会移动DOM元素来匹配数据项的顺序,而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key的作用主要是为了高效的更新虚拟DOM。

36.vue等单页面应用及其优缺点

  • 优点:Vue的目标是通过尽可能简单的API实现响应的数据绑定和组合的视图组件,核心是一个响应的数据绑定系统。MVVM、数据驱动、组件化、轻量、简洁、高效、快速、模块友好
  • 缺点:不支持低版本的浏览器,最低只支持到IE9,不利于SEO的优化(如果要支持SEO,建议通过服务端来进行渲染组件);第一次加载首页耗时相对长一些;不可以使用浏览器的导航按钮,需要自行实现前进,后退。

37.css只在当前组件起作用

38.$route 和$router的区

  • $route是‘路由信息对象’,包括path,params,hash,query,fullPath,matched,name等路由信息参数。
  • $router是‘路由实例对象’,包括了路由的跳转方法,钩子函数等

39. Vue.js是什么?

  • 一位华裔前Google工程师(尤雨溪)开发的前端js库

  • 作用: 动态构建用户界面

  • 特点:

    • 遵循MVVM模式
    • 编码简洁, 体积小, 运行效率高, 移动/PC端开发
    • 它本身只关注UI, 可以轻松引入vue插件和其它第三库开发项目
  • 与其它框架的关联:

  • vue包含一系列的扩展插件(库):

    • vue-cli: vue脚手架
    • vue-resource(axios): ajax请求
    • vue-router: 路由
    • vuex: 状态管理
    • vue-lazyload: 图片懒加载
    • vue-scroller: 页面滑动相关
    • mint-ui: 基于vue的组件库(移动端)
    • element-ui: 基于vue的组件库(PC端)

40.vue.js的两个核心是什么?

41.Vue组件data为什么必须是函数

  • 每个组件都是vue的实例
  • 组件共享data属性,当data的值是同一个引用类型的值时,改变其中一个会影响其他

42.指令v-el的作用是什么?

  • 提供一个在页面上已存在的DOM元素作为Vue实例的挂载目标,可以是一个css选择器,也可以是一个HTMLElement实例

43.对keep-alive的了解

  • keep-alive是Vue内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。
  • 在vue2.1.0版本之后,keep-alive新加入了两个属性:include(包含的组件缓存)与exclude(排除的组件不缓存,优先级大于include)
  • 使用方法:
<keep-alive include='include_components' exclude='exclude_components'>
  <component>
    <!-- 该组件是否缓存取决于include和exclude属性 -->
  </component></keep-alive>
  • 参数解释:

    • include - 字符串或正则表达式,只有名称匹配的组件会被缓存
  • exclude - 字符串或正则表达式,任何名称匹配的组件都不会被缓存

  • include 和exclude 的属性允许组件有条件地缓存。二者都可以用"," 分隔字符串、正则表达式、数组。当使用正则或者是数组时,要记得使用v-bind

[转载]原文链接:https://segmentfault.com/a/1190000019213474

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-65218.html

文章标题:Vue面试题收集

相关文章
三步搞定vue在vscode的环境配置问题
1. vscode基础开发插件 vscode-icons 图标美化 Debugger for Chrome 调试 Beautify 代码格式化 Prettier 代码格式化 ESLint 代码规范 JavaScript (ES6) cod...
2017-12-25
vue-awesome-swiper的使用以及API整理
一、先说一个看关于vue-awesome-swiper的一个坑 vue项目的package.json中显示的&lt;span style=“color: orange;”&gt;“vue-awesome-swiper”: “^2.5.4”&...
2018-04-26
vuejs通过filterBy、orderBy实现搜索筛选、降序排序数据
直接贴代码了: 先上输入前的样子: &lt;style&gt; #example{margin:100px auto;width:600px;} .show{margin:10px;} #searchText{display: block...
2017-03-17
最细致的vue.js基础语法 值得收藏!
介绍 前段时间接触到一个库叫做Vue.js, 个人感觉很棒,所以整理了一篇博文做个介绍。 Vue读音/vju:/,和view类似。是一个数据驱动的web界面库。Vue.js只聚焦于视图层,可以很容易的和其他库整合。代码压缩后只有24kb。 ...
2017-03-21
面试官:谈谈你对 CSS 盒模型的认识?(你确定会?)
题目:谈谈你对 CSS 盒模型的认识 涉及知识点(层层递进): 基本概念:标准模型+ IE模型(区别) CSS如何设置这两种模型 JS如何设置获取盒子模型对应的宽和高 实例题(根据盒模型解释边距重叠) BFC(边距重叠解决方案) 1...
2018-06-09
javascript字面量
你在JavaScript中使用文字代表值。 这些都是固定的值,而不是变量 从字面上 提供在你的脚本。 本节描述以下类型的文字: 数组 布尔 浮点型 整数 对象 字符串字面值 数组字面量 数组文字是零个或多个表达式的列表,每个代表一个数组元素...
2015-11-12
mpvue 小程序如何开启下拉刷新,上拉加载?
https://developers.weixin.qq.com/miniprogram/dev/api/pulldown.html#onpulldownrefresh 小程序API 微信小程序之下拉加载和上拉刷新 微信小程序下拉加载和上拉...
2018-05-25
vue使用watch 观察路由变化,重新获取内容
问题背景: 点击用户头像 =&gt; 进入用户个人中心,在用户个人中心里点击其他用户的头像,我希望显示被点击用户的个人中心,但只看到了路由参数在发生变化,页面内容并没有更新。如图: 页面代码如下: &lt;script&gt; exp...
2017-03-13
在 mpvue 使用 echarts 小程序组件
具体操作 下载 echarts-for-weixin 。 把其 ec-canvas 目录移动到 mpvue 项目的 static 目录下。 对 ec-canvas/ec-canvas.js 进行小调整,考虑提 pr 到 ec-c...
2018-03-11
mpvue 小程序如何自定义tabBar,不使用navigateTo跳转,模拟redirectTo跳转
原生tabBar tabBar: { &quot;list&quot;: [ { pagePath: &quot;pages&#x2F;index&#x2F;main&quot;, iconPath: &...
2018-05-25
回到顶部