美文网首页
Vue 动态组件和keep-alive的使用

Vue 动态组件和keep-alive的使用

作者: coderhzc | 来源:发表于2022-01-12 20:32 被阅读0次

    一. component Vue 内置组件的基本使用 它提供了一个is属性,

    <component  is="Left"></component >
    <component  :is="comName"></component >
    1. is有两种方法绑值,
           -- 直接写死的方式is="组件的名称"
           -- v-bind动态绑定的写法但是需要再data中定义一个变量 :is="comName"
    2. is属性的值,表示要渲染的组件的名字
    

    写死的写法:

    image.png

    动态的写法

    image.png

    需求: 点击Left就出现Left组件 点击Right出现Right组件

    <template>
      <div id="app">
        <div class="title">
          <h1>App 根组件</h1>
          <hr />
        </div>
    
        <button @click="btn(1)">展示Left</button>
        <button @click="btn(2)">展示Right</button>
        <div class="comp-box">
          <!-- <Left></Left>
          <Right></Right> -->
          <!-- component Vue 内置组件的使用 -->
    
          <!-- 1.这种就写死了 -->
          <!-- <component is="Left"></component> -->
    
          <!-- 2.动态绑定的写法 -->
          <component :is="comName"></component>
        </div>
      </div>
    </template>
    
    <script>
    import Left from "@/components/Left.vue";
    import Right from "@/components/Right.vue";
    export default {
      name: "App",
      data() {
        return {
          comName: "Left", // 表示要展示的名字
        };
      },
      components: {
        Right,
        Left,
      },
      methods: {
        btn(num) {
          num === 1 ? (this.comName = "Left") : (this.comName = "Right");
        },
      },
    };
    </script>
    
    <style lang="less" scoped>
    #app {
      .title {
        height: 60px;
        line-height: 60px;
        background-color: #ccc;
        text-align: center;
        padding: 20px 0;
        margin-bottom: 10px;
      }
      .comp-box {
        display: flex;
        justify-content: space-between;
      }
    }
    </style>
    
    

    实际截图

    image.png

    一.二 动态组件之间的传值 和事件绑定发射问题

    动态组件之间的传值,他绑定到<component></component>中的属性,对应的所有组件也会接受到传递过来的数据

    component 动态组件的传递参数:

    App.vue中的代码:
    <template>
      <button
        v-for="item in tabs"
        :key="item"
        @click="btnClick(item)"
        :class="currentTitle === item ? 'active' : ''"
      >
        {{ item }}
      </button>
    
      <h1>{{ currentTitle }}</h1>
    
      <component :is="CpmName" :age="18" name="huzhenchu"></component>
    </template>
    
    <script>
    import HomeCpn from "./pages/Home.vue";
    import AboutCpn from "./pages/About.vue";
    import CategoryCpn from "./pages/Category.vue";
    export default {
      name: "AppCpn",
      components: {
        HomeCpn,
        AboutCpn,
        CategoryCpn,
      },
      data() {
        return {
          tabs: ["Home", "About", "Category"],
          currentTitle: "Home",
          CpmName: "HomeCpn",
        };
      },
    
      methods: {
        btnClick(item) {
          console.log(item);
          this.currentTitle = item;
          // if (item === "Home") {
          //   this.CpmName = 'HomeCpn'
          // }else if(item === "About") {
          //   this.CpmName = "AboutCpn"
          // }else if(item === "category") {
          //   this.CpmName = "CategoryCpn"
          // }
          switch (item) {
            case "Home":
              this.CpmName = "HomeCpn";
              break;
            case "About":
              this.CpmName = "AboutCpn";
              break;
    
            case "Category":
              this.CpmName = "CategoryCpn";
              break;
            default:
              break;
          }
        },
      },
    };
    </script>
    
    <style lang="css" scoped>
    .active {
      color: red;
    }
    </style>
    
    
    /**********Home.vue子组件****************/
    <template>
      <div class="home-box">
        <h3>Home:{{ name }} ---- {{ age }}</h3>
      </div>
    </template>
    
    <script>
    export default {
      name: "HomeCpn",
      props: {
        name: {
          type: String,
          default: "",
        },
        age: {
          type: Number,
          default: 18,
        },
      },
    };
    </script>
    
    <style lang="css" scoped>
    .home-box {
      width: 400px;
      height: 400px;
      border: 1px solid red;
      margin-top: 20px;
      padding: 20px;
      box-sizing: border-box;
    }
    </style>
    

    实际截图

    image.png

    component动态组件的事件传递(子组件向父组件传值)实际截图如下:

    image.png

    二.keep-alive的使用

    二.一 keep-alive的基本使用

    需求在第一个页面点击+ 1 然后去了别的页面浏览网页,再回来当前页,还要看到当前页的 + 1?

    <template>
      <div id="app">
        <div class="title">
          <h1>App 根组件</h1>
          <hr />
        </div>
    
        <button @click="btn(1)" style="margin-right: 15px">展示Left</button>
        <button @click="btn(2)">展示Right</button>
        <div class="comp-box">
          <!-- <Left></Left>
          <Right></Right> -->
          <!-- component Vue 内置组件的使用 -->
    
          <!-- 1.这种就写死了 -->
          <!-- <component is="Left"></component> -->
    
          <!-- 2.动态绑定的写法 -->
          <keep-alive>
            <component :is="comName"></component>
          </keep-alive>
        </div>
      </div>
    </template>
    
    <script>
    import Left from "@/components/Left.vue";
    import Right from "@/components/Right.vue";
    export default {
      name: "App",
      data() {
        return {
          comName: "Left", // 表示要展示的名字
        };
      },
      components: {
        Right,
        Left,
      },
      methods: {
        btn(num) {
          num === 1 ? (this.comName = "Left") : (this.comName = "Right");
        },
      },
    };
    </script>
    
    <style lang="less" scoped>
    #app {
      .title {
        height: 60px;
        line-height: 60px;
        background-color: #ccc;
        text-align: center;
        padding: 20px 0;
        margin-bottom: 10px;
      }
      .comp-box {
        display: flex;
        justify-content: space-between;
      }
    }
    </style>
    
    

    这种就可以满足基本需求了

    image.png

    二.二 keep-alive对应的生命周期函数 deactivated activated

    当组件被缓存时,会自动出发组件的deactivated生命周期函数

    当组件被激活时,会自动出发组件的activated生命周期函数

    image.png

    二.三 keep-alive的两个属性

    注意这两个组件是不可以同时使用的

    1. include属性: 是表示哪些指定的组件可以被缓存(多个组件匹配的,以逗号分隔,但是中间不能有空格)
        -- 字符串分隔:
      <keep-alive include="a,b">
         <component :is="view"></component>
      </keep-alive>
        -- 正则 regex (使用v-bind)
        <keep-alive include="/a|b/">
         <component :is="view"></component>
      </keep-alive>
      -- Array (使用v-bind)
       <keep-alive :include="[a,b]">
         <component :is="view"></component>
      </keep-alive>
    2. exclude属性:是表示哪些指定的组件不需要被缓存,用法同include
    3. 注意这两个组件是不可以同时使用的
    4. max属性: number|string.最多可以缓存多少组件实例,一旦达到这个数字,name缓存组件中最近没有被访问的实例会被销毁
    

    实际截图

    image.png

    三. 组件的name名称:

    当组件中添加了name属性的话,在做include和exclude属性匹配的时候你就不能直接用组件的名字取匹配了

    image.png

    三.一.总结:

    1. 组件的"注册名称"的主要应用场景是:以标签的形式,把注册好的组件,渲染和使用到页面结构之中
    2. 组件声明时候的"name",名称的主要应用场景:结合<keep-alive>标签实现缓存功能;一级在调试工具中看到组件的name名称
    

    相关文章

      网友评论

          本文标题:Vue 动态组件和keep-alive的使用

          本文链接:https://www.haomeiwen.com/subject/ssowcrtx.html