IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 组件化你怎么看? -> 正文阅读

[JavaScript知识库]组件化你怎么看?

组件化你怎么看?

组件的使用必须在 Vue 实例挂载的 div 之内

拥有组件的三大步:

创建组件构造器

<!DOCTYPE html>
<html>
<script>
	const cpnC = Vue.extend({
		 template: ' //这里的template属性是html 模板的 意思
			 <div>
 				<h2>iiiiiii<h2>
 				<h3>sdfjsefi<h3>
 			</div>'
	})
</script>
<html>

注册组件

Vue.component('my-cpn',cpnC) 
 	//第一个参数是创建的标签名,
	//第二个参数是创建组件构造器的方法名
	//这样的注册方式注册的是全局组件</pre>

使用组件

组件实例对象

<body>
	<my-cpn></my-cpn>
 	<my-cpn></my-cpn>
 	<my-cpn></my-cpn>
</body>

组件 简单点~

简化注册组件的方式:在 Vue 实例或其他组件构造器中添加 component 属性

<script>
	const app = new Vue({
		el:'#app',
		components:{
			cpn1:cpnC1,  //cpn1是指标签名,cpnC1是指构造组件方法名
			cpn2:cpnC2  //可以注册多个组件
		}
	})
</script>

组件的创建、注册可以在任意其他组件中,或者在 Vue 实例中
官方文档的注册方式

 Vue.component('my-component-name',{ })
//该组件名就是 Vue.component 的第一个参数

全局注册

直接通过 Vue 实例注册创建的组件意味着注册方式是全局的。也就是说他们再注册之后可以用在任何新创建的 Vue 根实例的(new Vue)的模板中

