1.动态组件component(有点类似于路由跳转)
<temple>
<div>
// component标签是vue内置,作用:组件的占位符
// is属性的值,表示要渲染的组件的名字
// is属性的值,应该是组件在components节点下的注册名称
// keep-alive可以将内部的组件进行缓存,而不是销毁组件
<keep-alive>
<component :is="comName"></component>
</keep-alive>
</div>
</temple>
<script>
import Left from "*********"
export default{
data(){
return{
comName: "Left"
}
},
components: {
Left
}
}
<script>
2.keep-alive的生命周期函数(include="name"表示缓存哪个,exclude="name"表示不缓存哪个)
当组件被缓存时,会自动触发组件的deactivated生命周期函数
当组件被激活时,会自动触发组件的activated生命周期函数
注意点: 注意这个 <keep-alive>
要求被切换到的组件都有自己的名字,不论是通过组件的 name
选项还是局部/全局注册。若没有name,默认是注册时名称
3.slot插槽的使用
// Left.vue组件
<template>
<div>
// vue官方规定:每一个slot插槽,都有一个name名称
// 如果省略了slot的name属性,则有一个默认的名称叫做default
// 插槽中也可以加入默认内容,若插槽没有被使用,便使用了默认内容
<slot name="myLeft">
<h6>这是默认内容</h6>
</slot>
</div>
</template>
// app根组件
<template>
<div>
<Left>
// 默认情况下,在使用组件的时候,提供的内容都会被填充到名字为default的插槽之中
// 如果需要把内容填充到指定名称的插槽中,
// 需要使用v-slot指令,后面跟着插槽名称,则需要在外面包裹template标签
// v-slot只能用在组件上或者是template上,其他标签上面则会报错
<template v-slot:myLeft>
<p>这是在Left组件内容区域的声明的标签</p>
</template>
// v-slot的简写形式为#
<template #myLeft>
<p>这是在Left组件内容区域的声明的标签</p>
</template>
</Left>
</div>
</template>
<script>
import Left from "*******"
export default{
data(){
return {
}
},
components:{
Left
}
}
</script>
作用域插槽的使用
// Content.vue
<template>
<div>
// 若有子组件的内容需要让父组件访问到,则可以使用作用域插槽,下面例子则是把msg传过去
<slot name="content" msg="hello,vue.js"></slot>
</div>
</template>
// app.vue
<template>
<div>
<Content>
// 等号右边的对象是将传过来的msg 和 hello,vue.js 作为属性名和属性值
<template #content="obj">
<div>
{{obj.msg}} // 输出hello,vue.js
</div>
</template>
// 解构赋值
<template #content="{msg}">
<div>
{{msg}} // 输出hello,vue.js
</div>
</template>
</Content>
</div>
</template>
<script>
import Content from "********"
export default{
components: {
Content
}
}
</script>
说明:因为在父组件中无法访问到子组件中的数据,故使用了作用域插槽将数据传递给父组件进行渲染
4.自定义指令的用法
<template>
<div>
<div v-color="'red'">你好哈哈哈</div>
</div>
</template>
<script>
export default{
//私有自定义指令的定义
directives:{
// 定义名为color的指令
color:{
// 当指令第一次被绑定到元素上的时候,会立即触发bind函数
// 形参el 表示当前指令所绑定的那个DOM对象
// 形参binding 是一个对象,属性value就可以拿到传过来的值
bind(el,binding){
el.style.color = binding.value;
},
// bind函数只调用一次,当DOM更新时,bind不会被触发,update函数会在更新后触发
update(el,binding){
el.style.color = binding.value;
}
}
}
}
<script>
函数简写
// 若是在bind和update的代码都是完全一样的,则采用以下简写
<template>
<div>
<div v-color="'red'">你好哈哈哈</div>
</div>
</template>
<script>
export default{
directives:{
color(el,binding){
el.style.color = binding.value;
}
}
}
<script>
全局自定义指令
// 在main.js声明
Vue.directive("color",{
bind(el,binding){
el.style.color = binding.value;
},
update(el,binding){
el.style.color = binding.value;
}
})
// 简写形式,当bind和update里面代码相同可以使用
Vue.directive("color",function(el,binding){
el.style.color = binding.value;
})
6.computed和watch
watch的简单监听
<body>
<div id="app">
<input type="text" v-model="num">
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
num: ''
},
watch: {
num(newVal, oldVal) {
// 监听 num 属性的数据变化
// 作用 : 只要 num 的值发生变化,这个方法就会被调用
// 第一个参数 : 新值
// 第二个参数 : 旧值,之前的值
console.log('oldVal:',oldVal)
console.log('newVal:',newVal)
}
}
})
</script>
</body>
若是需要进入页面就调用,则要把num属性写成对象的形式
<body>
<div id="app">
<input type="text" v-model="num">
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
num: 1
},
watch: {
num: {
// 数据发生变化就会调用这个函数
handler(newVal, oldVal) {
console.log('oldVal:', oldVal)
console.log('newVal:', newVal)
},
// 立即处理 进入页面就触发
immediate: true
}
}
})
</script>
</body>
deep(深度监听)
对象和数组都是引用类型,引用类型变量存的是地址,地址没有变,所以不会触发watch。这时我们需要进行深度监听,就需要加上一个属性 deep,值为 true
<body>
<div id="app">
<input type="button" value="更改名字" @click="change">
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
food: {
id: 1,
name: '冰激凌'
}
},
methods: {
change() {
this.food.name = '棒棒糖'
}
},
watch: {
// 第一种方式:监听整个对象,每个属性值的变化都会执行handler
// 注意:属性值发生变化后,立即处理获得的newVal是undefined
food: {
// 每个属性值发生变化就会调用这个函数
handler(newVal, oldVal) {
console.log('oldVal:', oldVal)
console.log('newVal:', newVal)
},
// 立即处理 进入页面就触发
immediate: true,
// 深度监听 属性的变化
deep: true
},
// 第二种方式:监听对象的某个属性,被监听的属性值发生变化就会执行函数
// 函数执行后,获取的 newVal 值和 oldVal 值不一样
'food.name'(newVal, oldVal) {
console.log('oldVal:', oldVal) // 冰激凌
console.log('newVal:', newVal) // 棒棒糖
}
}
})
</script>
</body>
如果一个数据依赖于多个数据的变化监听得到,则使用computed属性
如果是在监听某个数据,并希望在监听到数据变化后做某些操作,就使用watch
7.vue上的$set
使用场景: 当我们在vue组件中已有对象上加属性和属性值,若是通过 object.属性 或者object[属性] 直接添加,那样就无法实现新添加属性的响应式
解决方案
使用Vue.set(对象,属性,属性值) 或this.$set(对象,属性,属性值),这样就可以实现新添加属性的响应性
8.vue的filters过滤器
使用场景: 可以用在双花括号插值和v-bind表达式
<!-- 在双花括号中 -->
{{ message | capitalize }}
<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>
// 可以在组件中定义本地的过滤器
filters: {
capitalize (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
// 也可以在Vue实例之前定义全局的过滤器
Vue.filter('capitalize', function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
})
过滤器还可以串联
// 这里首先把message作为参数传给了filterA,然后再把filterA的结果传给filterB
{{ message | filterA | filterB }}
// 过滤器是 JavaScript 函数,因此可以接收参数
// 这里接收了3个参数,其中message是第一个
{{ message | filterA('arg1', 'arg2') }}
9.混入mixin
使用场景:当vue组件中有methods或者data等需要被多个组件复用时,我们可以把这些抽取出来为一个js文件,然后使用mixin进行混入,大大提高了组件中的可复用功能(混入对象可以包含组件中的任意选项 data,methods等等)
// 混入形式
// 定义一个混入对象
var myMixin = {
created () {
this.hello()
},
methods: {
hello () {
console.log('hello from mixin!')
}
}
}
// 定义一个使用混入对象的组件
var Component = Vue.extend({
mixins: [myMixin]
})
var component = new Component() // => "hello from mixin!"
注意点:
a.当组件和混入对象的data数据同名重复时,以组件中的data数据为主
b.当混入methods中方法名与组件中的不冲突,则合并到组件中,若是方法名冲突,则以组件为主
c.钩子函数中则会进行合并,而且混入对象的钩子函数会在组件钩子函数之前调用