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零基础教程》

相关推荐
树上有只程序猿29 分钟前
年底了公司要裁员,大家还好吗?
前端·后端
问道飞鱼1 小时前
【前端知识】Javascript进阶-类和继承
开发语言·前端·javascript·继承·
Grocery store owner1 小时前
el-time-picker选择时分秒并且根据总秒数禁用不可选
前端·javascript·vue.js
川石教育1 小时前
Vue前端开发-axios默认配置和响应结构
前端·javascript·vue.js
半吊子全栈工匠1 小时前
WEB语义化的新探索:浅析LLMs.txt
前端·搜索引擎
JackieDYH2 小时前
Vue3中页面滑到最下面,然后跳转新页面后新页面的位置还是在之前浏览的位置
前端·javascript·html
正小安2 小时前
vue3实现ai聊天对话框
前端·javascript·vue.js·elementui
长风清留扬2 小时前
小程序开发中的插件生态与应用-上
前端·javascript·css·微信小程序·小程序·apache
JSCON简时空2 小时前
还没下雪嘛?等不及了,自己整个 3D 雪地写写字!
前端·react.js·three.js