03 Vue高级特性

  • 不是每个都很常用,但用到的时候都必须要知道。
  • 考察候选人对Vue的掌握是否全面,且由深度。
  • 考察做过的项目是否有深度和复杂度(至少用到高级特性)
  • 自定义 v-mdel
  • $nextTick
  • slot
  • 动态、异步组件
  • keep-alive
  • mixin
  • refs

3-1vue如何自己实现v-model

1.父组件index.vue,子组件CustomVMode.vue
在父组件中引入子组件。

<p>{{name}}</p>
    <CustomVModel v-model="name"></CustomVModel>

2.子组件CustomVMode.vue

<template>
  <input :value="text" type="text" @input="$emit('change', $event.target.value)" />
</template>

<script>
export default {
  name: "CustomVModel",
  model: {
    prop: "text",
    event: "change"
  },
  props: {
    text: {
      type: String,
      default: ""
    }
  }
};
</script>

解析:
(1)上面的input 使用了:value 而不是v-model
(2)上面的change和model的event对应起来。
(3)text属性对应起来。

3-2 $nextTick 和 $refs

  • Vue是异步渲染
  • data改变之后,DOM不会立刻渲染。
  • $nextTick 会在DOM渲染之后被触发,以获取最新DOM节点。
<template>
  <div>
    <button @click="addItem">Add</button>
    <ul ref="ul1">
      <li v-for="(item, index) in list" :key="index">{{item}}</li>
    </ul>
  </div>
</template>

<script>
export default {
  name: "app",
  data() {
    return {
      list: ["a", "b", "c"]
    };
  },
  methods: {
    addItem() {
      this.list.push(Date.now());
      this.list.push(Date.now());
      this.list.push(Date.now());

      // 添加完想立刻获取长度, 不能及时拿到
      // 要用nextTick等渲染完了才能获取准确的dom个数
      this.$nextTick(() => {
        console.log(this.$refs.ul1.childNodes.length);
      });
      // console.log(this.$refs.ul1.childNodes.length);
    }
  }
};
</script>

定义:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
所以就衍生出了这个获取更新后的DOM的Vue方法。所以放在Vue.nextTick()回调函数中的执行的应该是会对DOM进行操作的 js代码;
理解:nextTick(),是将回调函数延迟在下一次dom更新数据后调用,简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数,

3-3 slot是什么?

  • 基本使用
  • 作用域插槽
  • 具名插槽

基本使用:

在组件App.vue中引入SlotDemo.vue

<SlotDemo :url="website.url">{{website.title}}</SlotDemo>
...
data() {
    return {
      website: {
        url: 'http://imooc.com/',
        title: 'imooc',
        subTitle: '程序员的梦工厂'
      }
    };
  }

SlotDemo.vue

<template>
  <a :href="url">
    <slot>默认插槽文字</slot>
  </a>
</template>

<script>
export default {
  name: "SlotDemo",
  props: {
    url: {
      type: String,
      default: ""
    }
  }
};
</script>

解析:通过父向子属性传值,在props中接收了传来的url,slot是插槽,如果父级为没有插入时即App.vue中 ,删去下面的{{website.title}},会显示默认的。

<SlotDemo :url="website.url">{{website.title}}</SlotDemo>

现在由于有插入,所以显示的时{{website.title}},即imooc
在这里插入图片描述
插槽的意义是让父组件往子组件插入一段内容。

作用域插槽:
理解:把子组件里的数据通过slot让父组件获取到。

子组件ScopedSlotDemo.vue

<template>
  <a :href="url">
    <slot :slotData="website">
      {{website.subTitle}} //默认字显示subTitle, 即父组件不传
    </slot>
  </a>
</template>

<script>
export default {
  name: "ScopedSlotDemo",
  props: {
    url: {
      type: String,
      default: ""
    }
  },
  data() {
    return {
       website: {
        url: 'http://wangEditor.com/',
        title: 'wangEditor',
        subTitle: '轻量级富文本编辑器'
      }
    };
  }
};
</script>

解析:在子组件中slot中绑定属性,值为data中的website,在作用域插槽中的是父组件不传时显示的。

 <slot :slotData="website">
      {{website.subTitle}} //默认字显示subTitle, 即父组件不传
    </slot>

