全栈开发技术分享
首页
👉 CSS大揭秘 👈
  • 目录
  • 分类
  • 标签
  • 归档
  • Vue
  • JavaScript
  • 微信开发
  • 移动端H5调试工具
  • 国内十大前端团队网站
  • Nodejs
  • Egg
  • 环境搭建
  • 运维面板
  • 域名配置
  • Nginx
  • 收藏
  • 常用工具
  • 实用技巧
  • 常用命令
  • 友情链接
关于

Dreaming Lee 🍍 ҉҉҉҉҉҉҉҉

开发小菜鸡
首页
👉 CSS大揭秘 👈
  • 目录
  • 分类
  • 标签
  • 归档
  • Vue
  • JavaScript
  • 微信开发
  • 移动端H5调试工具
  • 国内十大前端团队网站
  • Nodejs
  • Egg
  • 环境搭建
  • 运维面板
  • 域名配置
  • Nginx
  • 收藏
  • 常用工具
  • 实用技巧
  • 常用命令
  • 友情链接
关于
  • 代码规范

    • Eslint
    • Eslint-Plugin-Vue
    • Stylelint
  • uniapp

    • 问题解决

      • 【uniapp】字节小程序BUG - “navigateToMiniProgram/getUserProfile:fail must be invoked by user tap gesture”
  • JavaScript

    • JS验证18位身份证号码
    • JS图片压缩
    • JS调用elementUI图片预览
    • JS图片上传前校验大小、尺寸
  • Vue

    • Vue基础教程

      • Vue教程(1)-基础篇
        • 1、模板语法
          • 1.1 指令
          • 1.2 v-on
          • 1.3 v-bind
          • 1.4 v-for
          • 1.5 v-model
          • 1.6 自定义指令
        • 2、API简要
          • 2.1 全局API
          • 2.2 选项-生命周期
          • 2.3 选项-数据
          • 2.4 选项-DOM
          • 2.5 选项-资源
          • 2.6 选项-组合
          • 2.7 选项-其他
          • 2.8 实例属性
          • 2.9 实例方法
          • 2.10 内置组件
          • 2.11 特殊特性
        • 3、其他
          • 3.1 计算属性和侦听器
        • 3.2 插件
        • 3.3 过滤器
        • 4、组件
          • 4.1 组件注册
          • 4.2 Prop
          • 4.3 event 自定义事件
          • 4.4 插槽slot
          • 4.5 动态组件
        • 5、过渡与动画
          • 5.1 过渡的类名
          • 5.2 显性的过渡持续时间
          • 5.3 JavaScript 钩子
          • 5.4 初始渲染的过渡
          • 5.5 其他
          • 5.6 状态过渡
      • Vue教程(2)-路由篇Vue-Router
      • Vue教程(3)- 状态管理Vuex
    • Vue自定义组件开发

      • Vue实现移动端轮播swiper组件
      • Vue实现switch开关组件
    • Vue扩展

      • Vue接入阿里OSS文件上传
    • Vue学习参考资料
  • 微信开发

    • 微信开发参考资料
    • 微信公众号

      • 微信公众号/订阅号/服务号主动给用户发消息
      • 微信jssdk自定义分享在iOS不生效
    • 微信小程序

      • 微信小程序区分运行环境:开发版/体验版/正式版
      • H5唤醒微信小程序
  • 收藏

    • 国内十大前端团队官网及GitHub
  • 常见问题解决

    • js错误

      • iframe下localStorage禁止访问。“Failed to read the localStorage property from Window”
      • TypeError: Promise.allSettled is not a function
    • IE兼容

      • fixed定位在IE下页面滚动时抖动
  • 工具

    • 移动端H5调试工具
  • 前端
  • Vue
  • Vue基础教程
