Vue 组件化开发

这篇具有很好参考价值的文章主要介绍了Vue 组件化开发。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

提示:这里可以添加本文要记录的大概内容:

Vue.js 是一种现代化的前端框架,可以用于构建可复用的组件化应用程序。Vue.js 提供了一种基于组件的架构,使得开发人员可以将应用程序分解为多个可重用的组件。

Vue.js 组件是一个可复用的代码模块,可以在 Vue.js 应用程序中使用。组件包括 HTML 模板、JavaScript 代码和 CSS 样式,并且可以包含其他组件。

Vue.js 组件化开发的主要优势包括:

  1. 模块化:Vue.js 组件使得应用程序变得更易于管理和维护,可以将应用程序分解为多个小模块,每个模块都有自己的功能和样式。

  2. 可重用性:组件化开发使得开发人员可以编写可重用的代码片段,可以在不同的项目中使用,并且可以在同一应用程序中多次使用。

  3. 维护性:组件化开发使得代码更加模块化,更易于维护和测试。

  4. 性能:在 Vue.js 中使用组件可以提高应用程序的性能,因为它可以在需要时延迟加载组件。

总之,Vue.js 组件化开发是一种高效的方式,可以帮助开发人员构建可维护和可重用的应用程序。


提示:以下是本篇文章正文内容,下面案例可供参考

组件化开发

首先Ctrl+c 停止上面项目访问,新建一个项目
cd ..:返回上一级
Vue 组件化开发,前端,vue.js,前端,javascript

接下来就是把【创建Vue-Cli工程】的过程再来一遍:
完整过程:

  1. 新建文件夹【vue create 小写名字】vue create component 。component(组件化开发)
  2. 选择最后一个Manually select features
  3. 空格去掉倒数第三个( * ) Linter / Formatter
  4. 默认选择3.x
  5. 选择倒数第二个In package.json
  6. 不保存n

出现Successfully代表创建成功
Vue 组件化开发,前端,vue.js,前端,javascript
打开项目,进行一些默认操作:

①、用脚手架创建项目时,把脚手架生成的代码删除掉
Vue 组件化开发,前端,vue.js,前端,javascript
②、删除App.vue内所有代码,随后输入vue选择第一个
Vue 组件化开发,前端,vue.js,前端,javascript

在template标签中加代码:

    <h1>{{ title }}</h1>

在script标签中的data函数的返回对象加代码:

title:'我是根组件'

打开终端输入:npm run serve,就可以运行了
Vue 组件化开发,前端,vue.js,前端,javascript
components文件夹下新建个子组件TabMenu.vue,名字是驼峰式命名

生成基本结构,输入vue回车,加点代码与样式,这里可以随便写,主要是展示子组件的使用
Vue 组件化开发,前端,vue.js,前端,javascript
Vue 组件化开发,前端,vue.js,前端,javascript
现在一个根组件(App.vue),一个子组件(TabMenu.vue),运行:
Vue 组件化开发,前端,vue.js,前端,javascript

那么如何在根组件中使用子组件呢?

底部菜单 TabMenu

以App.vue根组件,TabMenu.vue子组件为例:文章来源地址https://www.toymoban.com/news/detail-552963.html

  1. 导入需要的子组件(在script标签内)
import TabMenu from '@/components/TabMenu.vue';  //@相当于src

或者写成:

import TabMenu from '../components/TabMenu.vue';

当然需要在components 文件夹下新建 TabMenu 视图:
Vue 组件化开发,前端,vue.js,前端,javascript
详细代码:

<!-- 定义组件的模板 -->
<template>
  <div>
    <!-- 底部选项卡 -->
    <ul class="tab-menu">
        <!-- 首页选项 -->
        <li @click="gotoIndex">
            <i class="fa fa-home"></i>
            <p>首页</p>
        </li>
        <!-- 发现选项 -->
        <li @click="gotoBusiness">
            <i class="fa fa-compass"></i>
            <p>发现</p>
        </li>
        <!-- 订单选项 -->
        <li @click="gotoMyOrders">
            <i class="fa fa-file-text-o"></i>
            <p>订单</p>
        </li>
        <!-- 我的选项 -->
        <li @click="gotoMy">
            <i class="fa fa-user-o"></i>
            <p>我的</p>
        </li>
    </ul>
  </div>
