Vue组件化初体验

认识组件

组件化开发:

​ 将一个完成的页面,划分成一个个的组件,最终由一个个组件来完成整个页面你的开发,这个过程就是组件化开发

优势:复用!!

​ 也就是说组件只需要写一次,然后,用到组件的地方,只需要拿过去用就可以了

组成

一个组件由三部分组成:HTML+CSS+JS

两种注册组件的方式:

​ 1 全局组件

​ 2 局部组件

注册全局组件:

​ 第一个参数:表示组件名称

​ 第二个参数:是一个配置对象,这个配置对象类似于 Vue 构造函数中使用的配置对象

​ 也就是说:在 Vue 构造函数中能够使用的配置项,几乎都可以用在组件中

template 作用:指定组件模板

​ 注意:只能出现一个根节点

通过 data 指定组件中用到的数据

​ 注意:组件中的数据data,是一个方法,通过方法的返回对象来作为组件数据

我的第一个全局组件



  
    
    
    
    Document
  

  
    
注册局部组件

​ 通过配置项 components: {}

//html
 
//js Vue.component('wang',{ template:`

我是王婷,

`, components:{ //组件名称 ting:{ //组件模板 template:` 我最美,{{wt}} `, //组件使用的数据 data(){ return { wt:'确认过眼神,这是真的' } } } } }); const vm = new Vue({ el: '#app', data: { msg:'' }, components:{ item:{ template:`

我是一个局部的组件:{{chang}}

`, data(){ return{ chang:'验证通过' } } } } })
两中组件的区别

​ 1.全局组件可以在任意的地方使用

​ 2.局部组件只能在所属组件的 模板 中使用

使用组件

组件使用中的细节点:

表单/ul/ol等中指定的标签

产生的原因:在tbody中只能使用tr标签,使用其他的标签,浏览器解析的时候,会把其他标签作为table外部标签解析出去,结构就会发生分离,ul和ol也是如此

使用is解决问题,例如tr标签

//html
//js Vue.component('chang', { template: ` 常杰 李想 老丁 ` });

使用ref属性获取dom对象

//html
  
//js Vue.component('chang', { template: ` {{current}} `, data(){ return{ current:'常杰' } }, methods:{ handler(){ // alert('你触发了点击事件'); console.log(this.$refs.hello) } } });
组件通讯:

​ 组件是一个独立且封闭的个体,也就是说:默认情况下,组件只能使用自身的数据,而不能使用外部的数据

​ 但是,在组件化开发过程中,两个组件通讯( 也就是两个组件使用对方法的数据 ),是很常见的问题。

​ 这种问题就需要通过 组件通讯 机制来解决

组件通讯的三种情况:

​ 1 父组件 传递数据给 子组件

​ 2 子组件 传递数据给 父组件

​ 3 非父子组件(兄弟组件)

父 -->子通讯:

​ 父组件: Vue实例

​ 子组件: child组件

步骤:

​ 1 在子组件标签中添加要传递的属性

   msg就是要传递的属性
   表示传递动态数据给子组件

​ 2 在子组件中通过 props 显示指定要接受的属性

​ props: ['msg']

​ 3 此时,就可以在子组件中直接使用 msg 这个数据了



  
    
    
    
    Document
    
  

  
    
父组件:{{ parentMsg }}
子 -->父通讯

·思路:父组件提供一个方法,让子组件调用,子组件调用方法的时候将数据作为参数传递,这样,父组件就拿到子组件中传递过来的数据了

​ function parent(data) {

​ console.log('子组件中传递过来的数据:', data)

​ }

​ 子组件调用方法: parent( '要传递给父组件的数据' )

实现子组件给父组件传值的过程

​ 1.首先给父组件注册一个方法,同时在data设置一个变量准备接收子组件传出的值

​ 2.给子组件的标签上绑定自定义事件,并把方法作为事件函数传入

​ 3.在子组件中设置模板。在模板中设置事件,触发子组件的方法,在子组件的方法中,获取到传入的自定义事件,并且触发这个事件,传递参数

​ 4.子组件触发这个方法,并把数据作为方法的参数传出

​ 5.在父组件中处理触发事件的操作

//html
  
我儿子给我发的信息:{{msg}}
//js Vue.component('son',{ // 3.在子组件中设置模板。在模板中设置事件,触发子组件的方法,在子组件的方法中,获取到传入的自定义事件,并且触发这个事件,传递参数 template:`

我要给老爸发信息

