IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue-02 -> 正文阅读

[JavaScript知识库]vue-02

Vue

1. 常用命令

1.1 v-bind

用于绑定元素属性

1.2 v-if

<div id="app-3">
  <p v-if="seen">现在你看到我了</p>
</div>

var app3 = new Vue({
  el: '#app-3',
  data: {
    seen: true
  }
})

Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做除了使 Vue 变得非常快之外,还有其它一些好处。例如,如果你允许用户在不同的登录方式之间切换:

<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address">
</template>

那么在上面的代码中切换 loginType 将不会清除用户已经输入的内容。因为两个模板使用了相同的元素,<input> 不会被替换掉——仅仅是替换了它的 placeholder

这样也不总是符合实际需求,所以 Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 key attribute 即可:

<template v-if="loginType === 'username'">
  <label>Username</label>
  <input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
  <label>Email</label>
  <input placeholder="Enter your email address" key="email-input">
</template>

现在,每次切换时,输入框都将被重新渲染。

注意,<label> 元素仍然会被高效地复用,因为它们没有添加 key attribute。

v-if一般不与v-for在同一元素上连用

1.3 v-for

<div id="app-4">
  <ol>
    <li v-for="todo in todos">
      {{ todo.text }}
    </li>
  </ol>
</div>

var app4 = new Vue({
  el: '#app-4',
  data: {
    todos: [
      { text: '学习 JavaScript' },
      { text: '学习 Vue' },
      { text: '整个牛项目' }
    ]
  }
})

对于todos的操作如下:

app4.todos.push({text: '添加一个下项目'})

v-for 块中,我们可以访问所有父作用域的 property。v-for 还支持一个可选的第二个参数,即当前项的索引。

<ul id="example-2">
  <li v-for="(item, index) in items">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
  </li>
</ul>
data: {
    parentMessage: 'Parent',
    items: [
        {message: 'Foo'},
        {message: 'Bar'}
    ]
}

结果:

- Foo
- Bar

你也可以用 v-for 来遍历一个对象的 property。

<ul id="v-for-object" class="demo">
  <li v-for="value in object">
    {{ value }}
  </li>
</ul>
new Vue({
  el: '#v-for-object',
  data: {
    object: {
      title: A',
      author: 'B',
      publishedAt: 'C'
    }
  }
})

结果:

- A
- B
- C

你也可以提供第二个的参数为 property 名称 (也就是键名):

<div v-for="(value, name) in object">
  {{ name }}: {{ value }}
</div>

结果:

name:A
name:B
name:C

有关key和v-for结合使用的相关描述

2.2.0+ 的版本里,当在组件上使用 v-for 时,key 现在是必须的。

? https://cn.vuejs.org/v2/api/#key

为什么要加key

https://www.jianshu.com/p/4bd5e745ce95

1.4 v-once

<span v-once>这个将不会改变: {{ msg }}</span>	

通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。但请留心这会影响到该节点上的其它数据绑定:

1.5 钩子函数

如 mount/create等函数,可以在vue实例的生命周期中插入相关操作

1.6 箭头函数

实际上和java的λ表达式一样,但是在vue中比较多特殊的是不绑定this

var elements = [
  'Hydrogen',
  'Helium',
  'Lithium',
  'Beryllium'
];

elements.map(function(element) {
  return element.length;
}); // 返回数组:[8, 6, 7, 9]

// 上面的普通函数可以改写成如下的箭头函数
elements.map((element) => {
  return element.length;
}); // [8, 6, 7, 9]

// 当箭头函数只有一个参数时,可以省略参数的圆括号
elements.map(element => {
 return element.length;
}); // [8, 6, 7, 9]

// 当箭头函数的函数体只有一个 `return` 语句时,可以省略 `return` 关键字和方法体的花括号
elements.map(element => element.length); // [8, 6, 7, 9]

