https://www.jb51.net/article/266060.htm
父传子
1.页面的复用
所有的 props 都遵循着单向绑定原则,props 因父组件的更新而变化,自然地将新的状态向下流往子组件,而不会逆向传递。这避免了子组件意外修改父组件的状态的情况,不然应用的数据流将很容易变得混乱而难以理解。
另外,每次父组件更新后,所有的子组件中的 props 都会被更新到最新值,这意味着你不应该在子组件中去更改一个 prop。若你这么做了,Vue 会在控制台上向你抛出警告:
props:用对象的写法,type类型:
String
Number
Boolean
Array
Object
Date
Function
Symbol
在使用 script setup的单文件组件中,props 可以使用 defineProps() 宏来声明:
<script setup>
const props = defineProps(['foo'])
console.log(props.foo)
</script>
<!-- 父传子通过 props传递-->
<template>
<Navbar mytitle="电影"></Navbar>
<Navbar :mytitle="propertyTitle" ></Navbar>
</template>
<script>
import Navbar from './components/父传子/Nav.vue'
export default{
components:{
Navbar
},
data(){
return{
propertyTitle:'hhhhh'
}
}
}
</script>
<template>
<ul>
<li v-show="isShow">返回</li>
<li>{{ mytitle }}</li>
<li>确定</li>
</ul>
</template>
<script>
export default {
// props: ["mytitle"],
props:{
mytitle:String,
isShow:{
type:Boolean,
default:true
}
}
}
</script>
子传父
在组件的模板表达式中,可以直接使用 $emit
方法触发自定义事件 (例如:在 v-on
的处理函数中)
<template>
<Navbar @event="hindelBtn"></Navbar>
<!-- <button @click="isShow=!isShow">btn</button> -->
<Sidebar v-show="isShow"></Sidebar>
</template>
<script>
import Sidebar from './components/子传父/Sidebar.vue';
import Navbar from './components/子传父/Navbar.vue'
export default {
components: {
Navbar,
Sidebar
},
data(){
return{
isShow:false
}
},
methods:{
hindelBtn(data){
this.isShow=!this.isShow
console.log(data);
}
}
}
</script>
<template>
<!-- navbar-<button @click="this.$emit('event')">展开/收起</button> -->
navbar-<button @click="handle">展开/收起</button>
</template>
<script>
export default{
methods:{
handle(evt){
this.$emit('event','子组件')
}
}
}
</script>
<template>
<ul>
<li>1111</li>
<li>2222</li>
<li>3333</li>
</ul>
</template>
$refs父组件的强权
<template>
<field label="用户名" type="text" ref="username"></field><br>
<field label="密码" type="password" ref="pwd"></field><br>
<button @click="hindleLogin">登录</button>
<button @click="hindleReset">重置</button>
</template>
<script>
import field from './ref-login.vue'
export default{
components:{
field
},
methods:{
hindleLogin(){
console.log(this.$refs.username.myvalue,this.$refs.pwd.myvalue);
},
hindleReset(){
this.$refs.username.myvalue=""
this.$refs.pwd.myvalue=""
}
}
}
</script>
<template>
<label>{{ label }}</label>
<input :type="type" v-model="myvalue">
</template>
<script>
export default{
props:["label","type"],
data(){
return{
myvalue:''
}
}
}
</script>
root 子组件访问父组件
<template>
app
<div v-show="isShow">alkfjsal</div>
<sidebar></sidebar>
</template>
<script>
import sidebar from './child.vue'
export default{
components:{
sidebar
},
data(){
return{
isShow:true
}
}
}
</script>
<template>
child
<button @click=hindleShow>show</button>
</template>
<script>
export default{
methods:{
hindleShow(){
this.$parent.isShow=!this.$parent.isShow
console.log(this.$root);
console.log(this.$parent);
}
}
}
</script>
跨级通信 provide & inject
<template>
app
<navbar></navbar>
<tabbar></tabbar>
</template>
<script>
import navbar from './navbar.vue'
import tabbar from './tabbar.vue'
export default{
components:{
navbar,
tabbar
},
data(){
return{
title:'首页'
}
},
provide(){
return{
shareTitle:this
}
}
}
</script>
<template>
<div style="margin: 0 auto; width:50px;">{{shareTitle.title}}</div>
</template>
<script>
export default{
inject:["shareTitle"]
}
</script>
<template>
<ul>
<li v-for="item in dataList" :key="item.name" @click="hindleName(item.name)">
{{ item.name }}
</li>
</ul>
</template>
<script>
export default{
inject:['shareTitle'],
data(){
return{
dataList:[
{
name:'首页'
},
{
name:'列表'
},
{
name:'我的'
}
]
}
},
methods:{
hindleName(val){
this.shareTitle.title=val
}
}
}
</script>
<style scoped lang="scss">
ul{
list-style: none;
display: flex;
flex-direction: row;
justify-content: space-around;
position: absolute;
bottom: 0;
width: 100%;
}
</style>
动态组件 component
<template>
<Navbar></Navbar>
<Tabbar></Tabbar>
<KeepAlive include="Home">
<component :is="obj[title]" ></component>
</KeepAlive>
</template>