Dreaming Lee 🍍 ҉҉҉҉҉҉҉҉
2021-05-10
1、模板语法
1.1 指令
1.2 v-on
1.3 v-bind
1.4 v-for
1.5 v-model
1.6 自定义指令
2、API简要
2.1 全局API
2.2 选项-生命周期
2.3 选项-数据
2.4 选项-DOM
2.5 选项-资源
2.6 选项-组合
2.7 选项-其他
2.8 实例属性
2.9 实例方法
2.10 内置组件
2.11 特殊特性
3、其他
3.1 计算属性和侦听器
3.2 插件
3.3 过滤器
4、组件
4.1 组件注册
4.2 Prop
4.3 event 自定义事件
4.4 插槽slot
4.5 动态组件
5、过渡与动画
5.1 过渡的类名
5.2 显性的过渡持续时间
5.3 JavaScript 钩子
5.4 初始渲染的过渡
5.5 其他
5.6 状态过渡

Vue教程(1)-基础篇

# 1、模板语法

# 1.1 指令

{{msg}}/v-text   # 文本插值
v-html   # 原始html
v-once   # 只渲染一次
v-show   # css控制显示隐藏
v-if     # 根据表达式渲染元素   # 用 key 管理可复用的元素
v-else/v-else-if # 紧跟v-if的else
v-for    # 列表渲染  可以循环数字、数组、对象和对象数组
v-on     # 事件渲染
v-bind   # 动态绑定属性 :是缩写
v-model  # 表单输入绑定
v-slot   # 插槽 限用于<template>/组件
v-pre    # 不编译,显示源码
v-cloak  # 隐藏未编译直到实例完成
1
2
3
4
5
6
7
8
9
10
11
12
13

# 1.2 v-on

@[event].stop   # @是v-on的缩写  [event]是动态事件  .stop是修饰符
.stop    # 调用 event.stopPropagation()。停止冒泡
.prevent    # 调用 event.preventDefault()。阻止默认行为
.capture    # 添加事件侦听器时使用 capture 模式。
.self    # 只当事件是从侦听器绑定的元素本身触发时才触发回调。
.{keyCode | keyAlias}    # 只当事件是从特定键触发时才触发回调。
.native    # 监听组件根元素的原生事件。
.once    # 只触发一次回调。
.left    # (2.2.0) 只当点击鼠标左键时触发。
.right    # (2.2.0) 只当点击鼠标右键时触发。
.middle    # (2.2.0) 只当点击鼠标中键时触发。
.passive    # (2.3.0) 以 { passive: true } 模式添加侦听器
1
2
3
4
5
6
7
8
9
10
11
12

# 1.3 v-bind

#:class和:style绑定样式
:class="[ 'red', 'thin', isactive ? 'active' : '' ]" # 1.使用数组、三元表达式
:class="[ 'red', 'thin', { 'active', isactive } ]" # 2.使用嵌套对象
:class="{ red: true, italic: true, active: true }" # 3.使用对象

:[key]="value" # :是v-bind的缩写  [key]是动态特性名  value可以属性/表达式/数组/组合/json对象
.prop     # 被用于绑定 DOM 属性 (property)。
.camel     # (2.1.0+) 将 kebab-case 特性名转换为 camelCase. (从 2.1.0 开始支持)
.sync     # (2.3.0+) 语法糖,会扩展成一个更新父组件绑定值的 v-on 侦听器。
1
2
3
4
5
6
7
8
9

# 1.4 v-for

# 1.循环数组和对象数组
<p v-for="(item, i) in list">{{item.name}},{{i}}</p>  
# 2.循环对象
<p v-for="(val, key, i) in user">{{val}},{{key}},{{i}}</p>   
# 3.迭代数字
<p v-for="count in 10">{{count}}</p>   
# 在组件中使用 v-for 时,必须添加key(=string/number)。
1
2
3
4
5
6
7

# 1.5 v-model

.lazy     # 取代 input 监听 change 事件
.number     # 输入字符串转为有效的数字
.trim     # 输入首尾空格过滤
1
2
3

# 1.6 自定义指令

钩子函数:bind/inserted/update/componentUpdated/unbind 函数参数:el、binding、vnode 、 oldVnode

<input v-focus>
Vue.directive('focus', {
  inserted: function (el) {
    el.focus()
  }
})

