文章目录
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>
中的内容:
- 作用域插槽
- 具名插槽