</template>

<script>
// 引入路由
import router from '@/router';

export default {
  data() {
    return {}
  },
  methods: {
    // 跳转到首页
    gotoIndex() {
      router.push('/')
    },
    // 跳转到个人中心
    gotoMy() {
      // 判断是否登录
      let login = sessionStorage.getItem('login')
      if (login == null) {
        // 未登录则跳转到登录页
        router.push('/login')
      } else{
        // 已登录则跳转到个人中心页
        router.push('/my')
      }
    },
    // 跳转到发现页
    gotoBusiness() {
      router.push('/business')
    },
    // 跳转到我的订单页
    gotoMyOrders() {
      router.push('/myOrders')
    }
  },
  components: {},
  computed: {},
  watch: {},
  mounted() {},
}
</script>

<style scoped>
  /* 底部选项卡样式 */
  .tab-menu{
    width: 100vw; /* 设置选项卡宽度为屏幕宽度 */
    height: 14vw; /* 设置选项卡高度为14vw */
    background-color: #fff; /* 设置选项卡背景色为白色 */
    border-top: 0.2vw solid #ddd; /* 设置选项卡上边框为0.2vw宽的灰色实线 */
    display: flex; /* 设置选项卡为弹性布局 */
    justify-content: space-around; /* 设置选项卡内子元素沿主轴间距相等 */
    align-items: center; /* 设置选项卡内子元素沿侧轴居中对齐 */
    position: fixed; /* 设置选项卡为固定定位 */
    left: 0; /* 设置选项卡距离左侧为0 */
    bottom: 0; /* 设置选项卡距离底部为0 */
  }
  /* 选项样式 */
  .tab-menu li{
    display: flex; /* 设置选项为弹性布局 */
    flex-direction: column; /* 设置选项内子元素排列方向为垂直方向 */
    justify-content: center; /* 设置选项内子元素沿主轴居中对齐 */
    align-items: center; /* 设置选项内子元素沿侧轴居中对齐 */
    color: #999; /* 设置选项内子元素颜色为灰色 */
  }
</style>
  1. 在 components 的配置项中注册子组件
components: {TabMenu},
  1. 在template中以标记的语法使用子组件
<TabMenu></TabMenu>  

Vue 组件化开发,前端,vue.js,前端,javascript
当然在命令行中运行上这句:npm i font-awesome

效果:
Vue 组件化开发,前端,vue.js,前端,javascript

父子组件相互传数据

在父子组件中如何让他俩可以相互发数据?

以App.vue根组件,Data.vue子组件为例:

父传子:自定义属性

先写先接受数据的一方

  1. 父给子传数据,先给子组件里面增加一个新个配置项props,自定义属性的意思

components文件中新建子组件Data.vue(script标签内)
vue生成基本结构后,增加props配置项

  // 数组形式,里面自定义名字
  props: ['test']
  1. 在template标签内加上插值语法把上面的自定义名字加上去
<template>
  <div>
    <h1>数据子组件</h1>
    <h1>这是父组件传递给我的数据:{{ test }}</h1>
  </div>
</template>
  1. 父组件中再导入该子组件(在script标签内)
import Data from '@/components/Data.vue'
  1. 在components的配置项中注册子组件
  components: {TabMenu,Data}, //TabMenu是另一个子组件,多个子组件用逗号隔开
  1. 在template中以标记的语法使用子组件
<Data></Data>

父组件App.vue中完整代码:

<template>
  <div>
    <h1>{{ title }}</h1>
    <!-- 3.在template中以标记的语法使用子组件 -->
    <TabMenu></TabMenu>
    <Data></Data>
  </div>
</template>

<script>
// 1.导入需要的子组件
import TabMenu from '@/components/TabMenu.vue';  
import Data from '@/components/Data.vue'
export default {
  data () {
    return {
      title:'我是根组件'
    }
  },
  methods: {

  },
  //2.在components的配置项中注册子组件
  components: {TabMenu,Data},  //TabMenu是另一个子组件,多个子组件用逗号隔开
  computed: {},
  watch: {},
  mounted () {}
}
</script>
<style scoped>
</style>

