vue内置组件的使用

引用vue官网中内置组件,点我去官网

component

Props:
is - string | ComponentDefinition | ComponentConstructor
inline-template - boolean

用法:

渲染一个“元组件”为动态组件。依 is 的值,来决定哪个组件被渲染。

<!-- 动态组件由 vm 实例的属性值 `componentId` 控制 -->
<component :is="componentId"></component>

<!-- 也能够渲染注册过的组件或 prop 传入的组件 -->
<component :is="$options.components.child"></component>

其中component又叫动态组件,属性中 is 指定渲染的组件。

代码解释如下:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="../bootstrap/css/bootstrap.css">
  <script src="../js/vue.js"></script>
</head>

<body>
  <!--  1<div id="app">
    <com-a></com-a>
    <com-b></com-b>
    -----------------
    <component is="comA"></component>
    <component is="comB"></component>
  </div> -->
  
  <!--2-->
  <div id="app">
    <ul class="nav nav-tabs">
      <!-- 这里的item是是数组中的每一个对象 例如 {  name: 'fqniu', container: '吃美食' } -->
      <li class="nav-item" v-for="(item,idx) in tablist" v-on:click="changeTab(item)">
        <!-- 这里的class判断是否comNum等于item.name, 如果相等 则样式为 active -->
        <a class="nav-link" href="#" v-bind:class="{active:comNum===item.name}">{{ item.name }}--{{idx}}</a>
      </li>
    </ul>
    <div class="container p-3">
    <!-- 动态组件的使用-->
      <component :is="comNum"></component>
    </div>
  </div>

  <script>
    // 1、第一种 直接使用 component 
    // const vm = new Vue({
    //   el: '#app',
    //   components: {
    //     comA: {
    //       name: 'comA',
    //       template: `<div>comA</div>`
    //     },
    //     comB: {
    //       name: 'comB',
    //       template: `<div>comB</div>`
    //     }
    //   }
    // })

    // 2、
    // 点击tab栏切换内容 通过点击时 切换不同的组件 comNum 
    // 进而改变tab栏选项对应的内容 
    const vm = new Vue({
      el: '#app',
      data: {
        tablist: [{
          name: 'fqniu',
          container: '吃美食'
        }, {
          name: 'niuniu',
          container: '学游泳'
        }, {
          name: 'erniu',
          container: '宅屋看书'
        }, {
          name: 'shaniu',
          container: '敲代码'
        }],
        comNum: 'fqniu'
      },

      methods: {
        changeTab(item) {
          this.comNum = item.name
        }
      },
      created() {
        this.tablist.forEach(item => {
          Vue.component(item.name, {
            template: `<div>${item.container}</div>`
          })
        });
      }
    })

  </script>
</body>

</html>

keep-alive

Props:

include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
max - 数字。最多可以缓存多少组件实例。

用法:

< keep-alive > 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 < transition> 相似,< keep-alive > 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。

当组件在 < keep-alive> 内被切换,它的 activated 和 deactivated两个生命周期钩子函数将会被对应执行。

在 2.2.0 及其更高版本中,activated 和 deactivated 将会在 < keep-alive> 树内的所有嵌套组件中触发。

主要用于保留组件状态或避免重新渲染。

<!-- 基本 -->
<keep-alive>
  <component :is="view"></component>
</keep-alive>

<!-- 多个条件判断的子组件 -->
<keep-alive>
  <comp-a v-if="a > 1"></comp-a>
  <comp-b v-else></comp-b>
</keep-alive>

<!--`<transition>` 一起使用 -->
<transition>
  <keep-alive>
    <component :is="view"></component>
  </keep-alive>
</transition>

注意,< keep-alive > 是用在其一个直属的子组件被开关的情形。如果你在其中有 v-for 则不会工作。如果有上述的多个条件性的子元素,< keep-alive> 要求同时只有一个子元素被渲染。

2.1.0 新增 include and exclude

include 和 exclude 属性允许组件有条件地缓存。二者都可以用逗号分隔字符串、正则表达式或一个数组来表示:

<!-- 逗号分隔字符串 -->
<keep-alive include="a,b">
  <component :is="view"></component>
</keep-alive>

<!-- 正则表达式 (使用 `v-bind`) -->
<keep-alive :include="/a|b/">
  <component :is="view"></component>
</keep-alive>

<!-- 数组 (使用 `v-bind`) -->
<keep-alive :include="['a', 'b']">
  <component :is="view"></component>
</keep-alive>

匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配。

2.5.0 新增 max

最多可以缓存多少组件实例。一旦这个数字达到了,在新实例被创建之前,已缓存组件中最久没有被访问的实例会被销毁掉。

<keep-alive :max="10">
  <component :is="view"></component>
</keep-alive>

< keep-alive> 不会在函数式组件中正常工作,因为它们没有缓存实例。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="../bootstrap/css/bootstrap.css">
  <script src="../js/vue.js"></script>
</head>

