组件

基础介绍

参考:Vue 组件_哔哩哔哩

  • 组件本质上是可复用的Vue实例,所以在内部同样有data,methods等属性
  • 区别是:没有挂载的声明,不存在el这样的挂载选项;

template——定义挂载Dom,也可以理解为设置组件结构,最终被引入根实例

注意:template定义的结构只能有一个根元素(即所有的内容都包含在一个Dom元素里)

props——自定义组件的属性的数组,方便其他组件传值,类似接口的的形参,用来接收数据

data——组件里的data要封装在一个方法里,是因为要区分全局的变量的定义,确保组件定义的变量只能在组件内部调用

用途

  1. 用于封装页面的部分功能,将功能的结构、样式、逻辑代码封装成一个整体
  2. 提高功能的复用性、可维护性,更好专注业务逻辑

形式

通过组件名作为Html自定义标签名

		<div id="app">
			<!--普通Html标签  -->
			<span>普通Html标签</span>
			<!-- 自定义组件标签-->
			<my-com></my-com>
		</div>

全局注册

  • 全局注册的组件在注册后可用于任意实例或组件里
  • 全局注册必须设置在根Vue实例创建之前

组件命名规则

定义有两种规则

  1. kebab-case: my-component
  2. PascalCase: MyComponent
Vue.component('MyCom',{/*选项对象*/});
Vue.component('my—com',{/*选项对象*/});

应用规则

在Dom里只能采用kebab-case: ' my-component'

<my-com :vk="msg"></my-com>	

Demo:

		<div id="app">
			<!--普通Html标签  -->
			<span>普通Html标签</span>
			<!-- 自定义组件 -->
			<my-com></my-com>
		</div>
			Vue.component('MyCom',{
				template:`<div><p>这里是结构最简单的组件</p></div>`
			});

单向数据流

  1. 父子间组件的所有prop都是单向下行绑定的。包含两层含义

    • 传值只能父组件向子组件传值
    • 子组件的变化不能反向影响父组件的数据

    父组件向子组件传值Demo

    		<div id="app">
    			<!-- 3.给组件自定义属性vk传值-->
    			<!-- 注意:这里的value必须是定义在组件父级元素里的 -->
    			<my-com :val="msg"></my-com>
    		</div>
    
    		<script type="text/javascript">
    		// 全局组件必须声明在Vue实例创建之前
    		   <!-- 声明方式1 -->
    			Vue.component('MyCom',{
    				//1.为组件声明一个属性val
    				props:['val'],
    				//2.将组件里的属性val值赋给template里Dom元素的属性
    				template:`<input type="text" :value="val"></input>`
    			});
    			new Vue({
    				el:"#app",
    				data:{
    					msg:"Hello Word"
    				}
    			})
    		</script>
    
  2. 如果子组件要更改prop参数接收到的数据,应当存储在data中后操作

    		<div id="app">
    			<my-com :val="msg"></my-com>
    		</div>
    
    		<script type="text/javascript">
    			Vue.component('MyCom',{
    				props:['val'],
    				template:`<div>
                    {{title}}
                    <button  @click="fn">按钮</button>
                    </div>`,
                    data:function(){
    					return{
                            //1.将prop属性val存储在data中的title中
    						title:this.val
    					}
    				},
                    methods:{
                        fn(){
                            //2.存储完再更改储存的值title,不要直接修改this.val = "Hello Vue"会报错
                            this.title = "Hello Vue"
                        }
                    }
    			});
    			new Vue({
    				el:"#app",
    				data:{
    					msg:"Hello Word"
    				}
    			})
    		</script>
    
  3. 如果prop为对象或者数组时,子组件操作会影响父组件的状态。

因为当prop为对象或者数组时,传递的是对象或者数组的引用,所以父子组件操作的引用指向的是同一对象或数组,任一一方改变都会真实改变这个对象或者数组的值

<div id="app">
			{{student.sname}}:{{student.age}}
			<my-com 
			:val="msg" 
			:stu="student"
			></my-com>
           
		</div>
        <script type="text/javascript">
			Vue.component('MyCom',{
				props:['val','stu'],
				template:`<div>
                {{title}}
                <button  @click="fn">按钮</button>
				{{st.sname}}:{{st.age}}
                </div>`,
                data:function(){
					return{
                        //1.将prop属性val存储在data中的title中
						title:this.val,
						st:this.stu
					}
				},
                methods:{
                    fn(){
                        //2.存储完再更改储存的值title,不要直接修改this.val = "Hello Vue"会报错
                        this.title = "Hello Vue";
						this.st.sname = "Hanmeimei";
						this.st.age = 19;
                    }
                }
			});
			new Vue({
				el:"#app",
				data:{
					msg:"Hello Word",
					student:{
						sname:"Lilei",
						age:18
					}
				}
			})
		</script>

效果图: