props属性
props的命名也可以和component一样使用小写单词+-
直接通过对象传递
父组件可以通过v-bind指令,直接将对象传递到子组件,传递的对象和子组件暴露的props名称必须一致!
父组件
<child-component v-bind="paramObj"></child-component>
//...
data(){
return{
paramObj:{
id:1,
name:'testPropName'
}
}
}
上面的写法等同于:id="paramObj.id" :name="paramObj.name"
简化了写法!
子组件
props:['id','name']
不要修改props!
注意props仅仅用于父组件传数据给子组件,而不是反过来,
如果一定需要修改父组件传过来的值
选择新建data属性,并赋值,之后去操作data属性
示例:
props:['fatherCount'],
data(){
return{
count:this.fatherCount
}
}
//之后操作count就可以了!
如果只是调整props的显示格式,也可以使用computed计算属性
computed:{
computeCount:function(){
return '从父组件来了一个'+this.fatherCount
}
}
注意:数组和对象,是作为引用传入的!所以子组件修改了数组和对象,会影响父组件!!!
非Prop的Attribute
子组件没有使用props和emits定义的属性,也可以传递
一遍用于原生的属性,例如class style id change 等等,这些属性会关联到子组件的根节点上!
如果不希望上述的情况发生,需要使用inheritAttrs:false
可以通过**$attr**属性来访问所有的非prop的属性
子组件实现v-model
v-model作为双向绑定是非常好用的指令,如果我们需要在子组件上实现v-model双向绑定,
需要同时实现prop传值+emit提交反馈
子组件
<template>
<input type="text" :value="myName" @input="$emit(update:myName,$event.target.value)" />
</template>
//app.component('model-component'...
props:['myName']
父组件
<model-component v-model:my-name="fatherName"></model-component>
data(){
return {
fatherName:''
}
}
v-modeld的修饰符,子组件可以通过modelModifiers这个prop传递
子组件
prop[‘myName’,‘modelModifiers’]
created(){
console.log(this.modelModifiers.test)
}
父组件
v-model.test:my-name=“fatherName”
插槽
v-slot的简写如下 具体插槽讲解参考官网 内容较多
未具名的插槽写法如下
<parent-node #default="{item}">
<span>{{item.name}}</span>
</parent-node>
具名插槽<slot name="header"></slot>
只需要把#default
改成#header
就可以了
多层嵌套
当出现多层父子组件嵌套,
父组件不需要知道哪个子组件使用了数据
子组件不需要知道某个数据到底来源于那个父组件
这时候可以使用vue的provide、inject属性
父组件
data(){
return{
userName:'john'
}
},
provide(){
return{
user:this.userName
}
}
子组件
inject:['user'],
created(){
console.log(this.user)
}
异步组件
defineAsyncComponent
在有需要的时候再从服务器加载这个模块
ref模板引用
尽量少用ref来直接操作元素!
<input ref="myInput" />
methods:{
focusInput(){
this.$refs.myInput.focus()
}
},
mounted(){
this.focusInput()
}
$refs
只会在组件渲染完成之后生效,尽量避免在模板和计算属性中使用$refs
强制更新组件,
$forceUpdate
可以用来强制更新组件,但是尽量不要使用,大部分情况应该直接使用双向绑定来更新组件