输出效果:
Vue 组件化开发,前端,vue.js,前端,javascript
但是现在里面还没有数据,因为在Data.vue中test是自定义属性

  1. 接下来在父组件中加入自定义属性
<Data test="你好啊"></Data>

Vue 组件化开发,前端,vue.js,前端,javascript

如果说要在子组件里再定义一个属性,父组件再传一个,只需要在相应位置加上属性后用逗号隔开即可

子组件中:
Vue 组件化开发,前端,vue.js,前端,javascript
Vue 组件化开发,前端,vue.js,前端,javascript
父组件中:
Vue 组件化开发,前端,vue.js,前端,javascript

子传父:自定义事件

recive():接收子给父传上来的数据,有参,代表传来的数据

在父组件中:

  1. 自定义一个事件,这里取名abc
    <Data test="你好啊" test1="世界" @abc = "recive"></Data>
  1. 在methods配置项中定义recive()函数方法
  methods: {
    recive(d){
      // d:代表子给父发的数据
      this.title = d   //更改title值
    }
  },

子组件中:

  1. 在子组件中编写一个函数,加入一个事件:
    Vue 组件化开发,前端,vue.js,前端,javascript

  2. 给v-model的属性tes在data函数的return里面配置一下

  3. methods内加上send方法

    send(){
        this.$emit('abc',this.text)
        //this.$emit('在父组件中配置的事件名字',this.发送给父组件的数据)
    }

Vue 组件化开发,前端,vue.js,前端,javascript
最后输出:
Vue 组件化开发,前端,vue.js,前端,javascript

父子组件互传案例

一个App父组件
两个子组件:一个添加待办事项组件、一个待办列表组件

如果之前有项目在终端开着先Ctrl+c关掉
然后新建一个待办项目:vue create todo,然后依次回车选择配置选项
然后进入到 todo 项目中,删掉HelloWorld.vue文件 和 App.vue中所有代码(输入vue重新生成)

在components文件夹中创建新子组件AddItem.vue 和 List.vue

在父组件中使用子组件:

  1. 导入需要的子组件
  2. 在components的配置项中注册子组件
  3. 在template中以标记的语法使用子组件

目前为止父组件中代码:

<template>
  <div>
    <h1>待办事项</h1>
    <!-- 3.使用 -->
    <AddItem></AddItem>
    <List></List>
  </div>
</template>

<script>
// 1. 导入
import AddItem from '@/components/AddItem.vue';
import List from '@/components/List.vue';
export default {
  data () {
    return {

    }
  },
  methods: {

  },
  // 2.注册
  components: {AddItem,List},
  computed: {},
  watch: {},
  mounted () {}
}
</script>
<style scoped>
</style>

接下来先把List待办列表弄出来再写待办事项,也就是写个父给子的数据传递
增加自定义的属性,使用 v-for 指令对 todolist 进行循环渲染,将 todolist 中的每个元素都显示为一个有序列表中的一条,{{ item }} 则是将前面 item 变量名插入到模板中进行渲染。

由于本组件需要从父组件中接收一个名为 todolist 的属性,所以使用 props 选项来声明了一个具名的 todolist 属性

最后加了点CSS样式

下面是完整的 List.vue 代码

<template>
  <div>
    <ul>
      <!-- 使用 v-for 指令遍历传入的 todolist 数据,生成 li 列表项 -->
      <li v-for="(item, index) in todolist" :key="index">{{ item }}</li>
                                    <!-- 2.使用插值语法把上面的自定义名字加上去 -->
    </ul>
  </div>
</template>

<script>
export default {
  // 1.定义一个 props 属性,接收父组件传递的 todolist 数据 (自定义的属性)
  props: ['todolist']
}
</script>

<style scoped>
/* 为 ul 列表设置样式 */
ul {
  list-style: none; /* 取消列表项的默认样式 */
  margin: 0; /* 去除外边距 */
  padding: 0; /* 去除内边距 */
  display: flex; /* 将列表项设为弹性项目 */
  flex-wrap: wrap; /* 当空间不足时,自动换行 */
}

