在 vue 中,v-model 是用来进行数据双向绑定的一个语法糖,比如说用在 input 上,输入框数据变化,v-model 绑定的对应的值也会跟着变化,无需单独获取。
其实 v-model 还可以在自定义组件中使用,可以被拆解为 props:value 和 event:input,也就是说组件必须接收一个 value 值以及名为 input 的自定义事件,就可以在自定义组件上使用 v-model 了。
<template>
<input
type="text"
:value="textVal"
@input="$emit('changeMethod', $event.target.value)"
/>
template>
<script>
export default {
props: {
textVal: {
type: String,
default: () => '',
},
},
model: {
props: 'textVal',
event: 'changeMethod',
},
}
script>
<template>
<p>{{ name }}p>
<UseVModel v-model="name" />
template>
<script>
import UseVModel from '@/components/UseVModel.vue'
export default {
components: {
UseVModel,
},
data() {
return {
name: 'rmq',
}
},
}
script>
我个人觉得有点类似于父子组件传值,父组件通过v-model传值,子组件props接收,通过
:value
,绑定值,然后通过$emit()
触发事件又传值给父组件,实现双向绑定。
$nextTick() 是在下次DOM更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中获取更新后的DOM(DOM的改变是发生在 $nextTick()之后),这个方法作用是当数据被修改后使用这个方法,会回调获取更新后的DOM再render出来。
$nextTick()作用:在下次DOM更新循环结束之后,执行延迟回调。在修改数据之后立即使用这个方法,获得更新后的DOM。
<template>
<div>
<ul ref="ul1">
<li v-for="(item, index) in list" :key="index">{{ item }}li>
ul>
<button @click="change">添加button>
div>
template>
<script>
export default {
data() {
return {
list: ['a', 'b', 'c'],
}
},
methods: {
change() {
this.list.push(`${Date.now()}`)
this.list.push(`${Date.now()}`)
this.list.push(`${Date.now()}`)
// 直接这样写,获取到的是渲染之前的3个
// const ul = this.$refs.ul1
// console.log(ul.childNodes.length)
//this.$nextTick()
// vue 是 异步渲染,this.$nextTick()待 DOM 渲染完成后再回调
// 页面渲染时会将 data 修改整合, 多次的 data 修改 只会渲染一次
this.$nextTick(() => {
const ul = this.$refs.ul1
console.log(ul.childNodes.length)
})
},
},
}
script>
<template>
<div class="home">
<NextTick />
div>
template>
<template>
<div>
<a :href="url">
<slot :slotData1="slotData1"
name="rmq">父组件没有东西时显示默认内容slot>
a>
div>
template>
<script>
export default {
data () {
return {
slotData1: {
url: 'www.baidu.com1',
title: 'slot1',
subTitle: 'hello slot1',
},
}
},
props: {
url: {
type: String,
default: '',
},
},
}
script>
<template>
<div class="home">
<SlotDemo :url="slotData.url"
#rmq>SlotDemo>
<SlotDemo :url="slotData.url"
#rmq>
<template>{{ slotData.title }}template>
SlotDemo>
<SlotDemo :url="slotData.url">
<template #rmq="SlotProps">
{{ SlotProps.slotData1.subTitle }}
template>
SlotDemo>
div>
template>
<script>
import SlotDemo from '@/components/SlotDemo.vue'
export default {
components: {
SlotDemo,
},
data() {
return {
slotData: {
url: 'www.baidu.com',
title: 'slot',
subTitle: 'hello slot',
},
}
},
}
script>
props
和v-slot
配合也可以用来父子组件之间传值
一个页面的构成可以动态控制
<template>
<div>
<div v-for="(val, key) in comList" :key="key">
<component :is="val.componentName">component>
div>
div>
template>
<script>
export default {
data() {
return {
comList: {
1: { componentName: 'text' },
2: { componentName: 'text' },
3: { componentName: 'image' },
},
}
},
}
script>
通过
,来动态加载组件
对于大的组件或者有异步加载组件需求的时候可以用
<template>
<div class="home">
<WatchEventCom v-if="showCom">WatchEventCom>
<button @click="showCom = true">异步加载组件button>
<hr />
div>
template>
<script>
export default {
components: {
WatchEventCom: () => import('@/components/WatchEvent'), //如果同时引入2个相同组件,则不会异步加载,没有效果
Mixin,
},
data() {
return {
showCom: false,
}
},
}
script>
include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存。
max - 数字。最多可以缓存多少组件实例。
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和
相似,
是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。
当组件在内被切换,它的
activated
和deactivated
这两个生命周期钩子函数将会被对应执行。
<keep-alive>
<component :is="view">component>
keep-alive>
<keep-alive>
<comp-a v-if="a > 1">comp-a>
<comp-b v-else>comp-b>
keep-alive>
<transition>
<keep-alive>
<component :is="view">component>
keep-alive>
transition>
<keep-alive include="a,b">
<component :is="view">component>
keep-alive>
<keep-alive :include="/a|b/">
<component :is="view">component>
keep-alive>
<keep-alive :include="['a', 'b']">
<component :is="view">component>
keep-alive>
<keep-alive :max="10">
<component :is="view">component>
keep-alive>
注意,
是用在其一个直属的子组件被开关的情形。如果你在其中有 v-for 则不会工作。如果有上述的多个条件性的子元素,
要求同时只有一个子元素被渲染。
export default {
data() {
return {
name: 'rmq'
}
},
mounted() {
console.log('mixin');
},
methods: {
mixinMethod() {
console.log('点击了mixin');
}
},
}
<template>
<div>
<p>name:{{name}}p>
<p>age:{{age}}p>
<button @click="mixinMethod">clickbutton>
div>
template>
<script>
import mixin from '../assets/mixin';
export default {
mixins: [mixin],
data () {
return {
age: '18'
};
},
}
script>
可以看到组件中能够使用mixin,js中的data/methods等的数据方法。相当于把2个合并了。
这样可以抽离一些相同的逻辑,但是会有数据冲突
// 为自定义的选项 'myOption' 注入一个处理器。
Vue.mixin({
created: function () {
var myOption = this.$options.myOption
if (myOption) {
console.log(myOption)
}
}
})
new Vue({
myOption: 'hello!'
})
// => "hello!"