Vue零基础教程|从前端框架到GIS开发系列课程(五)组件式开发

Party1

简介

1) 什么是组件

组件可以理解成项目的零件

项目 就是由多个 组件 构成的

举例

  • 一个房子是一个Vue应用, 那么客厅/卧室/厨房/卫生间就是组件

  • 一个电脑是一个Vue应用, 那么硬盘/内存/主板/显示器/键盘就是组件

组件化思想

2) 为什么需要组件

将逻辑相近的功能模块封装到一起. 方便复用

示例

复制代码
<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <script src="../node_modules/vue/dist/vue.global.js"></script>  </head>  <body>    <div id="app">      <!-- 文章一 -->      <div class="blog-item">        <h3>{{title}}</h3>        <div>{{content}}</div>      </div>
      <!-- 文章二 -->      <div class="blog-item">        <h3>{{title}}</h3>        <div>{{content}}</div>      </div>
      <!-- 文章三 -->      <div class="blog-item">        <h3>{{title}}</h3>        <div>{{content}}</div>      </div>    </div>
    <script>      const { createApp } = Vue
      const vm = createApp({        data() {          return {            title: '文章标题',            content: '文章内容',          }        },      }).mount('#app')</script>  </body></html>

如果要使用组件需要先注册. 从注册的方式不同

可以将组件分为

  • 全局组件

  • 局部组件

3) 全局组件

顾名思义, 全局都可以使用的组件, 组件在当前 Vue 应用中全局可用

语法​​​​​​​

复制代码
// 可以使用 Vue 应用实例的 app.component() 方法
import { createApp } from 'vue'
const app = createApp({})
app.component(  // 注册的名字  'MyComponent',  // 组件的配置对象  {    /* ... */  })

组件对象中的配置项和createApp中的配置项一致

什么是当前Vue应用

每次调用createApp会创建一个新的Vue应用. 不同的Vue应用实例有自己的空间. 不能跨应用引用组件​​​​​​​

复制代码
const app = createApp({}) // 创建一个应用实例const app1 = createApp({}) // 创建一个新的应用实例
console.log(app === app1) //false// 在app中注册的组件, 不能在app1中使用

🤔为什么data是一个函数?

每个实例可以维护一份被返回对象的独立的拷贝:​​​​​​​

复制代码
data: function () {  return {    count: 0  }}

如果 Vue 没有这条规则,点击一个按钮就会影响到其它所有实例!

示例​​​​​​​

复制代码
<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <meta http-equiv="X-UA-Compatible" content="IE=edge">  <meta name="viewport" content="width=device-width, initial-scale=1.0">  <title>Document</title>  <script src="../node_modules/vue/dist/vue.global.js"></script><body>  <div id="app">    <counter></counter>    <counter></counter>    <counter></counter>  </div>  <script>    const {createApp} = Vue    const app = createApp({})
    // 定义组件    app.component('counter', {      template: '<button @click="count++">点击了{{count}}次</button>',      data() {        return {          count: 0        }      }    })    app.mount('#app')</script></body></html>

引用

在模板中, 通过组件名称引用组件

复制代码
<blog-item></blog-item>

注意事项

  1. 命名原则

  2. 闭合方式

  3. 引用位置

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../node_modules/vue/dist/vue.global.js"></script><body>
    <my-button></my-button>
    <script> const {createApp} = Vue const app = createApp({})
    复制代码
     // 定义组件    // 一. 组件名称    //    1. 组件名不能是HTML原生的标签名    //    2. 组件名尽量使用多个单词, 多个单词之间使用-连接(kebab-case)    //    3. 组件名尽量使用PascalCase(驼峰法)    // 二. 组件引用    //    1. 在不使用构建工具的情况下, 由于HTML不区分大小写, 所以在模板中不能使用PascalCase来引用组件    //    2. 组件使用双标签形式    //    3. 组件不要在ul.ol,table,select内部直接使用    app.component('MyButton', {      template: '<button @click="count++">点击了{{count}}次</button>',      data() {        return {          count: 0        }      }    })    app.mount('#app')</script></body></html>

4) 局部组件

语法

使用components选项​​​​​​​

复制代码
<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <script src="../node_modules/vue/dist/vue.global.js"></script>  </head>  <body>    <!-- 根组件解析的模板 -->    <div id="app">      <!-- 局部组件只能在当前组件的模板中引用 -->      <first-com></first-com>      <second-com></second-com>    </div>
    <script>      const { createApp } = Vue
      // 参数{}: 根组件配置对象      const app = createApp({        // 定义根组件下的子组件        components: {          // 组件名: 组件配置对象          FirstCom: {            template: `<div>FirstCom</div>`,          },          SecondCom: {            template: `<div>SecondCom</div>`,          },        },      })
      app.mount('#app')</script>  </body></html>

如何理解局部

局部注册的组件在 后代组件 不可用 , 只能在当前组件的模板中引用

示例​​​​​​​