// 在这个例子中,因为我们只需要 `length` 属性,所以可以使用参数解构
// 需要注意的是字符串 `"length"` 是我们想要获得的属性的名称,而 `lengthFooBArX` 则只是个变量名,
// 可以替换成任意合法的变量名
elements.map(({ "length": lengthFooBArX }) => lengthFooBArX); // [8, 6, 7, 9]

1.7 v-html

将文本内容按照html代码解析

<p>例如: {{ rawHtml }}</p>
<p>例如: <span v-html="rawHtml"></span></p>

输出如下

例如:hh

例如:hh //这里的hh是红色的

不推荐使用

1.8 []

从 2.6.0 开始,可以用方括号括起来的 JavaScript 表达式作为一个指令的参数:

<a v-bind:[attributeName]="url"> ... </a> 	 	

这里的 attributeName 会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用。例如,如果你的 Vue 实例有一个 data property attributeName,其值为 "href",那么这个绑定将等价于 v-bind:href

同样地,你可以使用动态参数为一个动态的事件名绑定处理函数:

<a v-on:[eventName]="doSomething"> ... </a>

在这个示例中,当 eventName 的值为 "focus" 时,v-on:[eventName] 将等价于 v-on:focus

1.9 修饰符

修饰符 (modifier) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault()

<form v-on:submit.prevent="onSubmit">...</form>

preventDefault() 方法阻止元素发生默认的行为(例如,当点击提交按钮时阻止对表单的提交)。

1.10 v-bind:class

? 用来动态切换clss,text-danger是普通的class attribute

<div 
     class="classA"
     :class="classB: isActive,'text-danger': hasErr"
></div>
data: {
    isActive: true,
    hasErr: false
}

渲染如下:

<div class="classA classB"></div>

若hasErr发生变化,则:

<div class="classA classB text-danger"></div>

绑定的数据对象不必内联定义在模板里:

<div v-bind:class="classObject"></div>
data: {
  classObject: {
    classB: true,
    'text-danger': false
  }
}

渲染的结果和上面一样。

1.11 v-bind:style

v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名:

<div 
     v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"
></div>
data: {
  activeColor: 'red',
  fontSize: 30
}

直接绑定到一个样式对象通常更好,这会让模板更清晰:

<div v-bind:style="styleObject"></div>
data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}

同样的,对象语法常常结合返回对象的计算属性使用。

v-bind:style 的数组语法可以将多个样式对象应用到同一个元素上:

<div v-bind:style="[baseStyles, overridingStyles]"></div>
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>

1.12 数组的相关操作

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

以上这些方法会改变调用他们的数组,还有一些方法,例如:filter()concat(),**slice()**等方法会直接返回一个新的数组

example1.items = example1.items.filter(function (item) {
  return item.message.match(/Foo/)
})

而且,你可能认为这将导致 Vue 丢弃现有 DOM 并重新渲染整个列表。幸运的是,事实并非如此。Vue 为了使得 DOM 元素得到最大范围的重用而实现了一些智能的启发式方法,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。

有时,我们想要显示一个数组经过过滤或排序后的版本,而不实际变更或重置原始数据。在这种情况下,可以创建一个计算属性,来返回过滤或排序后的数组。

例如:

<li v-for="n in evenNumbers">{{ n }}</li>
data: {
  numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
  evenNumbers: function () {
    return this.numbers.filter(function (number) {
      return number % 2 === 0
    })
  }
}

在计算属性不适用的情况下 (例如,在嵌套 v-for 循环中) 你可以使用一个方法:

1.13 v-on

事件修饰符

在事件处理程序中调用 event.preventDefault()event.stopPropagation() 是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。

为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的

  • .stop
  • .prevent
  • .capture
  • .self
  • .once
  • .passive
  • .once
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>

<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>

<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>

1.14 v-model

一些修饰符

  • .lazy

在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步 (除了上述输入法组合文字时)。你可以添加 lazy 修饰符,从而转为在 change 事件_之后_进行同步:

