面试整理 - VUE篇

Vue的使用

v-html

  • 有xss风险
  • 使用v-html后将会覆盖子元素
<p v-html="<a>覆盖子元素</a>">
	<span>有 xss 风险</span>
</p>

computed有缓存,data不变则不会重新计算

<template>
  <div>
    <p>{{ num }}</p>
    <p>{{ double1 }}</p>
    <input v-model="double2" />
  </div>
</template>
<script>
export default {
  name:'yyy',
  data() {
    return {
      num: 20,
    };
  },
  computed: {
    double1() {
      return this.num * 2;
    },
    double2: {
      get() {
        console.log('val');
        return this.num * 2;
      },
      set(val) {
        console.log(val);
        this.num = val / 2;
      },
    },
  },
};
</script>

watch如何深度监听?

watch监听引用类型拿不到oldVal

<template>
  <div>
    <input v-model="name" />
    <input v-model="info.city" />
  </div>
</template>
<script>
export default {
  name: "yyy",
  data() {
    return {
      name: "yyy",
      info: {
        city: "Bijing",
      },
    };
  },
  watch: {
    name(oldVal, val) {
      console.log("watch name", oldVal, val); // 值类型,可正常拿到oldval
    },
    info: {
      handler(oldVal, val) {
        console.log("watch info", oldVal, val); // 引用类型拿不到oldval,因为指针相同
      },
      deep: true, // 深度监听
    },
  },
};
</script>

class 和 style

<template>
  <div>
    <p :class="{ black: isBlack, yellow: isYellow }"></p>
    <p :class="[black, yellow]"></p>
    <p :style="styleData"></p>
  </div>
</template>
<script>
export default {
  name: "yyy",
  data() {
    return {
      isBlack: true,
      yellow: false,

      black: "black",
      yellow: "yellow",

      styleData: {
        fontSize: "40px",
        backgroundColor: "#ccc",
      },
    };
  },
};
</script>

条件渲染 v-if v-show

切换频繁的话选择v-show,减少dom渲染的消耗。切换不频繁的话两个都可以。

循环(列表)渲染

v-for和v-if不能一起使用,因为v-for计算优先级高于v-if,遍历后每一项再进行v-if判断,计算次数很多。可以将v-if放在v-for的外层或内层。

<template>
  <div>
    <p>遍历数组</p>
    <ul>
      <li v-for="(item, index) in listArr" :key="item.id">
        {{ index }} - {{ item.id }} - {{ item.title }}
      </li>
    </ul>
    
    <p>遍历对象</p>
    <ul>
      <li v-for="(val, key, index) in listObj" :key="key">
        {{ index }} - {{ key }} - {{ val.title }}
      </li>
    </ul>
  </div>
</template>
<script>
export default {
  name: "yyy",
  data() {
    return {
      listArr: [
        {
          id: "a",
          title: "title1",
        },
        {
          id: "b",
          title: "title2",
        },
        {
          id: "c",
          title: "title3",
        },
      ],
      listObj: {
        a: { title: "title1" },
        b: { title: "title2" },
        c: { title: "title3" },
      },
    };
  },
};
</script>

事件

事件被绑定到哪里?

<template>
  <div>
    <!-- 有额外参数时如何传event -->
    <p>{{ num }}</p>
    <button @click="increment1">+1</button>
    <button @click="increment2(2, $event)">+2</button>
  </div>
</template>
<script>
export default {
  name: "yyy",
  data() {
    return {
      num: 0,
    };
  },
  methods: {
    increment1(e) {
      console.log(e.__proto__.constructor); // ƒ MouseEvent() 是原生的event对象
      this.num++;
      // event是原生的
      // 事件被挂载到当前元素
    },
    increment2(val, e) {
      console.log(val, e);
      this.num += val;
    },
  },
};
</script>

事件修饰符

<template>
  <div>
    <!-- 阻止单机事件继续传播 -->
    <a v-on:click.stop="doThis"></a>
    <!-- 提交事件不再重载页面 -->
    <form v-on:submit.prevent="onSubmit"></form>
    <!-- 修饰符可以串联 -->
    <a v-on:click.stop.prevent="doThat"></a>
    <!-- 只有修饰符 -->
    <form v-on:submit.prevent></form>
    <!-- 添加事件监听时使用事件不火模式 -->
    <!-- 即内部元素出发的事件先再次处理,然后才交由内部元素进行处理 -->
    <div v-on:click.capture="doThis"></div>
    <!-- 只当在event.target是当前元素自身时触发处理函数 -->
    <!-- 即事件不是从内部元素触发的 -->
    <div v-on:click.self="doThat"></div>
  </div>
</template>

按键修饰符

<template>
  <div>
    <!-- 即使 Alt 或 Shift 被一同按下也会触发 -->
    <button @click.ctrl="onclick"></button>
    <!-- 有且只有 Ctrl 被按下时触发 -->
    <button @click.ctrl.exact="onCtrlclick"></button>
    <!-- 没有任何修饰符被按下时触发 -->
    <button @click.exact="onCtrlclick"></button>
  </div>
</template>

父子组件通讯 props $emit

接收props的两种写法

  props: ["list"],
  props: {
    list: {
      type: Array,
      default() {
        return [];
      },
    },
  },

非父子组件通讯 $on

在一个组件中绑定一个自定义事件:

import event from './event';
...
event.$on('onAddTitle', this.addTitleHandler);

在另外一个组件中触发自定义事件

import event from './event';
...
event.$emit('onAddTitle', this.title);

vue已经实现了$on $emit等自定义事件的能力,直接用即可。

// event.js
import Vue from 'vue';
export default new Vue();

注意,在解绑组件时要销毁:

beforeDestroy() {
	// 及时销毁,否则可能造成内存泄漏
	event.$off('onAddTitle', this.addTitleHandler);
}

生命周期

在这里插入图片描述

Vue高级特性

- 自定义v-model
// computed.vue
<template>
  <div>
    <p>{{ name }}</p>
    <CustomVModel v-model="name" />
  </div>
</template>
<script>
import CustomVModel from "./CustomVModel";
export default {
  components: { CustomVModel },
  data() {
    return {
      name: "yyy",
    };
  },
};
</script>

子组件:

// CustomVModel.vue
<template>
  <div>
    <!-- ;例如:vue 颜色选择器 -->
    <input
      type="text"
      :value="inputName"
      @input="$emit('handlerChange', $event.target.value)"
    />
    <!-- 
      1. 上面的 input 使用了 :value 而不是v-model
      2. 上面的 handlerChange 和 model.event 对应起来
      3. inputName 属性对应起来
     -->
  </div>
</template>
<script>
export default {
  model: {
    prop: "inputName", // 对应 props inputName
    event: "handlerChange",
  },
  props: {
    inputName: {
      type: String,
      default() {
        return "";
      },
    },
  },
  name: "yyy1",
};
</script>
- $nextTick refs

vue 是异步渲染的框架
data改变之后,DOM不会立即渲染。$nextTick会在DOM渲染,以获得最新DOM节点
在这里插入图片描述

- slot
  • 基础用法,slot相当于react里面的.children,如果调用时没有传标签里面的内容,则显示<slot></slot>中的内容:
    在这里插入图片描述
  • 作用域插槽
    在这里插入图片描述
  • 具名插槽
- 动态、异步组件
- keep-alive
- mixin

Vue的原理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值