`, // 4.子组件触发这个方法,并把数据作为方法的参数传出 methods:{ send(){ this.$emit('pmsg',"老爸,我资金有点....") } } }); const vm = new Vue({ el: '#app', data: { msg:'没啥用,就占个位' }, // 1.首先给父组件注册一个方法,同时在data设置一个变量准备接收子组件传出的值 methods:{ // 5.在父组件中处理触发事件的操作 fn(data){ this.msg = data } } })
小案例:

计数器实现的步骤

  • 1.首先创建一个子组件count
  • 2.在组件中创建模板,在模板中绑定事件handler,插入数据num
  • 3.在组件中创建模板中调用的方法handler
  • 4.在模板中设置数据num
  • 5.在组件标签上注册事件change,并绑定handlerChange方法(非常重要)
  • 6.在组件标签上添加属性ref为one/two(非常重要)
  • 7.在Vue实例中,添加方法handlerChange,并通过this.$refs.绑定的名称获取数据
  • 8.获取到子组件的数据进行操作




  
  
  
  Document



  
{{total}}
其他通讯(非父子)

思路:

1 创建一个事件总线(空的Vue实例 bus)

​ 2 哪个组件要接收数据,就注册事件

​ bus.$on(事件名称, () => {})

​ 3 哪个组件要传递数据,就触发事件

​ bus.$emit(事件名称, 要传递的数据)

注意: 注册和触发事件的 bus 是同一个,事件名称也要相同

实际上,不管两个组件是什么关系,都可以通过 bus 方式来实现通讯!

步骤:

​ 1.首先创建一个 空的vue实例的对象 bus

​ 2.然后创建两个组件,一个临时用于接收 (wang) ,一个临时用于发送数据 (chang)

​ 3.给两个组件设置好模板内容

​ 4. 组件chang设置方法,在方法中通过bus.$emit获取事件,并设置触发事件的参数

​ 5.在组件wang的钩子函数created中声明创建事件listen,并设置获取到参数后的处理

​ 注意点:虽然用不到vm但是,必须声明创建这个实例,只有指定了vue的边界,代码才能生效

//html
    
//js // 空Vue实例 // 事件总线 // 1.首先创建一个 空的vue实例的对象 即事件总线bus let bus = new Vue(); // 2.然后创建两个组件,一个临时用于接收 (wang) ,一个临时用于发送数据 (chang) Vue.component('chang',{ // 3.给两个组件设置好模板内容 template:`

我是常杰,我想对王婷说:

`, // 4. 组件chang设置方法,在方法中通过bus.$emit获取事件,并设置触发事件的参数 methods:{ fn(){ bus.$emit('listen','那天我一直在等你') } } }); Vue.component('wang',{ template:`

我是王婷,常杰对我说:{{msg}}

`, data(){ return { msg:'接收信息中,请等待...' } }, // 5.在组件wang的钩子函数created中声明创建事件listen,并设置获取到参数后的处理 created(){ bus.$on('listen',data=>{ this.msg = data }) } }); //没有用到数据,但是必须声明 const vm = new Vue({ el:"#app", data:{ } });

细节补充

props的属性

​ props:是只读的,在组件中使用的时候,只能读取,不能修改props的值( 赋值

)如果修改这个值,会报错!!!

​ 如果props是一个引用类型的数据,不能直接赋值,但是,可以修改引用类型中某个属性的值。

单向数据流:

​ 是说组件之间数据流动方向是从 父组件流动到 子组件

​ 父组件可以通过 props 将数据传递给子组件,并且,当父组件中的这个数据改变

后,这个改变后的数据会自动的再流动到子组件中。也就是说:子组件会自动接收到最

新的props数据,并且自动更新

​ 总结:

​ 1.props是只读的属性,只能读取props的值,而不能直接修改props的值

​ 如果是引用类型(对象、数组),可以直接修改对象中某个属性的值,但是,如果要求很严谨,也不应该直接修改对象中某个属性的值!!!

​ 2.单项数据流: 两个组件之间的数据流动方向,方向是: 父 -> 子

命名

HTML 标签或属性都是不区分大小写的(大小写不敏感的)

​ 不管你写的是大写字母的标签名或属性名,还是小写的,最终,都会被转化为小写字母

​ 同样的,在 Vue 中,给组件传递属性的时候,如果属性名中包含大写字母,在解析的时候,也会被转化为小写字母,再作为属性传递给组件

​ 如何给props命名:

​ 1 使用纯小写字母

​ props: ['childmsg']

​ 2 传递属性的时候,使用短横线连接多个单词,在子组件中通过 驼峰命名法 来接收这个数据(规范)

​ 传递(短横线连接)

​ 接收(驼峰命名法) props: ['childMsg']

你可能感兴趣的:(Vue组件化初体验)