vue中组件与传值

一、组件

那么首先,什么是组件呢:

我们在开发的时候把一些可以复用的内容封装成组件

在vue中定义组件有两种常见的形式:

	1.全局组件
	2.局部组件

1.全局组件

    Vue.component('', { template })
    
	// 全局组件定义之后可以直接使用不需要注册
	例:
		<hello></hello>
		<script src="https://cdn.jsdelivr.net/npm/vue"></script>
		<script>
			Vue.component('hello', {
				      template: `
				        <div>
				          <h1>Hello 小明</h1>
				          <p>小明是个万人迷,万物皆可小明</p>
				        </div>
				      `,
			 })
		</script>

结果如下方图片
在这里插入图片描述

2.局部组件

	 const c = { template: `` }
	 
	//	局部组件在使用的时候需要注册
	//	components 属性进行注册
	例:
		<div id="app">
		   <count></count>
		</div>
		<script src="https://cdn.jsdelivr.net/npm/vue"></script>
		<script>
		    // 局部组件
		    var Counter = {
		      template: `
		        <div class="counter">
		          <h1>我是一个局部组件</h1>
		        </div>
		      `,
		    }		    
		    var app = new Vue({
		      el: "#app",
		      components: {
		        count: Counter,
		      }
		    })
		</script>

结果如下方图片

在这里插入图片描述
3.自定义组件

	定义局部组件, 就是一个对象,此对象包含有一些特殊的属性。
	
	// template    模板内容
	// data        组件的数据, data必须是一个function,此function有一个对象
	做为返回值
	// methods     方法
	// computed    计算属性
	// ...         其他的等等等等,所有vue中可以使用的方法或者属性都可以在组件
	内部使用
	// 定义的组件必须只有一个根节点

二、传值

1.父传子

通过props属性

例:
	<div id="app">
	    <count :step="2"></count> <!-- : 表示一个对象  -->
	</div>
	  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
	  <script>
	    // 局部组件
	    var Counter = {
	      template: `
	        <div class="counter">
	          <h1>我是一个计数器:{{count}}</h1>
	          <p>步长:{{step}}</P>
	            <button @click="count+=step">点击</button>
	        </div>
	      `,
	     // props: ['step'],	
	      // 或者如下,以对象的形式设置属性,可以对传递的数据做验证
	      //props是属性传值 这个是父组件向子组件传,通过属性来传
	      props:{
	     	  step:Number,
	      }
	      data() {
	        return {
	          count: 0
	        }
	      }
	    }
	    var app = new Vue({
	      el: "#app",
	      components: {
	        count: Counter,
	      }
	    })
	  </script>

结果如下方图片:
每次点击增加2
在这里插入图片描述

2.子传父

通过事件派发

 <div id="app">
    <p style="color: darkred">从计数器中传递出来的数据:{{fromCount}}</p>
    <p>{{stepValue}}</p>
    <input type="range" max="10" min="0" step="1" v-model.number="stepValue">
    <count @countchanged="countCHandel" :step="stepValue"></count> <!-- : 表示一个对象  -->
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <script>
    // 局部组件
    var Counter = {
      template: `
        <div class="counter">
          <h1>我是一个计数器:{{count}}</h1>
          <p>步长:{{step}}</P>
            <button @click="addHandle">点击</button>
        </div>
      `,
      //props: ['step'],

      // 或者如下,以对象的形式设置属性,可以对传递的数据做验证
      //props是属性传值 这个是父组件向子组件传,通过属性来传
      props:{
      	step:Number,
     },
      data() {
        return {
          count: 0
        }
      },
      methods: {
        addHandle() {
          this.count += this.step;
          // 派发事件,谁派发事件,谁监听。Count组件派发,Count监听,所以@countchanged绑定在count上
          this.$emit('countchanged', this.count)
        },
      }
    }
   
    var app = new Vue({
      el: "#app",
      components: {
        count: Counter,
      },
      data: {
        stepValue: 2,
        fromCount: 0
      },
      methods: {
        // 接收组件传递的数据
        countCHandel(v) {
          this.fromCount = v
        }
      }
    })
  </script>

结果图如下:
在这里插入图片描述

3.非相关组件传值

事件总线:解决非相关组件之间传值;
如图:导航组件和列表组件,点击购买,购物车后数字加1,
在这里插入图片描述

	 我们通过定义一个空白的对象 所有的事件派发和监听都在这个对象上进行。
	 
	  const eventBus = new Vue();// 定义一个空白的vue实例用来做事件的转发。
	 例:
	 	
	 	<!DOCTYPE html>
			<html lang="en">
			  <head>
			    <meta charset="UTF-8" />
			    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
			    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
			    <title>非相关组件之间传值</title>
			    <style>
			      img {
			        width: 100px;
			        max-width: 100px;
			      }
			      .nav {
			        display: block;
			        width: 100%;
			        height: 80px;
			      }
			      .nav ul {
			        list-style: none;
			        height: 100%;
			        width: 100%;
			        display: flex;
			        align-items: center;
			        justify-content: center;
			      }
			      .nav li {
			        color: deeppink;
			        margin: 0 3rem;
			      }
			      .product {
			        border: 0.01rem solid deeppink;
			        padding: 0.8rem;
			        margin: 0.5rem;
			      }
			    </style>
			  </head>
			  <body>
			    <!-- 事件总线 解决非相关组件之间传值 -->
			    <!-- 我们通过定义一个空白的对象 所有的事件派发和监听都在这个对象上进行 -->
			    <div id="app">
			      <!-- 顶部导航组件 -->
			      <navbar></navbar>
			      <!-- 商品列表组件 -->
			      <product v-for="(p,i) in list" :key="i" :product="p"></product>
			    </div>
			    <script src="./libs/vue.js"></script>
			    <script>
			      const eventBus = new Vue(); // 定义一个空白的vue实例用来做事件的转发
			      const navbar = {
			        template: `<div class="nav">
			            <ul>
			                <li>首页</li>
			                <li>商品列表</li>
			                <li>购物车({{cartCount}})</li>
			                <li>其他</li>
			            </ul>
			        </div>`,
			        created() {
			          eventBus.$on('buy-product', this.buyHandle);
			        },
			        methods: {
			          buyHandle(product) {
			            console.log(product);
			            this.cartCount += 1;
			          },
			        },
			        data() {
			          return {
			            cartCount: 0,
			          };
			        },
			      };
			      const product = {
			        template: `<div class="product">
			            <img :src="product.img"/>
			            <h5>{{product.name}}</h5>
			            <button @click="buyHandle(product)">购买</button>
			          </div>`,
			        props: ['product'],
			        methods: {
			          buyHandle(p) {
			            eventBus.$emit('buy-product', p);
			          },
			        },
			      };
			      const app = new Vue({
			        el: '#app',
			        components: {
			          product,
			          navbar,
			        },
			        data: {
			          list: [
			            {
			              img:
			                'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2002504746,179271572&fm=26&gp=0.jpg',
			              name: 'Nokia',
			              price: 200,
			            },
			            {
			              img:
			                'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=4162623679,2168960991&fm=26&gp=0.jpg',
			              name: 'IPhone',
			              price: 300,
			            },
			            {
			              img:
			                'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=591403396,1405019377&fm=26&gp=0.jpg',
			              name: 'HuaWei',
			              price: 400,
			            },
			          ],
			        },
			      });
			    </script>
			  </body>
			</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值