/* 为 li 列表项设置样式 */
li {
  font-size: 1.2rem; /* 设置字体大小 */
  color: #333; /* 设置字体颜色 */
  background-color: #f5f5f5; /* 设置背景颜色 */
  border-radius: 5px; /* 设置圆角 */
  margin: 0.5rem; /* 设置外边距 */
  padding: 1rem; /* 设置内边距 */
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 0 12px rgba(0, 0, 0, 0.1); /* 设置阴影 */
  text-align: center; /* 设置文本居中 */
  transition: transform 0.2s cubic-bezier(0, 0, 0.2, 1), box-shadow 0.2s cubic-bezier(0, 0, 0.2, 1); /* 设置过渡效果 */
}

/* 当鼠标悬停在 li 列表项上时的样式 */
li:hover {
  transform: translateY(-5px);
  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.2), 0 0 12px rgba(0, 0, 0, 0.2);
}
</style>

第一步:在父组件data中把待办事项的数据定义出来

  data () {
    return {
      items: ['学习','做事','赚钱']
      // a.把items数据传给list组件去用,用属性todolist去传
    }
  },

第二步:用list组件动态绑定items数据

<List :todolist="items"></List>

最后父组件中完整代码

<template>
  <div>
    <h1>待办事项</h1>
    <!-- 3.使用 -->
    <AddItem></AddItem>
    <!-- b.list组件 加上冒号是动态绑定items数据-->
    <List :todolist="items"></List>
  </div>
</template>

<script>
// 1. 导入
import AddItem from '@/components/AddItem.vue';
import List from '@/components/List.vue';
export default {
  data () {
    return {
      items: ['学习','做事','赚钱']
      // a.把items数据传给list组件去用,用属性todolist去传
    }
  },
  methods: {

  },
  // 2.注册
  components: {AddItem,List},
  computed: {},
  watch: {},
  mounted () {}
}
</script>
<style scoped>
</style>

现在打开终端进入该项目路径下启动该项目:npm run serve
启动后运行
Vue 组件化开发,前端,vue.js,前端,javascript
接下来是子给父传数据
第一步:加上自定义事件
第二步:放在methods,接受要带参数

<!-- 第一步:自定义事件 -->
<AddItem @item="recive"></AddItem> 
...
//中间代码胜率
...
  methods: {
    // 第二步:放在methods,接受的话要带参数
    recive(d){
      this.items.unshift(d)  
    }
  },

父组件中完整代码是:

<template>
  <div>
    <h1>待办事项</h1>
    <!-- 3.使用 -->
    <!-- 第一步:自定义事件 -->
    <AddItem @item="recive"></AddItem> 
    <!-- b.list组件 加上冒号是动态绑定items数据-->
    <List :todolist="items"></List>
  </div>
</template>

<script>
// 1. 导入
import AddItem from '@/components/AddItem.vue';
import List from '@/components/List.vue';
export default {
  data () {
    return {
      items: ['学习','做事','赚钱']
      // a.把items数据传给list组件去用,用属性todolist去传
    }
  },
  methods: {
    // 第二步:放在methods,接受的话要带参数
    recive(d){
      this.items.unshift(d)  
    }
  },
  // 2.注册
  components: {AddItem,List},
  computed: {},
  watch: {},
  mounted () {}
}
</script>
<style scoped>
</style>

下一步到子组件AddItem.vue里面

1:在里面加一个输入框和按钮

    <input type="text" v-model="item">
    <button @click="send">添加</button>

2:data里面配数据

  data () {
    return {
      item: ''
    }
  },

3:在methods里把数据发送给父组件

  methods: {
    send(){
      this.$emit('item,this.item')
    }
  },

然后在给css内加点样式

最后AddItem.vue完整代码

<template>
  <div class="input-container"> <!-- 输入框容器 -->
    <input type="text" v-model="item" placeholder="输入待办事项" class="input-field"> <!-- 输入框 -->
    <button @click="send" class="add-btn">添加</button> <!-- 添加按钮 -->
  </div>
</template>