Vue.component('my-component-name',{
//..选项})
<div id="app">
  <component-a></component-a>
  <component-b></component-b>
  <component-c></component-c>
</div>

父组件与子组件的联系

如果是组件之间进行注册的话,那么最高级的组件其注册位置在 Vue 实例中,最高级不包括 Vue 实例,其实 Vue 实例是根组件

组件在哪里注册,就在哪里使用;在 Vue 实例中注册可以在全局中使用 、在其他组件中注册只能在其 他组件内使用

<script>
	const cpnC = Vue.extend({
        components:{
            cpn1:cpnC1,
            cpn2:cpnC2
        }
    })
</script>

组件的语法糖注册方式(创建组件的构造方法和注册一齐简写)

<script>  //省去组件的构造器方法(但是仍会调用extend),直接在注册组件中添加模板属性 template
	Vue.component('cpn1',{  //con1 是标签名
        template:{
            `
            <div>
                <h2>iiiiiii<h2>
                <h3>sdfjsefi<h3>
            </div>
            `
        }
    })
</script>

疑问在于,这样注册的组件算是全局组件还是局部组件呢?是算局部组件的,因为在组件内进行注册的,但是可以直接使用该组件

组件的 template 模板属性的抽离

1.把模版写在 中,通过添加 id 属性和组件相关联

在组件的template属性中添加模板的id即可

<template id="cpn">
	<div>
     <h2>
         我是内容
    </h2>   
   </div>
</template>

<script>
	Vue.component('cpn',{
        template:'#cpn'
    })
</script>

2.使用 template 标签 ,同样的通过添加 id 属性 和组件相关联

template 标签必须放在挂载区内

<div id = "app">
  <template id = "cpn">
		<div>
       <h2>
        我是标题
      	</h2>
      </div>
    </template>
</div>
<script>
	Vue.component('cpn',{
		template:'#cpn'
	})
   const app = new Vue({
       el:'#app'
   })
</script>

组件中的数据存放

data()非对象类型

组件是一个单独功能模块 的封装:这个模块有属于自己的HTML模板,也应该有属于自己的数据 data(因为组件不能访问 Vue 实例中的data属性中的值,就算能访问,多个组件叠加的值不利于代码编写),组件拥有属于自己可以保存数据的地方

组件中的data属性为什么是一个函数

因为在重复使用同一个组件时,并不希望在修改其中一个组件的数据时其他组件的值也同时被修改,使用函数是为了让其中的每个组件的内存地址不同从而做到互不影响

<script>
	//注册组件
   const obj = {
       counter:0
   }
   Vue.component('cpn',{
       template:'#cpn',
       //data(){
           //return{
              // counter:0
           //}
       //}
       data(){
          return {
              obj
          } 
       }
   })
</script>

这种情况就是多个组件的值会同时被修改

父子组件的通信

子组件是不能引用父组件或者 Vue 实例的数据的,但是在开发中,一些数据确实需要从上层传递到下层,比如在一个页面中从服务器中请求到很多数据,其中一部分数据并非由整个页面的大组件展示的,而是需要下面的小组件进行展示,这时我们不会让小组件再次发送网络请求,而是直接让大组件将数据传递给小组件

途径

  1. 通过props向子组件传递数据

  2. 通过事件向父组件发送消息

image.png

props 基本用法(父组件向子组件传递数据)

使用选项 props 来声明需要从父级接受到的数据

方法一:字符串数组,数组中的字符串就是传递时的名称

方法二:对象、对象可以设置传递时的类型,也可以设置默认值等

<body>
    <div id = "app">
        <cpn v-bind:cmovies = "movies" :cmessage = "message"></cpn> :相当于 v-bind
    </div>
    <template id = "cpn">
    		<div>
            	<h1>sdfsdf</h1>
                <h3>
                    {{cmovies}}
                </h3>
                <h3>
                    {{cmessage}}  检测是否接收到父组件的值
                </h3>
        	</div>
    	</template> 
    
    <script>
	const app = new.Vue({
        el:'#app',
        data:{
            message:'nihao',
            movies:['还望''海贼''海尔'],
            component:{
                cpn  //这里的子组件的注册放在了 Vue 实例中
            }
        }
    })
     const cpn = {
         template:"#cpn",
         props:['cmovies','cmessage'], //利用props属性通过数组的方式来接受父组件的值(变量)
         data(){
             return{}  //data 方法中必须设置返回值
         },
         methods:{
             
         }
     }
	</script>
</body>
props 属性还可以提供类型限制或一定的默认值
<script>
   const cpn = {
       template:"#cpn",
       props:{
           //1.类型限制
           cmovies:Array,
           cmessage:String,
           //2.提供默认值
           cmessage:{
               type:String,
               default:'aaaaa',
               required:true  //当调用这个组件时必须使用这个属性'cmessage',required是必传值
           },
           cmovies:{   //类型是对象或者数组时,默认值必须是个函数
           	type:Array,
           	default(){
       			return[]
   			}
       	}
       }
   }
</script>
<script>
	Vue.component('my-component',{
        pros:{ //基础的类型检查 ('null'匹配任何类型)
         	propA:Number
         	//多个可能的类型
         	propB:[String,Number],
        	//必填的字符串
        	 propC: {
        		type: String,
        		required: true
    		  },
           //带有默认值的数字
           propD: {
          		 type: Number,
              default:100
           },
        	//带有默认值的对象
        	propE: {
               type: Object,
                   default: function(){
                       return: {message: 'hello'}
                   }
            },
          propF: {
              validator: function (value) {
                //这个值必须匹配下列字符串中的一个
                return 	['success','warning','danger'].indexof(vaule) !== -1
              }
          }
        		
        }
    })
</script>
props驼峰标识 的转换

使用组件时,接受父组件的值通常会有 利用驼峰标识定义的属性,这时我们需要利用 c- / 或者用 - 来连接词语

暂时标签内传值时不支持驼峰命名

<body>
    <div id = "app">
        <cpn :c-info = "info" :child-my-message = "message"></cpn>
    </div>
</body>
<script>
	const cpn = {
        template:'#cpn',
        props:{
            cInfo:{ }
        }
    }
</script>
<body>
    <div>
        <h2>
            {{cInfo}}
        </h2>
        <h2>
            {{childMyMessage}}
        </h2>
    </div>
</body>

当模板中的标签过多时,需要使用一个总标签将其括起来,否则会报错

<template id = "cpn">
	<div>
     <h2>
       {{cInfo}}    
     </h2>
   </div>
</template>
子传父(自定义事件)

当子组件需要向父组件传递数据时就需要用到自定义事件

流程:在子组件中,通过$emit()来触发事件;在父组件中,通过v-on 来监听子组件事件(v-on不仅可以监听DOM事件,也可以监听自定义事件)

<body>
    <!-- 挂载区 父组件模板-->
    <div id="app">
        <cpn @item-click="cpn-click"></cpn>
    </div>
    <!-- //子组件 模板-->
    <template id="cpn1">
        <div>
            <!-- 向每个按钮添加点击事件 -->
            <button v-for="item in categories" @click='btnClick(item)'>{{item.name}}</button>
        </div>
    </template>

    <script>
        const cpn = {
            template: '#cpn1',
            data() {
                return {.
                    categories: [
                        { id: 'aaa', name: 'aaareinasdaif' },
                        { id: 'bbb', name: 'fffreiasdanaif' },
                        { id: 'ccc', name: 'gggreinasdaaif' },
                        { id: 'ddd', name: 'hhhhhhhh' },
                    ]
                }
            },
            methods: {
                btnClick(item) {
                    //发射
                     this.$emit('item-click',item)
                }
            }
        }
        const app = new Vue({
            el: '#app',
            components: {
                cpn:cpn
            },
            methods: {
                cpnClick(item) {
                    console.log('cpnClick',item);
                }
            }
        })
    </script>
```html
    <script>
        const cpn = {
            template: '#cpn1',
            data() {
                return {.
                    categories: [
                        { id: 'aaa', name: 'aaareinasdaif' },
                        { id: 'bbb', name: 'fffreiasdanaif' },
                        { id: 'ccc', name: 'gggreinasdaaif' },
                        { id: 'ddd', name: 'hhhhhhhh' },
                    ]
                }
            },
            methods: {
                btnClick(item) {
                    //发射
                     this.$emit('item-click',item)
                }
            }
        }
        const app = new Vue({
            el: '#app',
            components: {
                cpn:cpn
            },
            methods: {
                cpnClick(item) {
                    console.log('cpnClick',item);
                }
            }
        })
    </script></pre>

**错误思维**
![image.png](https://img-blog.csdnimg.cn/img_convert/ef8d865774ac3c9db91276c5ecd19a0a.png)

**正确思维**
![image.png](https://img-blog.csdnimg.cn/img_convert/9ee64e7af979242f9551e549a78d23d1.png)


  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-16 11:38:44  更:2021-08-16 11:40:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/26 15:50:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计