ref的使用 动态组件 插槽 自定义指令

757 阅读4分钟

ref

获取DOM元素
  1. ref用来辅助开发者在不依赖于jQuery的情况下 获取DOM元素或组件的引用
  2. 每个vue的组件实例上 都包含一个$refs对象 里面存储着对应的DOM元素或组件的引用,默认情况下,**组件的refs指向一个空对象给元素添加ref属性通过this.refs指向一个空对象** 给元素添加ref属性 通过this.refs.xxx前面ref的属性值 名字不能冲突 否则后面的会覆盖前面的
    <h1 ref="myh1">App 根组件</h1>
    <button @click="dayin">打印this</button>
    
    methods: {
    dayin() {
      // console.log(this.$refs.myh1);
      this.$refs.myh1.style.color = "red";
    },
  },
获取组件

给组件的标签添加ref属性 就可以获取到子组件中的方法

//父组件的内容  父组件操作子组件里面的方法
 <button @click="onReset">重置left组件的count值为0</button>
  <Left ref="comLeft"> </Left>
  
  methods: {
    onReset() {
      this.$refs.comLeft.resetCount();
      // this.$refs.comLeft.count = 0;
    },
  },
  

初步实现按钮和文本框的按需展示 了解this.$nextTick的应用场景 延迟cb(call back 回调函数)的代码 延迟到当DOM渲染完毕之后再去执行

    <input type="text" v-if="inputVisible" @blur="shouBtn" ref="iptRef" />
    <button v-else @click="showInput">展示输入框</button>
    
    data() {
    return {
      // 控制输入框和按钮的按需切换
      // 默认值为false 表示默认展示按钮 隐藏输入框
      inputVisible: false,
    };
  },
  methods: {
    // 点击按钮展示输入框
    showInput() {
      // 1.切换布尔值 把文本框展示出来
      this.inputVisible = true;
      // 让展示出来的文本框 自动获取焦点
      this.$nextTick(() => {
        this.$refs.iptRef.focus();
      });
    },
    //  当文本框失去焦点的时候 显示按钮
    shouBtn() {
      this.inputVisible = false;
    },
  },

动态组件

  • 动态组件指的是 动态切换组件的显示和隐藏
  • vue提供了一个内置的 <component> 组件 专门用来实现动态组件的渲染
  1. component标签 是vue内置的 作用是 组件的占位符
  2. is属性的的值表示要渲染的组件的名字

    <button @click="comName = 'Left'">展示 Left</button>
    <button @click="comName = 'Right'">展示 Right</button>
    <component :is="comName"></component>
  
使用kepp-alive保持状态
  1. 把动态组件包裹到里面即可 kepp-alive 可以把内部的组件进行缓存 而不是销毁组件
  • 当组件被缓存时 会自动触发组件的deactivated生命周期函数
  • 当组件被激活时 会自动触发组件的activated生命周期函数
  • 当组件第一次被创建的时候 既会执行created生命周期也会执行activated生命周期
  • 但是当组件被激活的时候 只会触发activated生命周期 不再触发created 因为组件没有被重新创建
    <keep-alive>
        <component :is="comName"></component>
      </keep-alive>
  1. include属性 告诉keep-alive哪些组件是需要被缓存的 exclude排除项 让谁不被缓存 不能同时使用
  • 只有名称匹配的组件会被缓存 多个组件名之间使用英文的逗号分隔
      <keep-alive include="Left,Right">
        <component :is="comName"></component>
      </keep-alive>

插槽

插槽(Slot)是vue为组封装者提供的能力 允许开发者封装组件时 把不确定的 希望由用户指定的部分定义为插槽

      <Left>
      //可以自动填充到插槽所在位置
        <p>这是在Left组件的内容区域声明的p标签</p>
      </Left>

    <!-- 插槽区域 -->
    <slot></slot>

vue官方规定 每一个slot插槽 都要有一个name名称 如果省略了slot的name属性 则有一个默认名称叫做default

  1. 如果要把内容填充到指定名称的插槽中 使用v-slot: 指令 简写形式 #
  2. v-slot: 后面要跟上插槽的名字
  3. v-slot: 不能直接用在元素身上 必须用在 template 标签上
  4. template标签 是一个虚拟的标签 只起到包裹性质的作用 不会被渲染到任何实质性html元素
        <template v-slot:default>
          <p>这是在Left组件的内容区域声明的p标签</p>
        </template>
        
    <slot name="default"></slot>

如果用户没有指定内容 放一个默认内容 直接在插槽中书写即可 如果用户自定义了 会覆盖插槽里的默认内容

<slot name="default">这是default插槽的默认内容</slot>
具名插槽 带有具体名字的插槽

如果封装期间有多个插槽 要给每个插槽起个名字

作用域插槽

在封装组件时 为预留的提供属性对应的值 这种用法叫做 作用域插槽 可以写死 写可以动态绑定一个 也可以添加组件


      <template v-slot:title="scope">
        <h3>一首诗----{{ scope.msg }}</h3>
      </template>
      <slot name="title" msg="hello vue.js"></slot>

自定义指令

  • 私有自定义指令
  1. 在每个vue组件中 可以在directives节点下声明私有自定义指令 与data节点平级
  2. bind函数只会在第一次绑定上去的时候才会被触发 当DOM更新时 bind函数不会被触发
  3. update函数会在每次DOM更新时被调用
    <h1 v-color="color">App 根组件</h1>
    <p v-color="'red'">测试</p>
    <button @click="color = 'green'">改变color的颜色值</button>

data() {
    return {
      color: "blue",
    };
  },
   
// 私有自定义指令节点
  directives: {
    // 定义名为color的指令 指向一个配置对象
    color: {
      // 当指令第一次被绑定到元素上时会立即触发bind函数
      // 形参中的el 表示当前指令所绑定到的那个DOM对象
      bind(el, binding) {
        el.style.color = binding.value;
      },
      // 在DOM更新的时候会触发updata函数
      update(el, binding) {
        console.log("触发");
        el.style.color = binding.value;
      },
    },
    //可以简写为
    color(el, binding) {
      el.style.color = binding.value;
    },
  },
  • 全局自定义指令