<!-- 在“change”时而非“input”时更新 -->
<input v-model.lazy="msg">
  • .number

    如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符:

    <input v-model.number="age" type="number">
    
  • .trim

    如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符:

    <input v-model.trim="msg">
    

v-model与自定义事件的一些用法

<custom-input v-model="searchText"></custom-input>

等价于

<custom-input
	v-bind:value="searchText"
    v-on:input="searchText = $event"   
></custom-input>

所以,为了让它正常工作,这个组件内的 <input> 必须:

  • 将其 value attribute 绑定到一个名叫 value 的 prop 上
  • 在其 input 事件被触发时,将新的值通过自定义的 input 事件抛出
Vue.component('custom-input', {
  props: ['value'],
  template: `
    <input
      v-bind:value="value"
      v-on:input="$emit('input', $event.target.value)"
    >
  `
})

2. 计算属性

在vue实例中队vue中的data中的属性进行绑定操作,这种操作可以当作data中的另一种属性,例如:

<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
})

结果:

Original message: “Hello”

Computed reversed message: “olleH”

这里我们声明了一个计算属性 reversedMessage。我们提供的函数将用作 property vm.reversedMessage 的 getter 函数:

console.log(vm.reversedMessage) // => 'olleH'
vm.message = 'Goodbye'
console.log(vm.reversedMessage) // => 'eybdooG'

一般计算属性不与v-for连用

一些其他用法

  • 可以替代侦听属性

    当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch

    <div id="demo">{{ fullName }}</div>
    

    侦听:

    var vm = new Vue({
      el: '#demo',
      data: {
        firstName: 'Foo',
        lastName: 'Bar',
        fullName: 'Foo Bar'
      },
      watch: {
        firstName: function (val) {
          this.fullName = val + ' ' + this.lastName
        },
        lastName: function (val) {
          this.fullName = this.firstName + ' ' + val
        }
      }
    })
    

    计算属性

var vm = new Vue({
    el: '#demo',
    data{
    	firstName: 'Foo',
    	lastName:	'Bar'
	}
    computer: {
    	fullName: function(){
    		return this.firstName + '' + this.lastName;
		}             
    }
})
  • 设置set方法

    一般计算属性默认都是setter方法,但可以设置一个setter方法

    var vm = new Vue({
        el: '#demo',
        data{
        	firstName: 'Foo',
        	lastName:	'Bar'
    	}
        computer: {
        	fullName:{
            	get: function(){
        			return this.firstName + '' + this.lastName;
    			}   
    			set: functiong(newValue){
                    var names = newValue.split('');
                    this.firstName = names[0];
                    this.lastName = names[names.length - 1];
                }
            }       
        }
    })
    

    现在再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstNamevm.lastName 也会相应地被更新。

计算属性的好处

<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在组件中
methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}

将reverseMessage定义成一个方法同样可以达到反转的效果,但计算属性属于响应式依赖,也就是说,如果使用计算属性来实现反转效果,如果message不发生改变,则reverseMessage不会再次运行,直接返回之前缓存中的值,而定义成方法则每次都会重新执行reverseMessage()方法,会消耗资源,因此,推荐使用计算属性。

computed: {
  now: function () {
    return Date.now()
  }
}

因为是计算属性,所以只要Date.now()不会每次都刷新

3. 非常有用的示例

3.1 动态添加一个含有函数的按钮

原文档

<div id="todo-list-example">
  <form v-on:submit.prevent="addNewTodo">
    <label for="new-todo">Add a todo</label>
    <input
      v-model="newTodoText"
      id="new-todo"
      placeholder="E.g. Feed the cat"
    >
    <button>Add</button>
  </form>
  <ul>
    <li
      is="todo-item"
      v-for="(todo, index) in todos"
      v-bind:key="todo.id"
      v-bind:title="todo.title"
      v-on:remove="todos.splice(index, 1)"
    ></li>
  </ul>
</div>

