Vue
动态组件
动态组件基本概念
作用
可以让多个组件使用同一个挂载点,并动态切换。
component 本质上是一个占位符,通过 :is 属性来指定渲染谁。
语法
<component :is="vue变量"></component>
例子
创建两个子组件。
子组件1:
<template>
<div>
用户名:<input type="text">
密码:<input type="text">
</div>
</template>
子组件2:
<template>
<div>
用户名:<input type="text">
密码:<input type="text">
</div>
</template>
在 App.vue 中插入动态组件:
<template>
<div>
<h1>动态组件的使用</h1>
<div>
<button @click="change('username')">账号密码</button>
<button @click="change('userinfo')">用户信息</button>
</div>
<component :is="curComp"></component>
</div>
</template>
<script>
import userinfo from "./components/userinfo.vue";
import username from "./components/username.vue";
export default {
data () {
return {
curComp:'username'
}
},
methods: {
change(type){
this.curComp=type
}
},
components: {
username,userinfo
}
}
</script>
在 data 中设置了子组件的变量名,点击按钮改变子组件从而实现动态组件的效果。
组件缓存
动态组件频繁切换会导致频繁销毁和创建组件,不利于提高性能。因此在组件创建出来之后将其缓存起来不被销毁,需要的时候就能使用。
语法
用 keep-alive 将其包裹即可。
<keep-alive>
<component :is="vue变量名"></component>
</keep-alive>
总结:
keep-alive可以把内部的组件进行缓存而非销毁,内部包裹的标签不会被销毁和重新创建,因此能够提高组件的性能。
生命周期补充
组件被缓存起来后钩子函数不会再触发,想要判断某个组件当前是显示还是隐藏状态,需要用到 actived 和 deactivated 这两个钩子。
actived:当前组件显示状态。当组件被激活的时候会自动触发这个生命周期函数。deactived:当前组件隐藏状态。当组件被缓存的时候会自动触发这个生命周期函数。
被缓存的组件不再创建和销毁,也就意味着钩子函数 created 和销毁函数只会触发一次,为了能得知此时组件是否是显示状态,可以通过新的钩子判断其是否被激活。
总结:
当组件第一次被创建的时候,既会触发
created生命周期,也会触发actived生命周期。而组件被激活的时候,只会触发actived生命周期,而不触发created生命周期。
include 属性
用来指定:只有名称匹配的组件会被缓存,多个组件名之间使用英文逗号分隔。
相反的,指定 exinclude 可用来指定被匹配的组件不会被缓存。
注意:
二者只能选其一来使用,不能一起使用。
组件注册与组件声明的区别
- 组件注册 组件注册指在a组件中引入b组件时设置的名称,主要应用场景:把注册好的组件渲染到页面上。
- 组件声明
组件声明指创建好了组件后为其设置一个
name属性,主要应用场景:结合keep-alive标签实现组件缓存功能,以及在调试工具中看到组建的name名称。
插槽
含义
作用
用于实现组件的内容分发, 通过 slot 标签, 可以接收到写在组件标签内的内容。
vue中不仅组件可以动态改变,标签也可以动态改变,提供组件插槽能力, 允许开发者在封装组件时,把不确定的部分定义为插槽。
语法
子组件中:使用以下代码,作用是占位
<slot></slot>
父组件中:插入以下代码,把动态的标签写入其中即可。
<子组件名称></子组件名称>
例子
子组件中,生成一个骨架,把会变化的部分用占位符替换。
<template>
<div>
<slot></slot>
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
父组件中,用引入的子组件 Pannel 包裹动态的标签,多个标签还能实现复用。
<template>
<div>
<div>
<h1>插槽的使用</h1>
<pannel>
<p>哈哈哈哈</p>
<p>我是文字</p>
</pannel>
<pannel>
<ul>
<li>刀刀</li>
<li>刀刀</li>
<li>刀刀</li>
<li>刀刀</li>
</ul>
</pannel>
</div>
</div>
</template>
<script>
import pannel from "./components/pannel.vue";
export default {
components: {
pannel
}
}
</script>
默认内容
如果调用者不传值, 有默认内容就会显示默认内容,默认内容添加在 slot 标签内。
语法
<slot>默认内容</slot>
具名插槽
当一个组件内有2处以上需要外部传入标签的插槽,可以为每个插槽添加名字加以区分。
语法
<slot name="自定义名字"></slot>
默认情况下,在使用组件的时候,提供的内容都会被填充到名字为 default 的插槽中.
- 如果要把内容填充到指定名称的插槽中,需要使用
v-slot这个指令. v-slot:后面要跟上插槽的名字.v-slot:指令不能直接作用在元素身上,必须用在template标签上.template:这个标签是一个虚拟标签,只起到包裹性质的作用,并不会被实际渲染成html元素.
在组件内添加 template 标签,结合 v-slot 或其简写形式 # 进行具名区分。
例子
子组件中定义两个具名插槽。
<template>
<div>
<slot name="title"></slot>
<slot name="content"></slot>
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
父组件分开使用。
<template>
<div>
<pannel>
<template v-slot:title>
<h1>我一路向北</h1>
</template>
<template #content>
<p>离开有你的季节</p>
</template>
</pannel>
</div>
</template>
<script>
import pannel from "./components/pannel.vue";
export default {
components: {
pannel
}
}
</script>
作用域插槽
子组件里的值,给插槽赋值,在父组件环境下使用。
语法
<slot :自定义名称="子组件内的值"></slot>
使用
父组件中用 template 和 v-slot="自定义变量名" 来使用。变量名会收集slot身上属性和值形成对象。
<template v-slot="scope">
<p>{{ scope.自定义名称.子组件内的值 }}</p>
</template>
推荐名称使用 scope ,但想起啥都无所谓。
例子
子组件内定义一个作用域插槽,把对象传过去。
<template>
<div>
<slot name="title"></slot>
<slot :row="obj" name="content"></slot>
</div>
</template>
<script>
export default {
data () {
return {
obj:{
one:'我是1',
two:'我是0'
}
}
}
}
</script>
父组件中接受其值,由于是对象形式的值,想要使用要再点一次。
<template>
<div>
<pannel>
<template #title>
<h1>七里香的滋味</h1>
</template>
<!-- 这里scoped变量只有当前template可以使用 -->
<template #content="chao">
<p>猫和你我都想了解</p>
<p>{{chao.row.two}}</p>
</template>
</pannel>
</div>
</template>
<script>
import pannel from "./components/pannel.vue";
export default {
components: {
pannel
}
}
</script>
注意:
作用域插槽只有当前
template可以使用。
自定义指令
除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令。
局部自定义
定义一个名为focus的指令,指向一个配置对象。
<div v-focus></div>
directives: {
focus: {
inserted(el,binding){
// 这里el表示被引用的标签
}
}
}
当指令第一次被绑定到元素上时,会立即触发一次 inserted 函数。
形参中的el表示当前指令所绑定到的那个dom对象。
binding 可以获取指令绑定的值。
传值
用第二个参数 binding 进行接受传递过来的参数。
<p v-color="colorStr">修改文字颜色</p>
Vue.directive('color', {
inserted(el, binding) {
el.style.color = binding.value
},
})
总结: 全局注册自定义指令, 哪里都能用, 局部注册, 只能在当前
vue文件里用。
注册
在自定义指令的标签注册后只执行一次 inserted 方法,后续发生改变也不会触发,因此需要新的指令 update 来监听。
Vue.directive('color', {
inserted(el) {
},
update(el) {
}
})
后续 dom 更新时都会触发 update 函数。
简写形式
如果 update 和 inserted 方法的代码指令一致,可以直接简写为函数的形式。
foucs(el,binging){
el.style.color = binding.value
}
这样写的方式相当于 update 和 inserted 方法执行一样的指令。
全局自定义
在 main.js 文件中使用。
Vue.directive("自定义名称", {
inserted(el) {
el.focus() // 触发标签的事件方法
}
})
简写形式
Vue.directive("自定义名称", fucntion(el,binding) {
inserted(el) {
el.focus() // 触发标签的事件方法
}
})
ESlint 指令
VScode插件满足ESlint规范要求。
插件一:ESlint,作者:微软 插件二:prettier,作者:prettier
打开设置 setting.json添加配置代码
// ESlint 插件配置
"editor.codeActionsOnSave": {
"source.fixAll": true
},
"eslint.alwaysShowStatus": true,
"prettier.trailingComma": "none",
"prettier.semi": false,
// 每行文字超出限制自动换行
"prettier.singleQuote": true,
"prettier.arrowParens": "avoid",
// 设置vue文件中,html代码的格式化插件
"vetur.format.defaultFormatter.html": "js-beautify-html",
"vetur.ignoreProjectWarning": true,
"vetur.format.defaultFormatterOptions": {
"js-beautify-html": {
"wrap_attributes": false
},
"prettier": {
"trailingComma": "none",
"semi": false,
"singleQuote": true,
"arrowParens": "avoid",
"printWidth": 300
}
},