复制代码
<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <script src="../node_modules/vue/dist/vue.global.js"></script>  </head>  <body>    <!-- 根组件解析的模板 -->    <div id="app">      <!-- 局部组件只能在当前组件的模板中引用 -->      <first-com></first-com>      <second-com></second-com>    </div>
    <script>      const { createApp } = Vue
      // 参数{}: 根组件配置对象      // 在当前组件的配置项中定义的组件只能在当前组件对应的模板中使用      const app = createApp({        // 定义根组件下的子组件        components: {          // 组件名: 组件配置对象          FirstCom: {            template: `<div>              不能在FirstCom组件的模板中引用父组件配置对象中定义的组件              <second-com></second-com>            </div>`,          },          SecondCom: {            template: `<div>SecondCom</div>`,          },        },      })
      // const app = createApp({})
      // app      //   .component('FirstCom', {      //     template: `<div>      //     FirstCom      //     -- <second-com></second-com>      //     </div>`,      //   })      //   .component('SecondCom', {      //     template: '<div>SecondCom</div>',      //   })
      app.mount('#app')</script>  </body></html>

Party2

父子组件间通信(重点掌握)

1) 为什么需要通信

场景

父组件Root, 子组件为BlogItem

每一篇blog的标题都不同. 子组件只能决定结构和样式. 具体的数据要变化, 需要父组件通知​​​​​​​

复制代码
<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <script src="../node_modules/vue/dist/vue.global.js"></script>  </head>  <body>    <div id="app">      <!-- 1. 在父组件的模板中, 通过自定义属性传值 -->      <blog-item title="Vue深入浅出"></blog-item>      <blog-item :title="msg"></blog-item>      <blog-item title="Vue的最佳实践"></blog-item>    </div>
    <script>      const { createApp } = Vue
      // 父组件: 确定数据      const vm = createApp({        data() {          return {            msg: 'Vue的设计与实现',          }        },        components: {          // 子组件定义: 确定结构和样式          BlogItem: {            // 在子组件的配置项中, 通过props接收            props: ['title'],            template: `              <div>                <h3>{{title}}</h3>                <p>内容</p>              </div>            `,          },        },      }).mount('#app')</script>  </body></html>

2) 父传子

通过子组件的自定义属性

  1. 在父组件模板中, 设置自定义属性

  2. 在子组件选项中, 通过props接收

示例

父组件:​​​​​​​

复制代码
<!-- 在父组件的模板中, 设置自定义属性 --><blog-item title="Vue深入浅出"></blog-item><!-- 在父组件的模板中, 绑定自定义属性 --><blog-item :title="msg"></blog-item>

子组件对象:​​​​​​​

复制代码
{  // 在子组件的配置项中, 通过props接收  props: ['title'],  template: `    <div>      <h3>{{title}}</h3>      <p>内容</p>    </div>  `,},

3) 子传父

借助子组件的中自定义事件

  1. 在子组件中, 触发自定义事件

  2. 在父组件中, 监听自定义事件

示例​​​​​​​

复制代码
<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <script src="../node_modules/vue/dist/vue.global.js"></script>  </head>  <body>    <div id="app">      <!-- 1. 在父组件的模板中, 通过自定义属性传值 -->      <blog-item title="Vue深入浅出"></blog-item>      <blog-item :title="msg"></blog-item>      <!-- 2. 在父组件的模板, 监听自定义事件 -->      <blog-item v-if="show" title="Vue的最佳实践" @close="handleClose"></blog-item>    </div>
    <script>      const { createApp } = Vue
      // 父组件: 确定数据      const vm = createApp({        data() {          return {            msg: 'Vue的设计与实现',            show: true,          }        },        methods: {          handleClose(i) {            this.show = false            console.log(i)          },        },        components: {          // 子组件定义: 确定结构和样式          BlogItem: {            // 在子组件的配置项中, 通过props接收            props: ['title'],            template: `              <div>                <h3>{{title}}</h3>                <p>内容</p>                // 1. 在子组件中触发一个自定义事件                <button @click="$emit('close', 1)">关闭</button>              </div>            `,          },        },      }).mount('#app')</script>  </body></html>

动态组件

渲染的组件是动态生成, 根据不同的状态渲染不同的组件

踢踢备注:《Vue零基础教程》

相关推荐
涔溪6 小时前
实现将 Vue2 子应用通过无界(Wujie)微前端框架接入到 Vue3 主应用中(即 Vue3 主应用集成 Vue2 子应用)
vue.js·微前端·wujie
IT_陈寒6 小时前
Redis性能翻倍的5个冷门技巧,90%开发者都不知道第3个!
前端·人工智能·后端
T***u3337 小时前
前端框架在性能优化中的实践
javascript·vue.js·前端框架
jingling5558 小时前
vue | 在 Vue 3 项目中集成高德地图(AMap)
前端·javascript·vue.js
油丶酸萝卜别吃8 小时前
Vue3 中如何在 setup 语法糖下,通过 Layer 弹窗组件弹出自定义 Vue 组件?
前端·vue.js·arcgis
J***Q29214 小时前
Vue数据可视化
前端·vue.js·信息可视化
JIngJaneIL15 小时前
社区互助|社区交易|基于springboot+vue的社区互助交易系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·社区互助
ttod_qzstudio16 小时前
深入理解 Vue 3 的 h 函数:构建动态 UI 的利器
前端·vue.js
_大龄16 小时前
前端解析excel
前端·excel
1***s63216 小时前
Vue图像处理开发
javascript·vue.js·ecmascript