Vue:入门9(组件基础)

component创建的组件可以当作自定义元素使用,并且有组件的相应功能

  • 因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,
    例如 data、computed、watch、methods 以及生命周期钩子等。
    仅有的例外是像 el 这样根实例特有的选项。
  • 组件的data必须是一个函数,这样写。所有组件都是互不影响的
</div>
<div id="id1">
   <button-counter></button-counter>
   <button-counter></button-counter>
   <button-counter></button-counter>
</div>
<script>
   Vue.component('button-counter',{
      data:function () {
         return {
            count:0
         }
      },
      template:'<button v-on:click="count++">{{count}}</button>'
   });
   new Vue({
      el:'#id1',
   });
</script>
<!--如果是这样写的话,所有组件的count都是一样的-->
<div id="id2">
  <button-counter></button-counter>
  <button-counter></button-counter>
  <button-counter></button-counter>
</div>
<script>

  var returnData = {
     count:0
  };
  Vue.component('button-counter',{
     data:function () {
        return returnData;
     },
     template:'<button v-on:click="count++">{{count}}</button>'
  });
  new Vue({
     el:'#id2',
  });
</script>

通过 Prop 向子组件传递数据

<!--方式1:直接在组件中。这样页面会将组件对应值替换
结果:<h3 id="id3">My journey with Vue</h3>
-->
<blog-post id="id3" title="My journey with Vue"></blog-post>
<script>
   Vue.component('blog-post',{
      props:['title'],
      template:'<h3 >{{title}}</h3>'
   });
   new Vue({
      el:'#id3',
   });
</script>
<!--方式二:通过Vue对象中传值,注意key这个属性不会在页面源码上显示出来
结果:
<div id="id4">
   <h3 id="1">My journey with Vue</h3>
   <h3 id="2">Blogging with Vue</h3>
   <h3 id="3">Why Vue is so fun</h3>
</div>
-->
<div id="id4">
   <blog-post2 v-for="post in posts" v-bind:id="post.id" v-bind:key="post.id" v-bind:title="post.title"></blog-post2>
</div>
<script>
   Vue.component('blog-post2',{
      props:['title'],
      template:'<h3>{{title}}</h3>'
   });
   new Vue({
      el: '#id4',
      data: {
         posts: [
            { id: 1, title: 'My journey with Vue' },
            { id: 2, title: 'Blogging with Vue' },
            { id: 3, title: 'Why Vue is so fun' }
         ]
      }
   });
</script>

注意这里进行了 v-bind:post=“post”,这样才能在template中使用这个对象

<!--其中一个页面结果是,注意看生成的id的位置:
<div id="1"><h3>My journey with Vue</h3> <div>1111</div></div>
-->
<div id="id5">
   <blog-post v-for="post in posts" v-bind:id="post.id" v-bind:key="post.id" v-bind:post="post"></blog-post>
</div>
<script>
   Vue.component('blog-post',{
      props:['post'],
      template:' <div>\n' +
              '      <h3>{{ post.title }}</h3>\n' +
              '      <div v-html="post.content"></div>\n' +
              '    </div>',
   });
   new Vue({
      el:'#id5',
      data:{
         posts: [
            { id: 1, title: 'My journey with Vue',content:'1111'},
            { id: 2, title: 'Blogging with Vue' ,content:'2222'},
            { id: 3, title: 'Why Vue is so fun' ,content:'3333'}
         ]
      }
   });
</script>
<!-- 效果:点击按钮增加div的字体大小
 首先添加了一个v-on:enlarge-text="postFontSize += 0.1"
 然后通过 v-on:click=$emit('enlarge-text')调用对应的方法
 -->
<div id="id6">
   <div :style="{fontSize : postFontSize1 + 'em'}">
      <blog-post v-on:enlarge-text="postFontSize1 += 0.1" v-for="post in posts"  v-bind:post="post" v-bind:key="post.id"> </blog-post>
   </div>
<!--   同时$emit('enlarge-text',0.2) 第二个参数也可以通过$event获取。第二个div每次+0.2-->
   <div :style="{fontSize : postFontSize2 + 'em'}">
      <blog-post v-on:enlarge-text="postFontSize2 += $event" v-for="post in posts"  v-bind:post="post" v-bind:key="post.id"> </blog-post>
   </div>
<!-- 同时还可以通过函数的方式  -->
   <div :style="{fontSize : postFontSize3 + 'em'}">
      <blog-post v-on:enlarge-text="onEnlargeText" v-for="post in posts"  v-bind:post="post" v-bind:key="post.id"> </blog-post>
   </div>
</div>
<script>
   Vue.component('blog-post',{
      props:['post'],
      template:'<div><h3>{{post.title}}</h3>' +
              '<button v-on:click="$emit(\'enlarge-text\',0.2)">enlarge text</button>' +
              '<div v-html="post.content"></div></div>'
   });
   new Vue({
      el: '#id6',
      data: {
         posts: [
            { id: 1, title: 'My journey with Vue',content:'1111'},
         ],
         postFontSize1: 1,
         postFontSize2: 1,
         postFontSize3: 1,
      },
      methods:{
         onEnlargeText: function (arg) {
            this.postFontSize3 += arg;
         }
      }
   });

</script>

组件使用v-model

<!--
<custom-input v-model="searchText"></custom-input>
实际是
<custom-input :value="searchText" @input="searchText = $event" ></custom-input>
-->
<div id="id7">
   <custom-input v-model="searchText"></custom-input>
   <span>{{searchText}}</span>
</div>
<script>
   Vue.component('custom-input',{
      props:['value'],
      template:' <input\n' +
              '      v-bind:value="value"\n' +
              '      v-on:input="$emit(\'input\', $event.target.value)"\n' +
              '    >',
   });
   new Vue({
      el:'#id7',
      data:{
         searchText:0,
      }
   });
</script>

通过插槽分发内容

<!--
<slot></slot>代表对应的'omething bad happened.'
结果:
<div id="id8"><strong>Error!</strong>
   Something bad happened.
</div>
-->
<alert-box id="id8">
   Something bad happened.
</alert-box>

<script>
   Vue.component('alert-box', {
      template: `
    <div>
      <strong>Error!</strong>
      <slot></slot>
    </div>
  `
   });
   new Vue({
      el:'#id8',
   })
</script>

动态组件

<!--
效果点击切换页面会一直切换不同的组件
这里用到了:is 可以认为:is=对应的组件名称
-->
<div id="id9">
   <button @click="change">切换页面</button>
   <component v-bind:is="currentTabComponent"></component>
</div>
<script>
   Vue.component('tab-home', { template: '<div>Home component</div>' });
   Vue.component('tab-posts', { template: '<div>Posts component</div>' });
   Vue.component('tab-archive', { template: '<div>Archive component</div>' });
   new Vue({
      el: '#id9',
      data: {
         currentTab: 'Home',
         index :0,
         tabs: ['Home', 'Posts', 'Archive']
      },
      computed: {
         currentTabComponent: function () {
            return 'tab-' + this.currentTab.toLowerCase()
         }
      },
      methods: {
         change:function () {
            this.index ++;
            if (this.index >= 3) {
               this.index = 0;
            }
            this.currentTab = this.tabs[this.index];
         }
      }
   })
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值