Vue(六)封装组件、组件化开发、组件间传值

举报
敬 之 发表于 2022/04/16 03:03:28 2022/04/16
【摘要】 目录 一、组件    1. 封装组件 2. 组件原理 二、组件化开发 1. 组件的使用过程 2. 组件分类(vue三大组件) 3. 组件间传值——父给子传值 一、组件           ...

目录

一、组件   

1. 封装组件

2. 组件原理

二、组件化开发

1. 组件的使用过程

2. 组件分类(vue三大组件)

3. 组件间传值——父给子传值


一、组件   

        组件是拥有专属的 HTML+JS+CSS+数据 的可重用的独立的页面功能区域,如果发现网页中有一个功能,可能被多处反复使用,都应封装为组件。

1. 封装组件

(1)创建一个组件


  
  1. Vue.component("组件名",{
  2. template:`组件的HTML片段`,
  3. data(){
  4. return { //相当于之前的data
  5. 模型变量:值,
  6. ... ...
  7. }
  8. },
  9. //注意:
  10. //组件中不再有el:"#app",而是用template:``代替
  11. //data不再写对象格式,而是写为函数格式且必须return一个新对象{}
  12. //HTML片段仍需写在唯一的父元素中

(2)在页面中使用组件


  
  1. <组件名></组件名>
  2. <!-- 每个自定义组件其实就是一个自定义的HTML标签而已 -->

        每个组件内都是一个缩微的小 new Vue(),所以 new Vue() 中有什么,组件中也应该有什么如:methods:{ ... }、watch:{ ... }、computed:{ ... }、八个生命周期钩子函数等。

2. 组件原理

        每当 new Vue() 扫描到一个不认识的标签时,都会去内存中的 vue 类型中找有没有同名的组件,如果找到同名的 vue 组件,就会做三件事:

(1)复制组件 template 中的 HTML 片段代替页面上<组件></组件>标签位置;

(2)自动调用 data() 函数,返回一个新创建的模型对象,其中包含当前组件专属的模型变量;

(3)自动为当前组件区域创建一个缩微版的 new Vue(),j监控该区域。

举例:封装一个计数器组件;


  
  1. <body>
  2. <div id="app">
  3. <ul>
  4. <li>
  5. <my-counter></my-counter>
  6. </li>
  7. <li>
  8. <my-counter></my-counter>
  9. </li>
  10. <li>
  11. <my-counter></my-counter>
  12. </li>
  13. <li>
  14. <my-counter></my-counter>
  15. </li>
  16. </ul>
  17. </div>
  18. <script>
  19. //做一个组件和做new Vue()完全一样:3步
  20. Vue.component("my-counter", {
  21. //1. 做界面:template里
  22. //1.1 唯一父元素
  23. //1.2 查找可能发生变化的位置
  24. //1.3 触发事件的元素
  25. template: `
  26. <div>
  27. <button @click="minus">-</button>
  28. <span>{{n}}</span>
  29. <button @click="add">+</button>
  30. </div>
  31. `,
  32. //2. 创建模型对象
  33. //2.1 创建data:必须是函数——为了反复调用
  34. data() {
  35. return {
  36. n: 0
  37. }
  38. },
  39. //2.2 创建methods
  40. methods: {
  41. add() {
  42. this.n++
  43. },
  44. minus() {
  45. if (this.n > 0) {
  46. this.n--
  47. }
  48. }
  49. }
  50. })
  51. new Vue({
  52. el: "#app"
  53. })
  54. </script>
  55. </body>

效果如下:

为什么组件的data必须是一个函数(高频笔试面试):

        可反复调用;

        反复创建新对象;

        避免组件间数据冲突。

二、组件化开发

        前端一个页面的功能和代码量越来越多,但是操作系统是禁止多人协作编写一个文件的。组件化就是将一个大的页面,划分为多个组件区域,分别保存在不同的文件中,由多人协作开发。最后运行时,还能合并在一个页面中运行。

        使用组件进行开发便于多人协作,提高开发效率;松耦合,一人出错,不会影响全局。

1. 组件的使用过程

(1)每当拿到一个页面后,先划分组件区域,根据3个原则:位置、功能、是否重用;

(2)为每个组件创建独立的js文件,来保存组件的代码;

(3)回到原页面中引入并使用组件标签,将组件重新拼接回一个完整的页面。

2. 组件分类(vue三大组件)

(1)根组件 new Vue()

        整个页面甚至整个项目只有一个 new Vue() 监控全局。

(2)全局组件 Vue.component()

        可放在任何位置,没有限制。

(3)子组件

        规定只能在指定父组件范围内使用的组件。子组件的创建及使用如下:

        a. 只创建一个普通的 js 对象,保存组件的内容;

var 子组件对象名={ 组件内容 }
 

        b. 为父组件添加新成员 components


  
  1. 父组件:{
  2. ... : ...,
  3. components:{ 子组件对象名, ... , }
  4. }

        c. 在父组件界面中

<子组件标签名></子组件标签名>
 

举例: 实现待办事项列表的界面部分划分组件;

        组件todo.js


  
  1. Vue.component("todo", {
  2. template: `
  3. <div>
  4. <h3>待办事项列表</h3>
  5. <todo-add></todo-add>
  6. <todo-list></todo-list>
  7. </div>
  8. `,
  9. components: {
  10. todoAdd, //vue自动将其翻译为todo-add
  11. todoList //vue自动将其翻译为todo-list
  12. }
  13. })

        组件todoAdd.js


  
  1. var todoAdd = {
  2. template: `
  3. <div>
  4. <input><button>+</button>
  5. </div>
  6. `
  7. }

        组件todoList.js


  
  1. var todoList = {
  2. template: `
  3. <ul>
  4. <todo-item></todo-item>
  5. <todo-item></todo-item>
  6. <todo-item></todo-item>
  7. <todo-item></todo-item>
  8. <todo-item></todo-item>
  9. </ul>
  10. `,
  11. components: {
  12. todoItem //vue将其自动翻译为todo-item
  13. }
  14. }

        组件todoItem.js


  
  1. var todoItem = {
  2. template: `
  3. <span>
  4. <li>1 - 吃饭 <a href="javascript:;">×</a></li>
  5. <span>
  6. `
  7. }

        首页index.html


  
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Document</title>
  7. <script src="js/vue.js"></script>
  8. <script src="todoItem.js"></script>
  9. <script src="todoList.js"></script>
  10. <script src="todoAdd.js"></script>
  11. <script src="todo.js"></script>
  12. </head>
  13. <body>
  14. <div id="app">
  15. <todo></todo>
  16. </div>
  17. <script>
  18. new Vue({
  19. el: "#app"
  20. })
  21. </script>
  22. </body>
  23. </html>

效果如下:


3. 组件间传值——父给子传值


  
  1. //1.父给子:
  2. 父组件:{
  3. template:`
  4. <子组件标签 :自定义属性名="父组件的变量">
  5. `
  6. //2.子组件接收属性值:
  7. 子组件对象:{
  8. props:[ "自定义属性名" ]
  9. }
  10. //在子组件内,props中的属性用法和data中的变量用法完全一样
  11. //差别在于props的属性值来自于外部传入,data中的变量值由自己定义

 举例:使用父给子传值,实现待办事项列表功能;

        组件todo.js


  
  1. Vue.component("todo", {
  2. template: `
  3. <div>
  4. <h3>待办事项列表</h3>
  5. <todo-add :tasks="tasks"></todo-add>
  6. <todo-list :tasks="tasks"></todo-list>
  7. </div>
  8. `,
  9. data() {
  10. return {
  11. tasks: ["踢足球", "玩游戏", "看电视"]
  12. }
  13. },
  14. components: {
  15. todoAdd, //vue自动将其翻译为todo-add
  16. todoList //vue自动将其翻译为todo-list
  17. }
  18. })

        组件todoAdd.js


  
  1. var todoAdd = {
  2. props: ["tasks"],
  3. template: `
  4. <div>
  5. <input v-model="t"><button @click="add">+</button>
  6. </div>
  7. `,
  8. methods: {
  9. add() {
  10. this.tasks.push(this.t);
  11. this.t = ""
  12. }
  13. }
  14. }

        组件todoList.js


  
  1. var todoList = {
  2. props: ["tasks"],
  3. template: `
  4. <ul>
  5. <li v-for="(t,i) of tasks" :key="i">
  6. <todo-item :t="t" :i="i" :tasks="tasks"></todo-item>
  7. </li>
  8. </ul>
  9. `,
  10. components: {
  11. todoItem //vue将其自动翻译为todo-item
  12. }
  13. }

        组件todoItem.js


  
  1. var todoItem = {
  2. props: ["t", "i", "tasks"],
  3. template: `
  4. <span>
  5. <li>{{i+1}} - {{t}} <a href="javascript:;" @click="del">×</a></li>
  6. <span>
  7. `,
  8. methods: {
  9. del() {
  10. // 从数组中删除一个元素
  11. this.tasks.splice(this.i, 1)
  12. }
  13. }
  14. }

         首页index.html


  
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Document</title>
  7. <script src="js/vue.js"></script>
  8. <script src="todoItem.js"></script>
  9. <script src="todoList.js"></script>
  10. <script src="todoAdd.js"></script>
  11. <script src="todo.js"></script>
  12. </head>
  13. <body>
  14. <div id="app">
  15. <todo></todo>
  16. </div>
  17. <script>
  18. new Vue({
  19. el: "#app"
  20. })
  21. </script>
  22. </body>
  23. </html>

效果如下:

        初始页,

        删除, 

        添加,

文章来源: majinjian.blog.csdn.net,作者:Developer 小马,版权归原作者所有,如需转载,请联系作者。

原文链接:majinjian.blog.csdn.net/article/details/120365513

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。