注意这里的 is="todo-item" attribute。这种做法在使用 DOM 模板时是十分必要的,因为在 <ul> 元素内只有 <li> 元素会被看作有效内容。这样做实现的效果与 <todo-item> 相同,但是可以避开一些潜在的浏览器解析错误。查看 DOM 模板解析说明 来了解更多信息。

Vue.component('todo-item', {
  template: '\
    <li>\
      {{ title }}\
      <button v-on:click="$emit(\'remove\')">Remove</button>\
    </li>\
  ',
  props: ['title']
})

new Vue({
  el: '#todo-list-example',
  data: {
    newTodoText: '',
    todos: [
      {
        id: 1,
        title: 'Do the dishes',
      },
      {
        id: 2,
        title: 'Take out the trash',
      },
      {
        id: 3,
        title: 'Mow the lawn'
      }
    ],
    nextTodoId: 4
  },
  methods: {
    addNewTodo: function () {
      this.todos.push({
        id: this.nextTodoId++,
        title: this.newTodoText
      })
      this.newTodoText = ''
    }
  }
})

解决:子组件调用父组件方法

demo1.vue

<template>
  <div id="todo-list-example">
    <form v-on:submit.prevent="addNewTodo">
      <label for="new-todo">Add a todo</label>
      <input
        v-model="newTodoText"
        id="new-todo"
        placeholder="E.g. Feed the cat"
      >
      <button>Add</button>
    </form>
    <ul>
      <li
        is="todoItem"
        v-for="(todo, index) in todos"
        v-bind:key="todo.id"
        v-bind:title="todo.title"
        @remove="todos.splice(index,1)"
      ></li>
    </ul>
  </div>
</template>

<script>
  import base from '@/baseMix/listMix'
  import todoItem from './demo2'


  export default {
    name: 'todo-list-example',
    components: {todoItem},
    data() {
      return {
        newTodoText: '',
        mixins: [base],
        todos: [
          {
            id: 1,
            title: 'Do the dishes',
          },
          {
            id: 2,
            title: 'Take out the trash',
          },
          {
            id: 3,
            title: 'Mow the lawn'
          }
          ],
        nextTodoId: 4
      }

    },
    methods: {
      addNewTodo: function () {
        this.todos.push({
          id: this.nextTodoId++,
          title: this.newTodoText
        })
        this.newTodoText = ''
      }
    }
  }
</script>

<style scoped>

</style>

demo2.vue

<template>
  <li>
    {{title}}
    <button v-on:click="$emit('remove')">Remove</button>
  </li>
</template>

<script>
    export default {
        name: "todo-item",
        props: {
          title: '',
        }
    }
</script>

<style scoped>

</style>

3.2 父组件调用子组件的方法

https://www.cnblogs.com/jin-zhe/p/9523029.html

3.3 子组件调用父组件的方法

https://www.cnblogs.com/jin-zhe/p/9523782.html

3.4 父组件向子组件传值

https://www.cnblogs.com/padding1015/p/7878710.html

3.4 props中属性值类型的设置

https://www.cnblogs.com/yddzyy/p/13269839.html

4. 组件深入

4.1 组件注册

全局注册

Vue.component('my-component',{...})

使用这种方式,为全局注册

例如:

<!--demo3的代码如下-->
<template>
    <div>
      <h1>测试一下全局注册</h1>
    </div>
</template>

<script>
    export default {
      name: 'test-demo3',
    }
</script>

<style scoped>

</style>

将demo3在main.js中全局注册

import testDemo1 from '@/views/dateList/dateListVue/demo3'
Vue.component('test-demo1',testDemo1)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1BvCef25-1629538897942)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210820144636596.png)]

在demo4中自动显示test-demo3

局部注册

通过普通的js对象来定义组件

var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }

然后在 component 中定义想要使用的组件

new Vue({
  el: '#app',
  components: {
    'component-a': ComponentA,
    'component-b': ComponentB
  }
})

