03、vue2.x组件快速入门

简介: 03、vue2.x组件快速入门

文章目录


1. 基础

1.1 组件的命名

定义组件名的方式有两种:

使用 kebab-case

Vue.component('my-component-name', { /* ... */ })

当使用 kebab-case (短横线分隔命名) 定义一个组件时,你也必须在引用这个自定义元素时使用 kebab-case,例如 <my-component-name>

使用 PascalCase

Vue.component('MyComponentName', { /* ... */ })

当使用 PascalCase (首字母大写命名) 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。也就是说 <my-component-name><MyComponentName> 都是可接受的。注意,尽管如此,直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的。

组件名应该始终是多个单词的,根组件 App 以及 <transition><component> 之类的 Vue 内置组件除外。

这样做可以避免跟现有的以及未来的 HTML 元素相冲突,因为所有的 HTML 元素名称都是单个单词的。

1.2 为什么组件的data必须是一个函数,而不能是一个对象

因为使用vue-cli构建工程文件来测试的时候,如果组件的data不是一个函数会报错,所以我们使用html单文件来测试。

但是很不幸的是,我们使用html来渲染也被报错了

  • 报错代码
<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
  <div id="app">
    <h1>函数data</h1>
    <func-add > </func-add>
    <func-add></func-add>
    <hr />
    <h1>对象data</h1>
    <obj-add > </obj-add>
    <obj-add></obj-add>
    <hr />
  </div>
  <div id="app2"></div>
  <script>
    Vue.component('func-add',{
      data(){
        return {
          num:1
        }
      },
      template:`<button @click='num++'>{{num1}}</button>`
    })
    Vue.component('obj-add', {
      data:{
        num1: 1
      },
      template:`<button @click='num1++'>{{num1}}</button>`
    })
    const vm = new Vue({
      el:'#app',
    })
  </script>
</body>
</html>

data 的值是一个对象时,它会在这个组件的所有实例之间共享。想象一下,假如一个 TodoList 组件的数据是这样的:

data: {
  listTitle: '',
  todos: []
}

因为每个组件的实例都引用了相同的数据对象,更改其中一个列表的标题就会改变其它每一个列表的标题。增删改一个待办事项的时候也是如此。

取而代之的是,我们希望每个组件实例都管理其自己的数据。为了做到这一点,每个实例必须生成一个独立的数据对象。在 JavaScript 中,在一个函数中返回这个对象就可以了:

data: function () {
  return {
    listTitle: '',
    todos: []
  }
}

1.3 组件props的推荐用法

Prop 定义应该尽量详细。

在你提交的代码中,prop 的定义应该尽量详细,至少需要指定其类型。

详解

细致的 prop 定义有两个好处:

  • 它们写明了组件的 API,所以很容易看懂组件的用法;
  • 在开发环境下,如果向一个组件提供格式不正确的 prop,Vue 将会告警,以帮助你捕获潜在的错误来源。

好例子

props: {
  status: String
}
// 更好的做法!
props: {
  status: {
    type: String,
    required: true,
    validator: function (value) {
      return [
        'syncing',
        'synced',
        'version-conflict',
        'error'
      ].indexOf(value) !== -1
    }
  }
}

1.4 事件的使用

不同于组件和 prop,事件名不存在任何自动化的大小写转换。而是触发的事件名需要完全匹配监听这个事件所用的名称。

1.5 v-model的实现原理

v-model实质上是v-bindv-on:input的结合语法糖

<template>
  <div class="main">
    <h1>使用v-model</h1>
    <input v-model='name' />
    <h1>不使用v-model</h1>
    <input :value='name1' @input='change' />
  </div>
</template>
<script>
export default {
name:'VModel',
data(){
  return {
    name:'默认名字',
    name1:'默认名字'
  }
},
methods:{
  change(e){
    console.log('发生变化', e)
    if(e.inputType === 'insertText'){
      console.log('插入',e.data)
      this.name1 += e.data
    }else{
      console.log('删除')
      let s = this.name1
      this.name1 = s.substring(0, s.length-1)
    }
  }
},
// 监听属性的变化
watch:{
name(n, o){
  console.log(`v-model导致name从--${o}--变化为--${n}--`)
},
name1(n,o){
  console.log(`模拟v-model导致name从--${o}--变化为--${n}--`)
}
}
}
</script>

1.6 插槽

插槽分类

  1. 具名插槽
  2. 默认插槽
  3. slot-scope vue 2.6+已废弃

父组件

<template>
  <div class="main">
    <center><h1>插槽</h1></center>
    <hr />
    <child>
      <!-- <div v-slot:myheader>标题</div> -->
      <!-- v-slot必须在tempalte标签中使用,不然会发生错误,如上行就是错误代码 -->
      <!-- 具名插槽 -->
      <template v-slot:myheader>
        <div id='world'>父组件插入头部</div>
      </template>
      <template>默认</template>
      <div>hello</div>
      <!-- 具名插槽的简写 -->
      <template #footer>
        <center id='hello'>{{footer}}</center>
      </template>
    </child>
  </div>
</template>
<script>
import child from './child.vue'
export default {
name:'slotParent',
components:{
  child
},
data(){
  return {
    footer:'我是父组件的脚注'
  }
}
}
</script>
<style scoped>
#world{
  color:aqua;
}
</style>
<style  >
#hello{
  color:red;
}
</style>

子组件