<script>
export default {
  data () {
    return {
      item: '' // 输入框绑定的数据
    }
  },
  methods: {
    send(){
      this.$emit('item',this.item) // 发出事件,传递输入框数据
    }
  },
}
</script>

<style scoped>
.input-container { /* 输入框容器样式 */
  display: flex; /* flex 布局 */
  align-items: center; /* 垂直居中 */
  margin-bottom: 20px; /* 底部外边距 */
}

.input-field { /* 输入框样式 */
  border: none; /* 取消边框 */
  border-bottom: 2px solid #aaa; /* 底部边框 */
  padding: 0.5rem; /* 内边距 */
  margin-right: 1rem; /* 右外边距 */
  font-size: 1rem; /* 字体大小 */
  font-family: Arial, sans-serif; /* 字体样式 */
  width: 300px; /* 宽度 */
}

.add-btn { /* 添加按钮样式 */
  background-color: #20A3FF; /* 背景颜色 */
  border: none; /* 取消边框 */
  color: white; /* 字体颜色 */
  padding: 0.5rem; /* 内边距 */
  border-radius: 5px; /* 圆角 */
  cursor: pointer; /* 鼠标样式 */
  transition: all 0.3s ease; /* 过渡效果 */
  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.3); /* 阴影 */
}

.add-btn:hover { /* 鼠标悬停样式 */
  background-color: #2186e2;
  transform: translateY(-2px); /* 上移 */
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3); /* 增加阴影 */
}

.input-field:focus { /* 输入框获得焦点时的样式 */
  outline: none; /* 取消选中时的边框 */
  border-bottom: 2px solid #2186e2; /* 底部边框颜色更改 */
}
</style>

输出效果:
Vue 组件化开发,前端,vue.js,前端,javascript

插槽 slot

新建子组件Slot.vue,用vue生成格式后在HTML位置输入

<template>
  <div>
    <h1>我是插槽子组件</h1>
    <!-- 插槽位置 -->
    <slot></slot>
  </div>
</template>

在父组件App.vue中在相应位置进行导入、注册、使用(可以新建一个项目,看起来更直观)

import Slot from '@/components/Slot.vue';

  components: {Slot},

    <Slot>
      <h1>你好</h1>
      <!-- 将会显示在子组件的Slot插槽位置上 -->
    </Slot>

运行项目:
Vue 组件化开发,前端,vue.js,前端,javascript

多个插槽

通过名字区分

比如在子组件中再加一个slot标签加个名字

<slot name="a"></slot>

在父组件中加上template v-slot:a

    <Slot>
      <!-- 将会显示在子组件的Slot插槽位置上 -->
      <h1>你好</h1>
      <!-- 通过名字单独指令子组件的Slot插槽位置 -->
      <template v-slot:a>
        <h2>hello</h2>
      </template>
    </Slot>

另外在css位置加了点样式(可以忽略)
Vue 组件化开发,前端,vue.js,前端,javascript

总结

组件化开发总结

Vue组件的基本组成

  1. template——模版 html代码
  2. script——脚本 vue配置对象中的各种配置项
  3. style——样式 css代码

子组件使用的三个步骤

  1. 在父组件中导入所需子组件
  2. 在父组件的配置对象中的components配置项中注册子组件
  3. 在父组件的template中以标记的语法使用子组件

父子组件相互传递数据

  1. 父传子
    a.在子组件配置对象中增加props配置项(自定义属性)
    b.在父组件使用子组件时通过自定义的属性名传数据

  2. 子传父
    a.在父组件中增加自定义事件,并编写接受数据的方法 【@item=“recive”】
    b.在子组件中增加一个发送数据的方法,调用this.$emit(‘自定义的事件名’,发送的数据)

那么如何在根组件中使用子组件呢?

以App.vue根组件,TabMenu.vue子组件为例:

  1. 导入需要的子组件(在script标签内)
import TabMenu from '@/components/TabMenu.vue';  //@相当于src
  1. 在components的配置项中注册子组件
components: {TabMenu},
  1. 在template中以标记的语法使用子组件
<TabMenu></TabMenu>  

