vue组件简述

组件是什么?

在 Vue 里,一个组件本质上是一个拥有预定义选项并且可复用的 Vue 实例。它提供了一种抽象,让我们可以使用独立可复用的小组件来构建大型应用,任意类型的应用界面都可以抽象为一个组件树。官网图:
在这里插入图片描述

组件的注册

  1. 全局注册组件
Vue.component(组件的名字, 组件的配置)
  1. 局部注册组件
    Vue实例中有一个components选项可以注册局部组件,注册后该组件就是这个Vue实例的子组件,也就是局部组件。
Vue.component(父组件的名字, {
	components: {
		yh-button: {//y-button 是子组件的名字
			key:value //组件的配置项
		}
	}
})

组件的调用

将组件名当成自定义标签使用即可,可以复用多次, 只写一个的话需要用 / 闭合

<div id="app">
	<!-- 这是调用组件-->
	<yh-button></yh-button>
	<yh-button></yh-button>
	<yh-button /> 
</div>
<script>
new Vue({
	el: "app"
})
//这是注册组件
Vue.component('yh-button',{
  template:`
    <button>按钮</button>
  `
}
<script>

组件的注意事项

  • 全局注册组件时,必须要放置在 new Vue 之前
  • 组件的配置没有 el 选项,因为后续调用组件在哪里,这个组件的挂载点就是哪里。
  • 必须有 template 或者 render 选项,用来规定组件的模板内容。
  • 组件的template模板只能有一个根元素,多个根元素会导致无法构成一颗树。
  • data 选项必须是一个函数返回对象的形式,防止调用多次造成全局污染。
Vue.component('yh-button',{
  template:`
    <button>按钮</button>
  `,
  data () {
  	return {
  		key:value //数据
  	}
  }
}
  • 组件名不能是现有的html标签名,也不能是其他已经注册过的组件名。
  • 组件名可以使用短横线写法与驼峰写法,但是调用组件时需要使用短横线写法。下列三种情况时例外:
    1. 写在 template 选项中
    2. 写在 里面的
    3. 写在.vue 后缀的单文件组件中

组件之间的通信方式

要了解组件的通信方式前先了解props选项

在不了解组件之前我们要考虑数据应该放在 data 中还是 computed 中,但是了解组件之后,组件的数据
就要考虑应该是 data 还是 props 还是 computed。prop 就是 props 中的具体一个参数,任何值都可以传递给任何 props中的prop,当一个值传递给一个 prop 属性的时候,它就变成了那个组件实例的一个属性。如果将组件看成是一个函数,那 props 就是这个函数接收到的参数集合。
示例:组件定义时如何设置形参,就是设置 props 选项

<div id="app">
</div>
<script>
Vue.component("hello", {
	props: ["name", "age", "sex"],
    template: `
      <div>
        <p>hello, 我的名字是 {{ name }} 我的年龄是 {{ age }} 我的性别是 {{ sex }}</p>
      </div>
        `,
   	});
let vm = new Vue({
	el: "#app",
    template: `
    	<div id="app">
            <hello name="张三" age="18"></hello>

            <hello name="李四" age="18" sex="男"></hello>

    		<hello name="王五" age="18" sex="男"></hello>
    	</div>
    `,
});
</script>

在这里插入图片描述
props也可以写成对象的形式,这种写法可以prop校验

//prop校验
props: {
	// key 是prop  {} 配置校验 
	key: {
		type: String, //type是类型也可以写出数组[String, Number]
		default: 'default',//default是默认项
		required: true //true 为必填
		// 自定义验证函数
		validator: function (value) {
        // value 是 当前的 prop 
        return /^张三$/.test(value) //这里 return 布尔值 一般可以做大小、正则之类的一些判断
      }
	}
}

单向数据流

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
root ->prop-> hello √
hello ->prop-> root ×

父子组件通信

直接使用 prop 传递数据给子组件即可

<div id="app">
	<parent></parent>
</div>
<script>
Vue.component("parent", {
	data() {
      return {
         son1Name: "张一",
         son2Name: "张二",
         son3Name: "张三",
    };
        },
    template: `
     	<div>
            <son :name="son1Name"></son>
            <son :name="son2Name"></son>
            <son :name="son3Name"></son>
       	</div>
    `,
});
Vue.component("son", {
	props: {
		name: {
		type: String,
		required: true,
		}
    },
    template: `
    	<div>
          <p>我是儿子,我的名字是 {{ name }} ,父亲取的</p>
        </div>
    `,
});
let vm = new Vue({
	el: "#app",
});
</script>

在这里插入图片描述

子父组件通信

  • 子组件不能直接去修改 prop 数据。
  • 子组件通过 $emit(自定义事件名字,数据) 去触发一个自定义事件。
  • 父组件在调用子组件时,监听这个自定义事件 。<son @事件名字=“事件处理函数”>
  • 父组件收到之后再去决定修改。(父组件修改自己的data中的数据是没有任何问题的)
<div id="app">
    <parent></parent>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
  <script>
    Vue.component('son',{
      template: `
      <button @click="fn1">按钮</button>
      `,
      methods: {
        // 自定义事件处理函数, event 是触发这个事件时,传递过来的 payload
        fn1(event) {
          this.$emit('hello', event)
        }
      }
    })

    Vue.component('parent',{
      template: `
        <div>
          <son @hello="fn2"></son>
        </div>
      `,
      methods: {
        fn2(payload) {
          console.log(123)
          console.log(payload)
        }
      }
    })
    new Vue({
      el: '#app'
    })
  </script>

在这里插入图片描述

兄弟组件之间的通信

  1. 最简单粗暴的方式:找他们的爹
    使用$emit: 子组件1 -> 通知 -> root -> prop -> 子组件2

  2. 推荐,中央事件管理器(中央事件总线)

    • 适用于: 亲兄弟之间或者关系特别复杂的组件之间

      扫描二维码关注公众号,回复: 11215145 查看本文章
    • 先创建一个空的vue实例对象。也就是不需要额外配置什么选项。(后期可使用vuex)
      const bus = new Vue()
      A B 两个组件,A 通信 B
      先在 B 组件的 created 中去通过 bus 来监听一个自定义事件
      bus.$on(eventName, callback)
      eventName 要监听的事件的名字
      callback 事件触发时的一个回调函数
      payload 事件触发时传递过来的 payload 参数

      在 A 组件的某个时候去触发自定义事件
      bus.$emit(eventName, payload)
      eventName 要触发的事件的名字
      payload 触发事件时传递过去的参数

<div id="app">
   <son1></son1>
   <son2></son2>
 </div>
 <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
 <script>
   let bus = new Vue()
   //子组件1
   Vue.component('son1',{
     data () {
       return {
         num: 1
       }
     },
     template: `
     <button @click="fn1">按钮</button>
     `,
     methods: {
       fn1() {
         this.num++
         bus.$emit('hello', this.num )
       }
     }
   })
   //子组件2
   Vue.component('son2', {
     data () {
       return {
         num: 1,
       }
     },
     template: `
       <div>
         {{ num }}
       </div>
     `,
     created () {
       bus.$on('hello', (num) => {
         this.num = num
       })
     }
   })
   new Vue({
     el: '#app'
   })
 </script>

点击前在这里插入图片描述
点击后

在这里插入图片描述

结尾

如果文章中有什么不足或者错误的地方欢迎大家留言分享。如果我的文章能帮到你的话那就给我个点赞和关注,谢谢朋友们的支持。

原创文章 11 获赞 259 访问量 1万+

猜你喜欢

转载自blog.csdn.net/yh604005215/article/details/105623837