<template>
  <div class="main">
    <header>
      <center>头部插槽</center>
      <slot name='myheader' />
      <hr />
    </header>
    <main>
      <center>默认插槽</center>
      <slot  />
      <hr />
    </main>
    <footer>
      <center>脚部插槽</center>
      <slot name='footer' />
    </footer>
  </div>
</template>
<script>
export default {
name:'slotChild'
}
</script>
<style>
</style>

2. [动态组件](动态组件 & 异步组件 — Vue.js (vuejs.org))

希望某些标签的组件实例能够被在它们第一次被创建的时候缓存下来。为了解决这个问题,我们可以用一个 <keep-alive> 元素将其动态组件包裹起来。

<!-- 失活的组件将会被缓存!-->
<keep-alive>
  <component v-bind:is="currentTabComponent"></component>
</keep-alive>

3. 异步组件

通常用于路由中

component: ()=>import('./test.vue')

4. 组件使用常见问题

1. 为什么下面的代码只渲染了一个func-add组件,而且蓝色圈部分的代码失效?

<!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="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
  <div id="app">
    <h1>函数data</h1>
    <func-add  />
    <hr />
    <br />
    <func-add  />
  </div>
  <div id="app2"></div>
  <script>
    Vue.component('func-add',{
      props:['data'],
      data(){
        return {
          num:1
        }
      },
      template:`<button @click='num++'>{{num}}</button>`
    })
    const vm = new Vue({
      el:'#app',
    })
  </script>
</body>
</html>

但是把组件的名字改成<func-add></func-add>又可以正常显示。

答案:【[参考Vue的风格指南](风格指南 — Vue.js (vuejs.org))】


2. 同一个组件的template代码属于同一个Vue实例

  • 结果表明
相关文章
|
3月前
|
JavaScript
Vue中如何实现兄弟组件之间的通信
在Vue中,兄弟组件可通过父组件中转、事件总线、Vuex/Pinia或provide/inject实现通信。小型项目推荐父组件中转或事件总线,大型项目建议使用Pinia等状态管理工具,确保数据流清晰可控,避免内存泄漏。
327 2
|
6月前
|
人工智能 JavaScript 算法
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
814 0
|
8月前
|
JavaScript
vue实现任务周期cron表达式选择组件
vue实现任务周期cron表达式选择组件
1046 4
|
6月前
|
JavaScript UED
用组件懒加载优化Vue应用性能
用组件懒加载优化Vue应用性能
|
6月前
|
JavaScript 前端开发 UED
Vue 表情包输入组件的实现代码:支持自定义表情库、快捷键发送和输入框联动的聊天表情解决方案
本文详细介绍了在 Vue 项目中实现一个功能完善、交互友好的表情包输入组件的方法,并提供了具体的应用实例。组件设计包含表情分类展示、响应式布局、与输入框的交互及样式定制等功能。通过核心技术实现,如将表情插入输入框光标位置和点击外部关闭选择器,确保用户体验流畅。同时探讨了性能优化策略,如懒加载和虚拟滚动,以及扩展性方案,如自定义主题和国际化支持。最终,展示了如何在聊天界面中集成该组件,为用户提供丰富的表情输入体验。
512 8
|
6月前
|
JavaScript 前端开发 UED
Vue 表情包输入组件实现代码及详细开发流程解析
这是一篇关于 Vue 表情包输入组件的使用方法与封装指南的文章。通过安装依赖、全局注册和局部使用,可以快速集成表情包功能到 Vue 项目中。文章还详细介绍了组件的封装实现、高级配置(如自定义表情列表、主题定制、动画效果和懒加载)以及完整集成示例。开发者可根据需求扩展功能,例如 GIF 搜索或自定义表情上传,提升用户体验。资源链接提供进一步学习材料。
289 1
|
8月前
|
存储 JavaScript 前端开发
基于 ant-design-vue 和 Vue 3 封装的功能强大的表格组件
VTable 是一个基于 ant-design-vue 和 Vue 3 的多功能表格组件,支持列自定义、排序、本地化存储、行选择等功能。它继承了 Ant-Design-Vue Table 的所有特性并加以扩展,提供开箱即用的高性能体验。示例包括基础表格、可选择表格和自定义列渲染等。
649 6
|
6月前
|
JavaScript 前端开发 UED
Vue 项目中如何自定义实用的进度条组件
本文介绍了如何使用Vue.js创建一个灵活多样的自定义进度条组件。该组件可接受进度段数据数组作为输入,动态渲染进度段,支持动画效果和内容展示。当进度超出总长时,超出部分将以红色填充。文章详细描述了组件的设计目标、实现步骤(包括props定义、宽度计算、模板渲染、动画处理及超出部分的显示),并提供了使用示例。通过此组件,开发者可根据项目需求灵活展示进度情况,优化用户体验。资源地址:[https://pan.quark.cn/s/35324205c62b](https://pan.quark.cn/s/35324205c62b)。
273 0
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
586 161
|
JavaScript
在 Vue 3 中,如何使用 v-model 来处理自定义组件的双向数据绑定?
需要注意的是,在实际开发中,根据具体的业务需求和组件设计,可能需要对上述步骤进行适当的调整和优化,以确保双向数据绑定的正确性和稳定性。同时,深入理解 Vue 3 的响应式机制和组件通信原理,将有助于更好地运用 `v-model` 实现自定义组件的双向数据绑定。
837 159