Vue学习之——Vue组件间通信

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

实现页面之间的数据共享,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值