到了这里,关于Vue 组件化开发的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【vue2第九章】组件化开发和根组件以及style上的scoped作用

    组件化开发和根组件 什么是组件化开发? 一个页面可以拆分为多个组件,每个组件有自己的 样式,结构,行为 ,组件化开发的好处就是,便于维护,利于重复利用,提升开发的效率。 便于维护 :页面中块出了问题,可以直接去找到这个组件,修改组件的样式逻辑结构。

    2024年02月10日
    浏览(32)
  • 低代码开发之vue.draggable的使用(进阶:组件化拖拽生成功能页面)

    效果展示: 前言:随着各公司定制化需求的不断攀升,公司对低代码、组态化的开发需求日渐迫切。也许是研发任务节点将至,也许是为顺应时代潮流,我也是去学习并实践了一番。如图所示。 功能简介: 左侧组件区域特意做了选中态,小眼睛预览浮框态等交互,右侧内容区

    2024年03月23日
    浏览(35)
  • 低代码开发之vue.draggable的使用(初阶:组件化拖拽生成简单页面)

    效果展示 vue.draggable 安装 使用 vue.draggable 相关属性 事件 Demo完整代码 更多详见draggable官网=https://www.itxst.com/vue-draggable/tutorial.html

    2024年02月19日
    浏览(26)
  • 二、Vue组件化编程

    Vue 中使用组件的三大步骤: 定义组件(创建组件) 注册组件 使用组件(写组件标签) 如何定义一个组件? 使用 Vue.extend(options) 创建,其中 options 和 new Vue(options) 时传入的那个 options 几乎一样,但也有点区别; 区别如下: el 不要写,为什么? ——— 最终所有的组件都要经过一

    2024年02月22日
    浏览(32)
  • VUE3 --->组件化

    目录 vue-cli 1、基于 vue ui 创建 vue 项目  组件库 1.vue 组件库 2.vue 组件库和 bootstrap 的区别 3. 最常用的 vue 组件库 4. Element UI axios 拦截器 1. 回顾:在 vue3 的项目中全局配置 axios 2. 在 vue2 的项目中全局配置 axios 3、拦截器 4. 配置请求拦截器 5、配置响应拦截器 proxy 跨域代理 1. 回

    2024年02月15日
    浏览(30)
  • Vue(组件化编程:非单文件组件、单文件组件)

    传统组件编写:不同的HTML引入不同的样式和行为文件 组件方式编写:组件单独, 复用率高(前提组件拆分十分细致)  理解为封装行为:html,css,js封装在一个文件中 解释模块化和组件化的区别: 组件化 :css,js,html三件套使用在同一部分的代码封装在一个组件中 模块化

    2024年02月01日
    浏览(40)
  • 通用vue组件化登录页面

    1.首先建立一个login文件夹,在里面建立对应的login.vue文件 2.设置登录页面的背景图,在App.vue文件中使用router-view进行展示登录组件 3.先给App.vue的div元素设置高度100%,之后在login.vue里面去设置背景图 这里注意怎么使login组件垂直水平居中的样式 1.首先建立一个cpns的文件夹,里

    2024年02月09日
    浏览(29)
  • 【前端知识】React 基础巩固(十九)——组件化开发(三)

    Main.jsx TabControl/index.jsx TabControl/style.css

    2024年02月13日
    浏览(35)
  • 【前端知识】React 基础巩固(十七)——组件化开发(一)

    什么是组件化开发? 分而治之的思想 将一个页面拆分成一个个小的功能块 将应用抽象成一颗组件树 React的组件相对于Vue更加的灵活和多样 按照不同的方式可以分为很多类组件 根据 组件的定义方式 ,分为: 函数组件 、 类组件 根据 组件内部是否有状态需要维护 ,分为:

    2024年02月12日
    浏览(51)
  • Vue 如何简单快速组件化

    为了简化拆分复杂的代码逻辑,和实现代码的组件化,封闭化。我们需要使用组件化的方法。我这里只讲解我感觉最优的组件化方法。 vue组件化总结 vue 单文件组件 子组件修改Props报错 vue 父组件调用子组件方法ref vue中组件的props属性(详) 使用Vue-cil搭建一个简单的Vue页面,

    2024年02月12日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包