• 【Vue】组件


    Vue的两大核心

    1. 数据驱动 - 数据驱动界面显示
    2. 模块化 - 复用公共模块,组件实现模块化提供基础

    组件基础

    组件渲染过程

    template ---> ast(抽象语法树) ---> render ---> VDom(虚拟DOM) ---> 真实的Dom ---> 页面

    Vue组件需要编译,编译过程可能发生在

    • 打包过程 (使用vue文件编写)
    • 运行时(将字符串赋值template字段,挂载到一个元素上并以其 DOM 内部的 HTML 作为模板)

    对应的两种方式 runtime-only vs runtime-compiler

    runtime-only(默认)

    • 打包时只包含运行时,因此体积更少
    • 将template在打包的时候,就已经编译为render函数,因此性能更好

    runtime-compiler

    • 打包时需要包含(运行时 + 编译器),因此体积更大,大概多10Kb
    • 在运行的时候才把template编译为render函数,因此性能更差

    启用runtime-compiler

    vue.config.js(若没有手动创建一个)

    module.exports = {
        runtimeCompiler: true      //默认false
    }

    组件定义

    1. 字符串形式定义(不推荐)

    例子

    const CustomButton = {
      template: "<button>自定义按钮</button>"
    };

    这种形式在运行时才把template编译成render函数,因此需要启用运行时编译(runtime-compiler)

    2. 单文件组件(推荐)

    创建.vue后缀的文件,定义如下

    <template>
      <div>
        <button>自定义按钮</button>
      </div>
    </template>

    <template> 里只能有一个根节点,即第一层只能有一个节点,不能多个节点平级

    这种形式在打包的时就编译成render函数,因此跟推荐这种方式定义组件

    组件注册

    1. 全局注册
    全局注册是通过Vue.component()注册

    import CustomButton from './components/ComponentDemo.vue'
    Vue.component('CustomButton', CustomButton)

    优点

    • 其他地方可以直接使用
    • 不再需要components指定组件

    缺点

    • 全局注册的组件会全部一起打包,增加app.js体积

    适合

    • 基础组件全局注册

    2. 局部注册

    在需要的地方导入

    <template>
      <div id="app">
        <customButton></customButton>
      </div>
    </template>
    <script>
    import CustomButton from "./components/ComponentDemo.vue";
    
    export default {
      name: "App",
      components: { CustomButton }
    };
    </script>

    优点

    • 按需加载

    缺点

    • 每次使用必须导入,然后components指定

    适合

    • 非基础组件

    组件使用

    组件复用

    <template>
      <div id="app">
        <img alt="Vue logo" src="./assets/logo.png" />
        <customButton></customButton>
        <customButton></customButton>
        <customButton></customButton>
      </div>
    </template>

    customButton 组件

    <template>
      <div id="app">
        <button @click="increment">click me {{times}} times</button>
      </div>
    </template>
    <script>
    export default {
      data() {
        return { times: 0 };
      },
      methods: {
        increment() {
          return this.times++;
        }
      }
    };
    </script>

    每个组件都会创建一个新实例,组件的data必须是function,因为每个实例维护自己的data数据

    组件传参

    1. 通过props属性

    定义一个button,按钮文本通过props传入

    <template>
      <button> {{buttonText}} </button>
    </template>
    <script>
    export default {
      props: {
        buttonText: String
      }
    };
    </script>

    调用者通过attribute传入

    <customButton buttonText="Button 1"></customButton>
    <customButton buttonText="Button 2"></customButton>
    <customButton buttonText="Button 3"></customButton>

    运行效果

    2. 通过插槽<slot></slot>

    组件在需要替换的地方放入插槽<slot></slot>

    <template>
      <button style="margin:10px"><slot>Defalt Button</slot></button>
    </template>
    <script>
    export default {
      props: {
        buttonText: String
      }
    };
    </script>

    调用者的innerHtml会替换插槽的值,若为空,使用默认的

    <customButton></customButton>
    <customButton><span style="color:blue">Button 2</span></customButton>
    <customButton>Button 3</customButton>

    运行效果

    注意:看到是用自定义组件的innerHtml替换插槽,若插槽只有一个,可以不写name attribute,若多个插槽需指定插槽name attribute

    自定义事件

    1. 在组件内部调用this.$emit触发自定义事件

    <template>
      <div style="margin:10px">
        <button @click="increment">
          <slot>Defalt Button</slot>
        </button>
        <span>Click me {{times}} times</span>
      </div>
    </template>
    <script>
    export default {
      props: {
        buttonText: String
      },
      data() {
        return { times: 0 };
      },
      methods: {
        increment() {
          this.times++;
            ("increment");
        }
      }
    };
    </script>

    2. 调用者监听自定义事件

    <template>
      <div id="app">
        <customButton @increment="handleIncrement"></customButton>
        <customButton @increment="handleIncrement">
          <span style="color:blue">Button 2</span>
        </customButton>
        <customButton @increment="handleIncrement">Button 3</customButton>
        <p>Total click {{totalClicks}} times</p>
      </div>
    </template>
    <script>
    import CustomButton from "./components/ComponentDemo.vue";
    
    export default {
      name: "App",
      components: { CustomButton },
      data() {
        return { totalClicks: 0 };
      },
      methods: {
        handleIncrement() {
          this.totalClicks++;
        }
      }
    };
    </script>

    3. 运行效果

  • 相关阅读:
    宠物的生长(多态)
    程序员和程序狗
    表彰优秀学生(多态)
    [leetcode] Anagrams
    [leetcode] Add Two Numbers
    [leetcode] Add Binary
    [leetcode] 4Sum
    [leetcode] 3Sum Closest
    [leetcode] 3Sum
    函数成员修饰之私有方式
  • 原文地址:https://www.cnblogs.com/WilsonPan/p/12763404.html
Copyright © 2020-2023  润新知