父传子靠属性,子传父靠事件
父传子:
<body>
<div id="app">
<!-- 此处父组件向子组件传递name值 注意:动态值要加bind 也就是:-->
<navbar name="首页" :show="true"></navbar>
<navbar name="侧边栏" :show="false"></navbar>
<navbar :name="parentname" :show="false"></navbar>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 此处为定义的组件名navbar
Vue.component("navbar", {
template: `
<div>
<button v-show="show">返回</button>
navbar------ {{name}} 注意:此处渲染的是props中父组件传过来的属性名name
</div>
`,
/* props属性 */
/* props: ["name", "show"] */
/* 属性验证限制(限制父组件传递过来属性的类型) */
props: {
name: String, //此处子组件接收(name)传过来之后,可直接使用该值(类型设定为String,父组件只能传string类型的name,否则报错)
show: Boolean
}
})
new Vue({
el: "#app",
data() {
return {
parentname: '哈哈'
}
},
})
</script>
</html>
子传父
<body>
<div id="app">
<!-- 父组件在此处定义银行卡号myevent -->
<!-- $event固定写法 -->
<child @myevent="getMoney($event)"></child>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.component("child", {
template: `
<div>
<button @click="forMoney">打钱</button>
</div>
`,
data() {
return {
childname: '字组件状态'
}
},
methods: {
/* 点击按钮此方法触发打钱行为 */
forMoney() {
this.$emit('myevent', this.childname)) /* 子组件通过this.$emit方法向父组件打钱,myevent好比是银行卡号 this.childname为钱数也就是要传的值 */
}
},
props: {
}
})
new Vue({
el: "#app",
data() {
return {
childnames: '字组件状态'
}
},
methods: {
getMoney(ev) { /* 此处ev就是子组件传过来的参数 */
alert('父组件收到钱了' + ev)
}
},
})
</script>
</html>
ref父子组件传值
<body>
<div id="app">
<div>
<!-- ref放在标签上,拿到的是该标签原生dom节点
ref放在组件上,拿到的是组件对象 -->
<input type="text" ref="mytext"><button @click="handleRef">点击</button>
<child ref="mychild"></child>
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.component("child", {
template: `
<div>child</div>
`,
data() {
return {
childname: '我是子组件'
}
},
methods: {
// 子组件abc方法
abc(data) {
console.log('哈哈')
console.log(data)//此处子组件接收data打印"孩子听话"
}
}
})
new Vue({
el: "#app",
data() {
return {
}
},
methods: {
handleRef() {
console.log(this.$refs.mytext.value) // 获取文本框的值
this.$refs.mychild.abc()//此处父组件可通过this.$refs.mychild.abc()直接调用子组件的方法(this.$refs.mychild获得的是该组件的组件对象)
this.$refs.mychild.abc("孩子听话")// 父组件可通过调用该方法直接给子组件传值(这里传了"孩子听话")
}
}
})
</script>
</html>
链接https://blog.csdn.net/weixin_42983021/article/details/90169363(详细说明)
非父子组件之间的通信(兄弟组件或爷孙组件等所有组件间的通信)
<body>
<div id="app">
<author></author>
<user></user>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var bus = new Vue();//定义new Vue实例为时间总线,总有组件可通过此方式进行组件通信
// 比如微信公众作者发布文章,订阅用户在第一时间就获取到了发布的文章
// 作者组件
Vue.component("author", {
template: `
<div style="background:yellow">
我是作者
<input type="text" ref="mytext"></input>
<button @click="hanldeArt">发布文章</button>
</div>
`,
methods: {
hanldeArt() {
// 作者此处在message账号(和下面用户订阅账号一致)通过bus.$emit进行文章发布(this.$refs.mytext.value为获取input输入框的文章进行发布)
bus.$emit("message", this.$refs.mytext.value)
}
}
})
// 用户组件
Vue.component("user", {
template: `
<div style="background:red;margin-top:200px">
我是用户
</div>
`,
methods: {
hanldeArt() {
}
},
mounted() {
// 此处微信用户先通过bus.$on进行订阅,定义message可理解为订阅作者的账号。订阅后开始监听作者是否发布文章
bus.$on("message", (data) => {// 用户此处data为作者发布的文章信息
console.log('我接收到了消息', data)
})
}
})
new Vue({
el: "#app",
data() {
return {
}
},
})
</script>
</html>
动态组件:
<style>
footer {
width: 100%;
position: absolute;
bottom: 0;
}
footer ul {
display: flex;
justify-content: space-around;
}
</style>
</head>
<body>
<div id="app">
<!-- component组件的is属性可以选择让那个组件进行渲染 用法为is="组件名" -->
<!-- 注意cpmponent的:is组件切换会直接删除组件,等下次在切换回来时再重新渲染,如果要保持组件状态,需要加keep-alive进行状态保持,
也就等于是将不需要显示的组价隐藏起来而不是删除 -->
<keep-alive>
<component :is="who"></component>
</keep-alive>
<footer>
<ul>
<!-- 点击控制显示哪个组件 -->
<li><a @click="who='home'">首页</a></li>
<li><a @click="who='list'">列表</a></li>
<li @click="who='shopcar'"><a>购物车</a></li>
</ul>
</footer>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
el: "#app",
data() {
return {
who: 'home'
}
},
components: {
"home": {
template: `<div>首页<input type="text" /></input></div>`
},
"list": {
template: `<div>列表</div>`
},
"shopcar": {
template: `<div>购物车</div>`
}
}
})
</script>
</html>