Vue.directive('demo', {
  bind: function (el, binding, vnode) {
    var s = JSON.stringify
    el.innerHTML =
      'name: '       + s(binding.name) + '<br>' +
      'value: '      + s(binding.value) + '<br>' +
      'expression: ' + s(binding.expression) + '<br>' +
      'argument: '   + s(binding.arg) + '<br>' +
      'modifiers: '  + s(binding.modifiers) + '<br>' +
      'vnode keys: ' + Object.keys(vnode).join(', ')
  }
})
# 函数简写(只在 bind 和 update 时触发相同行为)
Vue.directive('color-swatch', function (el, binding) {
  el.style.backgroundColor = binding.value
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 2、API简要

# 2.1 全局API

Vue.extend( options )   # 构造器扩展
Vue.directive( id, [definition] )   # 注册或获取全局指令。
Vue.set( target, key, value )   # 全局操作
Vue.component( id, [definition] )   # 注册或获取全局组件。
Vue.nextTick( [callback, context] )   # 在下次 DOM 更新循环结束之后执行延迟回调。
Vue.delete( target, key )   # 删除对象的属性。
Vue.filter( id, [definition] )   # 注册或获取全局过滤器。
Vue.use( plugin )   # 安装 Vue.js 插件。
Vue.mixin( mixin )   # 全局注册一个混入
Vue.compile( template )   # 在 render 函数中编译模板字符串。
Vue.observable( object )   # 让一个对象可响应。v2.6.0+
Vue.version   # 获取Vue 安装版本号。可根据不同版本号制定不同策略。
1
2
3
4
5
6
7
8
9
10
11
12

# 2.2 选项-生命周期

beforeCreate(){}    // 执行时组件实例还未创建,通常用于插件开发中执行一些初始化任务
created(){}         // 组件初始化完毕,各种数据可以使用,常用于异步数据获取
beforeMount(){}     // 未执行渲染、更新,dom未创建
mounted(){}         // 初始化结束,dom已创建,可用于获取访问数据和dom元素
beforeUpdate(){}    // 更新前,可用于获取更新前各种状态
updated(){}         // 更新后,所有状态已是最新
beforeDestroy(){}   // 销毁前,可用于一些定时器或订阅的取消
destroyed(){}       // 组件已销毁,作用同上
activated(){}       // keep-alive 缓存的组件激活时
deactivated(){}     // keep-alive 缓存的组件停用时
errorCaptured(){}   // 子孙组件的错误时被调用
1
2
3
4
5
6
7
8
9
10
11

# 2.3 选项-数据

data: Object|Function  # Vue 实例的数据对象。
props: Array<string>|Object   # 用于接收来自父组件的数据。
propsData: {[key:string]:any}   # 创建实例时传递 props。只用于 new 创建的实例中。
computed: {[key:string]:Function|{get:Function,set:Function}}   # 计算属性
methods: {[key:string]:Function}   # 方法
watch: {[key:string]:string|Function|Object|Array}   # 监听器
1
2
3
4
5
6

# 2.4 选项-DOM

el: string|Element   # 提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标。
template: string   # 模板
render: (createElement: () => VNode) => VNode   # 渲染函数
renderError: (createElement: () => VNode, error: Error) => VNode   # render函数错误提供另一种渲染输出
1
2
3
4

# 2.5 选项-资源

directives: Object   # 私有指令
filters: Object   # 私有过滤器
components: Object   # 私有组件
1
2
3

# 2.6 选项-组合

parent: Vue instance   # 指定已创建的实例之父实例,在两者之间建立父子关系。
mixins: Array<Object>   # 混入
extends: Object|Function   # 继承
provide / inject   # 为高阶插件/组件库提供用例。
1
2
3
4

# 2.7 选项-其他

name: string   # 只有作为组件选项时起作用。
delimiters: Array<string>   # 改变纯文本插入分隔符。只在完整构建版本中的浏览器内编译时可用
functional: boolean   # 使组件无状态 (没有 data ) 和无实例 (没有 this 上下文)。
model: { prop?: string, event?: string }   # 允许一个自定义组件在使用 v-model 时定制 prop 和 event。
inheritAttrs: boolean   #
comments: boolean   # 是否保留且渲染html注释
1
2
3
4
5
6

# 2.8 实例属性

vm.$data: Object   # Vue 实例观察的数据对象。
vm.$props: Object   # 当前组件接收到的 props 对象。
vm.$el: Element   # Vue 实例使用的根 DOM 元素。
vm.$options: Object   # 用于当前 Vue 实例的初始化选项。
vm.$parent: Vue instance   # 父实例,如果当前实例有的话。
vm.$children: Array<Vue instance>   # 当前实例的直接子组件。
vm.$slots: { [name: string]: ?Array<VNode> }   # 用来访问被插槽分发的内容。
vm.$scopedSlots: { [name: string]: props => Array<VNode> | undefined }   # 用来访问作用域插槽。
vm.$refs: Object   # 一个对象,持有注册过 ref 特性 的所有 DOM 元素和组件实例。
vm.$isServer: boolean   # 当前 Vue 实例是否运行于服务器。
vm.$attrs: { [key: string]: string }   # 包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。
vm.$listeners: { [key: string]: Function | Array<Function> }   # 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。
1
2
3
4
5
6
7
8
9
10
11
12

# 2.9 实例方法

vm.$watch( expOrFn, callback, [options] )    #监听器
vm.$set( target, key, value )   # 全局 Vue.set 的别名。
vm.$delete( target, key )   # 全局 Vue.delete 的别名。

vm.$on( event, callback )   # 监听当前实例上的自定义事件。
vm.$once( event, callback )   # 监听一个自定义事件,但是只触发一次.
vm.$off( [event, callback] )   # 移除自定义事件监听器。
vm.$emit( eventName, […args] )   # 触发当前实例上的事件。

vm.$mount( [elementOrSelector] )   # -生命周期-挂载实例
vm.$forceUpdate()   # -生命周期-重新渲染
vm.$nextTick( [callback] )   # -生命周期-将回调延迟到下次 DOM 更新循环之后执行。
vm.$destroy()   # -生命周期-销毁实例
1
2
3
4
5
6
7
8
9
10
11
12
13

# 2.10 内置组件

component   # 渲染一个“元组件”为动态组件。依 is 的值,来决定哪个组件被渲染。
transition   # 为单个元素/组件的过渡效果。
transition-group   # 为多个元素/组件的过渡效果。
keep-alive   # 动态组件
slot   # 为组件模板之中的内容分发插槽。
1
2
3
4
5

# 2.11 特殊特性

key: number | string   # 设置唯一的值
ref: string   # 用来给元素或子组件注册引用信息。
is: string | Object (组件的选项对象)   # 用于动态组件且基于 DOM 内模板的限制来工作。
slot/slot-scope(已废弃):v-slot指令替代
scope(已移除)
1
2
3
4
5

# 3、其他

# 3.1 计算属性和侦听器

  • 计算属性computed具有缓存性,适合做筛选,不可异步。多用于多对一场景,一些值变化时,生成一个计算值。
  • 侦听器watch适合做异步或开销较大的操作。多用于一对多场景,监听某个值变化时,处理相应的变化。

# 3.2 插件

Vue.use(MyPlugin)   // 使用插件
// 开发插件
MyPlugin.install = function (Vue, options) {
  // 1. 添加全局方法或属性
  Vue.myGlobalMethod = function () {
    // 逻辑...
  }
  // 2. 添加全局资源
  Vue.directive('my-directive', {
    bind (el, binding, vnode, oldVnode) {
      // 逻辑...
    }
    // ...
  })
  // 3. 注入组件
  Vue.mixin({
    created: function () {
      // 逻辑...
    }
    // ...
  })
  //  4. 添加实例方法
  Vue.prototype.$myMethod = function (methodOptions) {
    // 逻辑...
  }
}
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

# 3.3 过滤器

常用于文本格式化,用在双花括号插值和 v-bind 表达式中。

{{ message | capitalize }}
<div v-bind:id="rawId | formatId"></div>
# 局部过滤器
filters: {
    capitalize: function (value) {
        if (!value) return ''
        value = value.toString()
        return value.charAt(0).toUpperCase() + value.slice(1)
    }
}
# 全局过滤器
Vue.filter('dateFormat', function (time,format) {
	let t = new Date(time);
	let tf=(str)=>(str.toString().padStart(2,'0'));
	return format.replace(/yyyy|MM|dd|HH|mm|ss/g, function(a){
		switch(a){
			case 'yyyy':
				return tf(t.getFullYear());
				break;
			case 'MM':
				return tf(t.getMonth() + 1);
				break;
			case 'mm':
				return tf(t.getMinutes());
				break;
			case 'dd':
				return tf(t.getDate());
				break;
			case 'HH':
				return tf(t.getHours());
				break;
			case 'ss':
				return tf(t.getSeconds());
				break;
		}
	})
})
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

# 4、组件

  • 组件是可复用的 Vue 实例,带有一个名字,我们可以在一个通过 new Vue 创建的 Vue 根实例中,把这个组件作为自定义元素来使用。
  • 组件的data必须是函数。
  • 每个组件必须只有一个根元素。

# 4.1 组件注册

  • 全局注册 Vue.component(name, options)
<course-list :courses="courses"></course-list>
<script>
Vue.component('course-list', {
    data() {
        return { selectedCourse: '',}
    },
    props: {
        courses: {type: Array,default: []},
    },
    template: `<div>test</div>`,
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
  • 局部注册
  • 在模块系统中局部注册
var ComponentA = { /* ... */ } 
import ComponentB from 'ComponentB'
new Vue({
  el: '#app',
  components: {
    'component-a': ComponentA,
    'component-b': ComponentB
  }
})
1
2
3
4
5
6
7
8
9
  • 基础组件的自动化全局注册

# 4.2 Prop

  • prop传值为单向数据流,子组件可通过新定义参数接受改值
  • prop类型、默认值、校验
  • prop 可以通过 v-bind 动态赋值
Vue.component('my-component', {
  props: {
    propA: Number, // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
    propB: [String, Number], // 多个可能的类型
    propC: { type: String, required: true }, // 必填的字符串
    propD: { type: Number, default: 100 }, // 带有默认值的数字
    propE: { type: Object, default:()=> { message: 'hello' }}, // 对象或数组默认值必须从一个工厂函数获取
    propF: { validator: (value)=>  ['success', 'warning', 'danger'].indexOf(value) !== -1 }, // 自定义验证函数
  }
})
1
2
3
4
5
6
7
8
9
10

# 4.3 event 自定义事件

  • 事件名:使用 kebab-case
  • 自定义组件的 v-model : 需要实现内部input的:value和@input
  • .native 修饰符 将原生事件绑定到组件
  • .sync 修饰符 双向绑定
  • 监听子组件事件

# 4.4 插槽slot

- 插槽内容
- 编译作用域
- 后备内容:可在slot内定义默认内容
- 具名插槽:用name特性定义额外插槽,用带有v-slot的<template>提供内容;v-slot:header可缩写为#header
- 作用域插槽:如<slot v-bind:user="user">{{ user.lastName }}</slot>
- 动态插槽名:如<template v-slot:[dynamicSlotName]></template>
- 将插槽转换为可复用的模板:模板基于输入的 prop 渲染出不同的内容
1
2
3
4
5
6
7

# 4.5 动态组件

  • is特性:实现动态组件
  • keep-alive:包裹动态组件时,会缓存不活动的组件实例
  • 异步组件:...
  • 处理加载状态: v2.3.0+ 新增

# 5、过渡与动画

# 5.1 过渡的类名

v-enter    进入过渡的开始状态。# 在元素被插入之前生效,在元素被插入之后的下一帧移除。
v-enter-active    进入过渡生效时的状态。# 在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。
v-enter-to    进入过渡的结束状态。# 在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。
v-leave    离开过渡的开始状态。# 在离开过渡被触发时立刻生效,下一帧被移除。
v-leave-active    离开过渡生效时的状态。# 在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。
v-leave-to    离开过渡的结束状态。# 在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。
# 自定义过渡的类名
enter-class    enter-active-class    enter-to-class
leave-class    leave-active-class    leave-to-class
1
2
3
4
5
6
7
8
9

# 5.2 显性的过渡持续时间

<transition :duration="1000">...</transition>
<transition :duration="{ enter: 500, leave: 800 }">...</transition>
1
2

# 5.3 JavaScript 钩子

# 这些钩子函数可以结合 CSS transitions/animations 使用,也可以单独使用
<transition
  v-on:before-enter="beforeEnter"
  v-on:enter="enter"
  v-on:after-enter="afterEnter"
  v-on:enter-cancelled="enterCancelled"

  v-on:before-leave="beforeLeave"
  v-on:leave="leave"
  v-on:after-leave="afterLeave"
  v-on:leave-cancelled="leaveCancelled"
>...</transition>

methods: {   # 当与 CSS 结合使用时, 回调函数 done 是可选的
  beforeEnter: function (el){// ...},
  enter: function (el, done) {// ... done() }, 
  afterEnter: function (el){// ...},
  enterCancelled: function (el) {// ...},

  beforeLeave: function (el) {// ...},
  leave: function (el, done) {// ... done() }, 
  afterLeave: function (el) {// ...},
  leaveCancelled: function (el) {// ...}  # leaveCancelled 只用于 v-show 中
}

# 使用 Velocity.js 
  methods: {
    beforeEnter: function (el) {
      el.style.opacity = 0
      el.style.transformOrigin = 'left'
    },
    enter: function (el, done) {
      Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 })
      Velocity(el, { fontSize: '1em' }, { complete: done })
    },
    leave: function (el, done) {
      Velocity(el, { translateX: '15px', rotateZ: '50deg' }, { duration: 600 })
      Velocity(el, { rotateZ: '100deg' }, { loop: 2 })
      Velocity(el, {rotateZ: '45deg',translateY: '30px',translateX: '30px',opacity: 0}, { complete: done })
    }
  }
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

# 5.4 初始渲染的过渡

# 可以通过 appear 特性设置节点在初始渲染的过渡
<transition
  appear
  # 自定义 CSS 类名
  appear-class="custom-appear-class"
  appear-to-class="custom-appear-to-class"
  appear-active-class="custom-appear-active-class"
  # 自定义 JavaScript 钩子
  v-on:before-appear="customBeforeAppearHook"
  v-on:appear="customAppearHook"
  v-on:after-appear="customAfterAppearHook"
  v-on:appear-cancelled="customAppearCancelledHook"
>...</transition>
1
2
3
4
5
6
7
8
9
10
11
12
13

# 5.5 其他

多个元素的过渡:key 特性
过渡模式: mode="out-in" mode="in-out"
多个组件的过渡:使用动态组件
列表过渡:使用transition-group  组件
列表的排序过渡:v-move 特性
表的交错过渡:通过 data 属性与 JavaScript 通信
可复用的过渡:将 transition 或者 transition-group 作为根组件,然后将任何子组件放置在其中 
动态过渡:通过 name 特性来绑定动态值。 v-bind:name="transitionName"
1
2
3
4
5
6
7
8

# 5.6 状态过渡

对于据元素本身的动效:数字和运算、颜色的显示、SVG 节点的位置、元素的大小和其他的属性

# 使用第三方库来实现切换元素的过渡状态
数值:TweenMax.min.js
CSS的color值:Tween.js和Color.js
动态状态过渡
把过渡放到组件里
1
2
3
4
5
上次更新: 2021-05-10 14:08:54
JS图片上传前校验大小、尺寸
Vue教程(2)-路由篇Vue-Router

← JS图片上传前校验大小、尺寸 Vue教程(2)-路由篇Vue-Router→

最近更新
01
【uniapp】字节小程序BUG - “navigateToMiniProgram/getUserProfile:fail must be invoked by user tap gesture”
06-21
02
七牛云上传自有证书
04-27
03
使用腾讯云申请免费SSL证书
04-27
更多文章>
Theme by Vdoing | Copyright © 2020-2025 | 豫ICP备2020030395号 | 靳立祥 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式