对于 components 对象中的每个 property 来说,其 property 名就是自定义元素的名字,其 property 值就是这个组件的选项对象。

或者如果你通过 Babel 和 webpack 使用 ES2015 模块,那么代码看起来更像:

import ComponentA from './ComponentA.vue'

export default {
  components: {
    ComponentA
  },
  // ...
}

在 ES2015+ 中,在对象中放一个类似 ComponentA 的变量名其实是 ComponentA: ComponentA 的缩写,即这个变量名同时是:

  • 用在模板中的自定义元素的名称
  • 包含了这个组件选项的变量名

.注意

1.大小写问题

  • 在 DOM 中使用模板时 (直接在一个 HTML 文件里撰写模板),还需要避免使用大写字符来命名键名,因为浏览器会把 attribute 名全部强制转为小写:

    <!--
    在 DOM 中使用模板时这段代码会被转换为 `v-bind:[someattr]`。
    除非在实例中有一个名为“someattr”的 property,否则代码不会工作。
    -->
    <a v-bind:[someAttr]="value"> ... </a>
    

    那么,我们一般在props中定义attribute,最好不要用驼峰命名法,用小短横 - 来命名,如data-list

2.props和data的区别

https://www.jb51.net/article/181697.htm

3.v-if

v-if接收的值不是简单的true而是truthy

Truthy(真值)的解释

https://developer.mozilla.org/zh-CN/docs/Glossary/Truthy

4.命名

4.1 组件名

在注册组件名的时候强烈推荐:

字母全小写且必须包含一个连字符

Vue.component('my-component-name', { /* ... */ })

4.2 事件名

推荐始终使用kebab-case 的事件名,因为:

  1. v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent 将会变成 v-on:myevent——导致 myEvent 不可能被监听到。
  2. 不同于组件和 prop,事件名不会被用作一个 JavaScript 变量名或 property 名,所以就没有理由使用 camelCase 或 PascalCase 了

总结

https://www.cnblogs.com/zhanglw456/p/12761008.html

5. 关于v-bind的一些问题

因为以前的学习中,双引号""中的内容,我们通常看作字符串,也因此通常不考虑""中的内容如何执行。

但是在v-bind中,经过v-bind绑定后,属性后的""中的内容将被看作js表达式

<!-- 即便 `42` 是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post v-bind:likes="42"></blog-post>

6. is

is attribute。在ul,table等元素中可能严格要求了其中的标签,所以我们直接使用组件可能并不能被接受,eg:

<ul>
    <my-row></my-row>
</ul>

并不能被识别,所以:

<ul>
    <row
    	is="my-row"
    ></row>
</ul>

4.1 组件名

在注册组件名的时候强烈推荐:

字母全小写且必须包含一个连字符

Vue.component('my-component-name', { /* ... */ })

4.2 事件名

推荐始终使用kebab-case 的事件名,因为:

  1. v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent 将会变成 v-on:myevent——导致 myEvent 不可能被监听到。
  2. 不同于组件和 prop,事件名不会被用作一个 JavaScript 变量名或 property 名,所以就没有理由使用 camelCase 或 PascalCase 了

总结

https://www.cnblogs.com/zhanglw456/p/12761008.html

5. 关于v-bind的一些问题

因为以前的学习中,双引号""中的内容,我们通常看作字符串,也因此通常不考虑""中的内容如何执行。

但是在v-bind中,经过v-bind绑定后,属性后的""中的内容将被看作js表达式

<!-- 即便 `42` 是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post v-bind:likes="42"></blog-post>

6. is

is attribute。在ul,table等元素中可能严格要求了其中的标签,所以我们直接使用组件可能并不能被接受,eg:

<ul>
    <my-row></my-row>
</ul>

并不能被识别,所以:

<ul>
    <row
    	is="my-row"
    ></row>
</ul>
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-22 13:28:04  更:2021-08-22 13:29:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 13:30:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码