<body>
  <div id="app">
    <ul class="nav nav-tabs">
      <li class="nav-item" v-for="(item,idx) in tablist" v-on:click="changeTab(item)">
        <a class="nav-link" href="#" v-bind:class="{active:comNum===item.name}">{{ item.name }}--{{idx}}</a>
      </li>
    </ul>
    <div class="container p-3">
      <keep-alive>
        <!-- 缓存组件 保留组件状态 避免重新渲染 -->
       <component :is="comNum"></component>
      </keep-alive>
     
    </div>
  </div>

  <script>

    // 点击tab栏切换内容 上一个内容里面的数据还存在,并没有销毁
    const vm = new Vue({
      el: '#app',
      data: {
        tablist: [{
          name: 'fqniu',
          container: '吃美食'
        }, {
          name: 'niuniu',
          container: '学游泳'
        }, {
          name: 'erniu',
          container: '宅屋看书'
        }, {
          name: 'shaniu',
          container: '敲代码'
        }],
        comNum: 'fqniu'
      },

      methods: {
        changeTab(item) {
          this.comNum = item.name
        }
      },
      created() {
        this.tablist.forEach(item => {
          Vue.component(item.name, {
            data() {
              return {
                num: 1
              }
            },
            methods: {
              change() {
                this.num++
              }
            },
            created() {
              console.log('created', item)
            },
            distoryed() {
              console.log('distory', item)
            },
            template: `<div>${item.container}
            <button @click="change">这是点击增加的{{num}}</button>
            </div>`
          })
        });
      }
    })

  </script>
</body>

</html>
  • <keep-alive> 缓存组件

    把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染可以添加一个 keep-alive
    包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们,主要用于保留组件状态或避免重新渲染

    • include(String/Regexp) : 指定缓存组件名
    • exclude(String/Regexp) : 指定不缓存的组件名
   <!-- 代表 xxx, yyy 下的组件被缓存 这里的 xxx 和 yyy 是组件名 该大写的大写 必须一致-->
  <keep-alive include="xxx,yyy">
     <component v-bind:is="currentTabComponent"></component>
  </keep-alive>

slot

Props:

name - string,用于命名插槽。

Usage:

< slot> 元素作为组件模板之中的内容分发插槽。< slot> 元素自身将被替换。

<!-- 1、具名插槽 -->
<base-layout>
  <template v-slot:header>
    Header content
  </template>

  Default slot content

  <template v-slot:footer>
    Footer content
  </template>
</base-layout>

<!-- 2、接收 prop 的具名插槽 -->
<infinite-scroll>
  <template v-slot:item="slotProps">
    <div class="item">
      {{ slotProps.item.text }}
    </div>
  </template>
</infinite-scroll>

<!-- 3、接收 prop 的默认插槽,使用了解构 -->
<mouse-position v-slot="{ x, y }">
  Mouse position: {{ x }}, {{ y }}
</mouse-position>

利用组件内容进行通讯(父->子)

在组件模板中利用内置组件<slot></slot>来承载组件内容,否则它的内容都会被忽略(被模板内容覆盖)

  • 默认插槽default

    
      <!-- 使用组件 -->
      <nav-link url="/home">首页</nav-link>
    
      <!-- 定义组件 -->
      <script>
        Vue.component('nav-link',{
          props:['url']
          //以下template写法,组件内容“首页”,会被template的内容覆盖掉,
          //最终解析为:<a href="/home"><span>Home</span></a>
          //template:`<a :href="url"><span>Home</span></a>`
    
          // 解决方案:可以用<slot></slot>保留内容和设置默认值
          // 最终解析为:<a href="/home">首页<span>Home</span></a>
          template:`<a :href="url"><slot></slot><span>Home</span></a>`
        });
      </script>
      
    
  • 具名插槽:

    • 模板内容:给<slot/>组件命名(设置name属性)
    • 组件内容:设置slot属性,实现内容精准显示到模板具体位置

    Vue2.6+已经废除slot属性,改成v-slot:name(只能用在template元素或组件上)


  <!-- 组件模板内容 -->
  <template id="myTest">
    <div>
      <slot name="header">这是拥有命名的slot的默认内容</slot>
      <slot>这是拥有命名的slot的默认内容</slot>
      <slot name="footer">这是拥有命名的slot的默认内容</slot>
    </div>
  </template>

  <!-- 使用组件 -->
  <my-component>
    <span slot="header">这里的内容显示到name为header的插槽</span>
    <span>这里的内容显示到默认插槽</span>
    <span slot="footer">这里的内容显示到name为footer的插槽</span>
  </my-component>

  <!-- Vue2.6+用法 -->
  <my-component>
    <template v-slot:header>这里的内容显示到name为header的插槽</template>
    <span>这里的内容显示到默认插槽</span>
    <template v-slot:footer>这里的内容显示到name为footer的插槽</template>
  </my-component>
  

作用域插槽(子- >父)

Vue编译规则:父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译

