Vue3 组件化开发

发布于:2025-08-10 ⋅ 阅读:(17) ⋅ 点赞:(0)


前言

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

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-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代表创建成功
在这里插入图片描述
打开项目,进行一些默认操作:

①、用脚手架创建项目时,把脚手架生成的代码删除掉
在这里插入图片描述
②、删除App.vue内所有代码,随后输入vue选择第一个
在这里插入图片描述

在template标签中加代码:

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

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

title:'我是根组件'

打开终端输入:npm run serve,就可以运行了
在这里插入图片描述
components文件夹下新建个子组件TabMenu.vue,名字是驼峰式命名

生成基本结构,输入vue回车,加点代码与样式,这里可以随便写,主要是展示子组件的使用
在这里插入图片描述
在这里插入图片描述
现在一个根组件(App.vue),一个子组件(TabMenu.vue),运行:
在这里插入图片描述

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

底部菜单 TabMenu

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

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

或者写成:

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

当然需要在components 文件夹下新建 TabMenu 视图:
在这里插入图片描述
详细代码:

<!-- 定义组件的模板 -->
<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>  

在这里插入图片描述
当然在命令行中运行上这句:npm i font-awesome

效果:
在这里插入图片描述

父子组件相互传数据

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

以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>

输出效果:
在这里插入图片描述
但是现在里面还没有数据,因为在Data.vue中test是自定义属性

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

在这里插入图片描述

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

子组件中:
在这里插入图片描述
在这里插入图片描述
父组件中:
在这里插入图片描述

子传父:自定义事件

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

在父组件中:

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

子组件中:

  1. 在子组件中编写一个函数,加入一个事件:
    在这里插入图片描述

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

  3. methods内加上send方法

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

在这里插入图片描述
最后输出:
在这里插入图片描述

父子组件互传案例

一个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
启动后运行
在这里插入图片描述
接下来是子给父传数据
第一步:加上自定义事件
第二步:放在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>

输出效果:
请添加图片描述

插槽 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>

运行项目:
在这里插入图片描述

多个插槽

通过名字区分

比如在子组件中再加一个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组件的基本组成

  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>  

网站公告

今日签到

点亮在社区的每一天
去签到