Vue组件间通信
父子传值 :props 总线模式 vuex 发布订阅 ref $root $parent $attrs
父传子:子组件使用prop接收父组件传来的值,在父组件给子组件赋值。
<body>
<div id="app">
<demo></demo>
</div>
</body>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
Vue.component("demo",{
// 这个父传子值 是在父模板中 插入了子组件,并给子组件中添加了属性值!!!
template:`
<h1>
Demo组件{{title}}
<test title="🍉" test-title="🍑"></test>
<test test-title="🍑"></test>
</h1>
`,
data:function(){
return{
title:"🈷"
}
},
components:{
//子组件接受值 如果传入的参数是短横线的形式,接收的时候要变为驼峰式
//接收方式 1-数组 2-对象
//使用 props 接收
"test":{
// 1-数组的形式
props:["title","testTitle"],
// 2-对象的形式
// props:{
// title:[String,Number],
// testTitle:{
// type:String, //类型
// default:"😀" //默认值
// }
// },
template:`<h2>test组件{{title}} {{testTitle}}</h2>`
},
},
})
let vm = new Vue({
el:"#app",
data:{
},
})
</script>
子向父传值:通过自定义事件
。
子传父,说明动作发生在子组件中。
在父组件中给子组件传一个自定义事件 @myclick="handleClick"
在子组件中调用这个自定义事件,并传值
<body>
<div id="app">
<!-- 原生事件 的方式 -->
<button @click="handleClick">原生事件</button>
<!-- 自定义事件 的方式 -->
<!-- 标签是组件模板 事件是自定义事件 -->
<my-button @myclick="handleClick">自定义事件</my-button>
</div>
</body>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 首先是自定义了一个全局组件,点击了自定义组件中的button,触发了函数handleMyButtonClick,执行该函数,执行方法 this.$emit("eventName",params),触发了当前组件的自定义事件 handleClick ,执行该函数,并且子组件中的值传到了父组件中。
Vue.component("my-button",{
template:`
<div>
<button @click="handleMyButtonClick">使用原生事件触发自定义事件</button>
</div>
`,
methods:{
handleMyButtonClick:function(){
console.log("触发了自定义 button 中的点击事件");
//从这里,子组件 传值给父组件
/*
vm.$emit(eventName,[...arg])
触发当前实例上的事件。附加参数都会传给监听器回调
*/
console.log(this);
// 当前的this是组件 my-button 所以当前实例上的事件是自定义的事件
this.$emit("myclick","🍎")
}
}
})
let vm = new Vue({
el:"#app",
data:{},
methods:{
handleClick:function(params){
console.log("从子组件传来的值",params);
}
},
})
</script>
跨组件传值:使用prop
依次接收
<body>
<div id="app">
<demo :haha="money"></demo>
</div>
</body>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
//2-定义一个全局组件
Vue.component("demo",{
//获取实例中的money值
//问题====>单纯的获取实例中的值是获取不到的,要在html结构中绑定一个属性,来接收实例中的 值 money
props:["haha"],
// props:{
// money:{
// type:String,
// default:"",
// },
// },
template:`
<div>
<h1>
demo组件
接受到 :{{haha}}
</h1>
<test v-bind:xixi="haha"></test>
</div>
`,
components:{
test:{
//子组件获取值
props:["xixi"],
template:`<h2>我是test组件 {{xixi}}</h2>`
}
}
})
// 1-首先是实例 data 中有一个数据 🈷
let vm = new Vue({
el:"#app",
data:{
money:"🈷",
},
})
</script>
跨组件传值-provide-inject
// 这个是vuex的吗???不是,是vue里面的
<body>
<div id="app">
<!-- 222222222222222绑定一个属性 获取值 -->
<!-- 不需要 绑定值 这一步了!!!!!!!!!!!! -->
<!-- <demo :haha="money"></demo> -->
<demo></demo>
</div>
</body>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
/* provide/inject 注入值
React =>React.createContext =>Procvider Comsumer
*/
Vue.component("demo",{
//33333333333333333333333333333在子组件中注入值
inject:["money"],
template:`
<div>
<h1>
demo组件
接受到 :{{money}}
</h1>
<test></test>
</div>
`,
components:{
test:{
inject:["money"],
template:`<h2>我是test组件 {{money}}</h2>`
}
}
})
let vm = new Vue({
el:"#app",
/* 11111111111111111111111111111111在父组件中提供值 */
provide:{
money:"🈷",
},
data:{},
})
</script>
组件通信-事件机制方式 $emit / $on
父子,跨组件
<body>
<div id="app">
<button @click="handleClick">触发test事件</button>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 生命周期钩子 mounted
// 类型 Function
// 实例被挂载后调用,这时el被创建的
let vm = new Vue({
el:"#app",
// 元素 挂载到 dom 上面的时候 触发 mounted 方法
mounted(){
// 发布订阅的方式
// vm.$on(event,callback)
//实例方法 监听当前实例上的自定义事件。事件可以由vm.$emit触发。回调函数会接收所有传入事件触发函数的额外参数。
this.$on('test',function(msg){
console.log("将信息",msg,"发送给朋友1");
})
this.$on('test',function(msg){
console.log("将信息",msg,"发送给朋友2");
})
},
methods:{
handleClick:function(){
//触发当前实例的事件
this.$emit("test","🍉")
}
}
})
</script>
</body>
组件通信 - ref
方式
<body>
<div id="app">
<!-- 1-获取原始节点的信息 -->
<!-- <p id="domP">这是原始节点</p>
<button @click="handleClick">点击获取原始节点的信息</button> -->
<!-- 2-获取vue节点 -->
<demo ref="domeRef"></demo>
<!-- -->
<test ref="testRef"></test>
<button @click="handleDemo">vue实现点击获取test的dom节点</button>
</div>
</body>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
Vue.component("demo", {
template: `
<div>
<h1 ref="hRef">能获取到我这个vue节点吗</h1>
<button @click="handleClick">点击获取vue节点</button>
</div>
`,
methods: {
handleClick: function () {
//this是这个组件
// console.log(this);
//获取到了整个demo
// console.log(this.$el);
// html里是使用属性ref绑定一个属性值
// 获取是使用$refs来获取
// vm.$refs 是Object类型,只读属性,一个对象,持有注册过 ref 属性的所有dom元素和组件实例。
console.log(this.$refs); //{hRef: h1}
console.log(this.$refs['hRef']);//获取到了绑定这个属性值的dom元素
},
},
})
Vue.component("test",{
template:`<h1>test</h1>`
})
let vm = new Vue({
el: "#app",
data: {
},
methods: {
handleDemo: function () {
// console.log(this);
console.log(this.$refs); //{domeRef: VueComponent}
console.log(this.$refs["testRef"]);
}
},
})
</script>
组件通信 - 事件总线(Bus)
有一个$root
,
<body>
<div id="app">
<demo></demo>
<button @click="handleGetRoot">获取根节点信息</button>
</div>
</body>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
//一个全局组件
Vue.component("demo",{
template:`
<div>
<h1>demo组件</h1>
<button @click="handleClick">子组件获取 根组件实例</button>
</div>
`,
methods:{
handleClick:function(){
//获取到了根节点上的信息
console.log(this.$root.$data.msg);
}
}
})
// $root 总线
let vm = new Vue({
el:"#app",
data:{
msg:"😀"
},
methods:{
handleGetRoot:function(){
console.log(this.$root);
console.log(this.$root.$data);
}
},
})
</script>
Bus模式结合发布订阅
// vue 的一个实例
window.busline = new Vue() // 做 全局的事件通信
// 注册了一个事件
window.busline.$on("test",function(msg){
console.log("收到最新的消息")
})
// 在Demo子组件中
window.busline.$emit("test","😀") //通过总线传给了App父组件
组间通信 - cookie
等
<script>
localStorage.getItem("key")
localStorage.setItem("key","value")
sessionStorage.getItem("key")
sessionStorage.setItem("key","value")
console.log(document.cookie)
document.cookie="name=xiaoming"
console.log(location.search);
</script>
Vuex
实现页面之间的数据共享,