利用作用域插槽(slot-scope)实现把组件模板template中的数据传到组件内容中处理,实现特殊定制(PS:Vue2.6+已废除该属性,改为v-slot:name格式,简写:#name)


  <!-- mynav组件模板 -->
  <div class="box">
    <slot :msg="msg" :username="username">{{username}},{{msg}}</slot>
    <slot name="footer" title="播放器" :player="player">{{player}}</slot>
  </div>

  <!-- 组件内容 -->
  <mynav>
    <!-- props为传过来的数据组成的对象 -->
    <div slot-scope="props">{{props.msg}},{{props.username}}</div>

    <!-- Vue2.6+用法 -->
    <div v-slot:default="props">{{props.msg}},{{props.username}}</div>
    <div v-slot:footer="foot">{{foot.title}},{{foot.player}}</div>
  </mynav>
  

transition 和 transition-group

过渡动画

  • <transition>
  • <transition-group>

<transition>用于单个元素动画,<transition-group>用于多个元素并解析为一个标签(默认:span)

属性

  • name : 过渡类名前缀(默认:v)

    如设置name=“fade”,过渡类名变成:fade-enter / fade-enter-active / fade-leave / fade-leave-active

  • css : boolean,是否使用 CSS 过渡类(默认:true)。设置为 false,将只通过组件事件触发注册的 JavaScript 钩子。

  • 自定义过渡类名(可配合animate.css框架实现过渡效果)

    • enter-class
    • enter-active-class
    • enter-to-class
    • leave-class
    • leave-active-class
    • leave-to-class
      <transition
        enter-active-class="bounceIn"
        leave-active-class="bounceOut"
      >
      </transition>
    

触发动画场景

Vue会自动检测是否设置css动画或JavaScript钩子,并在下列情形中添加进入/离开过渡效果(css过渡或javascript过渡)

  • 条件渲染 (使用 v-if)
  • 条件展示 (使用 v-show)
  • 动态组件
  • 组件根节点

CSS过渡

  • 通过CSS过渡类名

    组件过渡过程中,默认会有四个CSS类名自动进行切换,会有如下四个CSS类名:

    • v-enter:进入过渡的开始状态,元素被插入时生效,只应用一帧后立即删除;
    • v-enter-active:进入过渡的结束状态,元素被插入时就生效,在过渡过程完成之后移除;
    • v-leave:离开过渡的开始状态,元素被删除时触发,只应用一帧后立即删除;
    • v-leave-active:离开过渡的结束状态,元素被删除时生效,离开过渡完成之后被删除;

在这里插入图片描述

JavaScript过渡

通过内置事件实现过渡动画效果,可以利用第三方动画库(如:velocity.js,jquery等)实现动画效果

    <transition
      v-on:before-enter="beforeEnter"
      v-on:enter="enter"
      v-on:after-enter="afterEnter"
      v-on:enter-cancelled="enterCancelled"
      v-on:before-leave="beforeLeave"
      v-on:leave="leave"
      v-on:after-leave="afterLeave"
      v-on:leave-cancelled="leaveCancelled"
    >
    </transition>
    methods: {
      // 过渡进入
      // 设置过渡进入之前的组件状态
      beforeEnter: function (el) {
        // ...
      },
      // 设置过渡进入完成时的组件状态
      enter: function (el, done) {
        // ...
        done()
      },
      // 设置过渡进入完成之后的组件状态
      afterEnter: function (el) {
        // ...
      },
      enterCancelled: function (el) {
        // ...
      },
      // 过渡离开
      // 设置过渡离开之前的组件状态
      beforeLeave: function (el) {
        // ...
      },
      // 设置过渡离开完成时地组件状态
      leave: function (el, done) {
        // ...
        done()
      },
      // 设置过渡离开完成之后的组件状态
      afterLeave: function (el) {
        // ...
      },
      // leaveCancelled 只用于 v-show 中
      leaveCancelled: function (el) {
        // ...
      }
    }

代码解释如下:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="../bootstrap/css/bootstrap.css">
  <script src="../js/vue.js"></script>
  <style>
    /* 1、默认 v */
    /*.v-enter,
    .v-leave-to {
      opacity: 0;
      transition: all 1s;
    }

    .v-enter-to,
    .v-leave {
      opacity: 1;
      transition: all 1s;
    } */
    
    /* 2、标签中添加一个name属性,然后把类名中v改成你定义的类名 */
    .my-enter,
    .my-leave-to {
      opacity: 0;
      transition: all 1s;
    }

    .my-enter-to,
    .my-leave {
      opacity: 1;
      transition: all 1s;
    }
  </style>
</head>

<body>
  <div id="app">
    <!-- 1、动画效果 -->
    <!-- <button @click="tag">点我看效果</button>
    <transition>
      <div v-if="flag">我是div,会消失和隐藏</div>
    </transition> -->

    <!-- 2、动画效果 -->
    <button @click="tag">点我看效果</button>
    <!-- 需要在transition标签上添加一个name属性,然后把类名中v改成你定义的类名, 比如my -->
    <transition name="my">
      <div v-if="flag">我是div,会消失和隐藏</div>
    </transition>

  </div>

  <script>
    // 点击反转flag的值
    const vm = new Vue({
      el: '#app',
      data: {
        flag: true
      },
      methods: {
        tag() {
          this.flag = !this.flag
        }
      }
    })

  </script>
</body>

</html>

注意点

以上内置组件不会产生具体的html结构;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值