父组件在App.vue里,在App.vue里引入了ScopedSlotDemo.vue。

<ScopedSlotDemo :url="website.url">
      <template v-slot="slotProps">
        {{slotProps.slotData.subTitle}}
      </template>
    </ScopedSlotDemo>

解析:关于作用域插槽的理解,主要在父组件中即可。
(1)通过在父组件的template标签中通过v-slot="slotProps"定义作用域插槽名称。
(2)插值表达式{{slotProps.slotData.subTitle}}中的slotData必须和子组件slot绑定属性名一样。

slot-具名插槽

在这里插入图片描述

3-4 动态组件

  • :is = “component-name” 用法
  • 需要根据数据,动态渲染的场景。即组件类型不确定。
    在这里插入图片描述
<div v-for = "(val, key) in newsData :key = "key">
  <component :is="val.type" />
</key>
...
newsData: {
   1: {
     type: 'text'
   },
   2: {
     type: 'image'
   }
}

3-5 异步组件

  • import()函数
  • 按需加载,异步加载大组件
<FormDemo v-if = "showFormDemo" />
<button @click="showFormDemo = true">show form demo</button>
...
export default {
  components: {
    FormDemo: () => import('../BaseUse/FormDemo')
  }
},
data () {
  showFormDemo: false
}

解析:通过v-if首先把显示默认为false,再通过在button控制,在components中import。

3-6 keep-alive

  • 缓存组件
  • 频繁切换,不需要重复渲染
  • Vue常见性能优化
<button @click="changeState('A')">A</button>
    <button @click="changeState('B')">B</button>
    <button @click="changeState('C')">C</button>

    <keep-alive>
      <KeepAliveStageA v-if="state === 'A'"></KeepAliveStageA>
      <KeepAliveStageB v-if="state === 'B'"></KeepAliveStageB>
      <KeepAliveStageC v-if="state === 'C'"></KeepAliveStageC>
    </keep-alive>

通过引入keepAliveStageABC,把组件包裹在标签中,通过button控制显示。

3-7vue组件如何抽离公共逻辑 mixin

  • 多个组件有相同的逻辑,抽离出来
  • mixin 并不是完美的解决方案,会有一些问题
  • vue 3 提出的Composition API旨在解决这些问题
    mixin.js
export default {
  data() {
    return {
      city: "深圳",
    };
  },
  mounted() {
    console.log("mixin mounted", this.name);
  },
  methods: {
    showName() {
      console.log(this.name);
    },
  },
};

MixinDemo.vue

<template>
  <div>
    <p>{{name}} - {{major}} - {{city}}</p>
    <button @click="showName">显示姓名</button>
  </div>
</template>

<script>
import mixin from "./mixin";

export default {
  name: "MixinDemo",
  mixins: [mixin], 
  data() {
    return {
      name: "Bruski",
      major: "Web 前端"
    };
  },
  methods: {},
  mounted() {
    console.log("this mounted");
  }
};
</script>

解析:通过在组件中引入mixin,mixins: [mixin](可以混入多个)把mixin中的逻辑引入。如下图,在MixinDemo.vue并没有直接声明city和showName()方法,都是靠mixin混入进去的。
在这里插入图片描述

mixin的缺点:

  • 变量来源不明确,不利于阅读。
  • 多mixin可能造成变量命名冲突。
  • mixin 和组件可能出现多对多的关系,复杂度较高。

3-8 Vuex使用

  • 面试考点并不多(因为熟悉Vue之后,vuex没有难度)
  • 但基本概念,基本使用和API必须要掌握。
  • 可能会考察state的数据结构设计。
  • dispatch mapGetters
  • commit mapActions
  • state mapstate
    actions才能异步操作。
    在这里插入图片描述

3-9 Vue-router 使用

  • 路由模式 (hash、H5、history)
  • 路由配置(动态路由、懒加载)

路由模式:

  • hash模式(默认),如http://abc.com/#/user/10
  • H5 history模式,如http://abc.com/user/20

路由配置 动态路由:
在这里插入图片描述
路由配置 懒加载:
在这里插入图片描述
在不同的路由下异步加载不同的路由。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值