Vue非父子组件传值+案例cnode首页

1. 创建公共实例化对象

const bus=new Vue()

2. 在需要发送数据的组件中

绑定事件 使用 bus.$emit发送数据

<button @click="send">发送</button>

methods:{
  send(){
    bus.$emit('自定义事件名',要发送的数据)
  }
}

3. 在需要接收数据的组件中

使用bus.$on监听数据改变 实时输出数据

bus.$on需要自动触发需要使用生命周期钩子函数created/mounted,一般使用created

created(){
  bus.$on('自定义事件名',data=>{
    console.log(data) //data就是传递过来的数据
  })
}

4. 案例:cnode首页

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="./css/public.css" />
    <link rel="stylesheet" href="./css/bootstrap.min.css" />
    <link rel="stylesheet" href="./css/index.css" />
  </head>
  <body>
    <div id="app">
      <heads></heads>
      <labs></labs>
      <lists></lists>
      <chose></chose>
      <fotters></fotters>
    </div>
    <script src="./js/vue.min.js"></script>
    <script src="./js/axios.min.js"></script>
    <script>
      const bus = new Vue();
      const heads = {
        data() {
          return {
            tit: ["首页", "新手入门", "API", "关于", "注册", "登录"],
          };
        },
        template: `
        <div class="heads">
          <div class="head-container">
            <div class="lefthead">
              <img src="https://static2.cnodejs.org/public/images/cnodejs_light.svg" alt="">
              <input type="text">
            </div>
            <div class="righthead">
              <ul>
                <li v-for="(item,index) in tit" :key='index'>
                  {{item}}
                </li>
              </ul>
            </div>
          
          </div>
        </div>
      `,
      };
      const labs = {
        data() {
          return {
            num: 0,
            arrs: ["全部", "精华", "分享", "问答", "招聘", "客户端测试"],
          };
        },
        template: `
      <div class="labs">
        <ul class="nav nav-tabs labsmenu">
          <li role="presentation" @click="send(items,index)" :class="{menushow:num==index}" v-for="(items,index) in arrs " :key="items.id"><span>{{items}}</span></li>
        </ul>
      </div>
      `,
        methods: {
          send(item,i) {
            bus.$emit("send-name", item);
            this.num=i
          },
        },
      };
      const lists = {
        data() {
          return {
            items: [],
            tab: "all",
            time:"2022-07-27T06:03:34.611Z",
          };
        },
        filters:{
          fliterA(msg){
            let times = new Date()
            let tall=0
            tall= Date.parse(times)
            let msg1=0
            msg1=Date.parse(msg)
            var t=Math.floor((tall-msg1)/1000%60)
            var min=Math.floor((tall-msg1)/1000/60)
            var h=Math.floor((tall-msg1)/1000/60/60)
            var day=Math.floor((tall-msg1)/1000/60/60/24)
            var months=Math.floor((tall-msg1)/1000/60/60/24/30)
            var year =Math.floor((tall-msg1)/1000/60/60/24/30/12)
            if(h>24&&day<30){
              msg= day + '天前'
            }else if(h<24){
              msg = h + '小时前'
            }else if(day>30){
            msg = months + '月前'
            }
           if(months>12){
              msg = year + '年前'
            }
            if(min<60){
              msg = min + '分钟前'
            }
            return msg
          }
        },
        created() {          
          axios
            .get("https://cnodejs.org/api/v1/topics", {
              params: {
                limit: 20,
              },
            })
            .then((res) => {
              this.items = [...res.data.data];
            })
            .catch((err) => {
              console.log(err);
            });
          bus.$on("send-page", (data) => {
            console.log(data);
            this.getMonth(this.tab, data);
          });
          bus.$on("send-name", (data) => {
            console.log(data);
            this.tab =
              data == "全部"
                ? "all"
                : data == "精华"
                ? "good"
                : data == "问答"
                ? "ask"
                : data == "招聘"
                ? "job"
                : data == "分享"
                ? "share"
                : "dev";
            this.getMonth(this.tab, 1);
          });
        },
        template: `
      <div class="lists">
        <div class="list-group">
          <div class="list-group-item lishe"  v-for="(item,index) in items" :key="index">
            <div class="lishe-left">
                <div class="atpho">
                <img :src="item.author.avatar_url" alt="">
                </div>
                <div class="atcount">
                  <span>{{item.reply_count}}/</span>
                  <span>{{item.visit_count}}</span> 
                </div>
                <div v-show="item.good" class="attop">置顶</div>
                <div v-show="!item.good" class="atshare">分享</div>
                <p class="attit">{{item.title}}</p>
            </div>
            <div class="lishe-right">
              <div>
                <img :src="item.author.avatar_url" alt="">
                <span>{{item.last_reply_at|fliterA}}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
      `,
        methods: {
          getMonth(tab, page) {
            
            this.items = [];
            axios
              .get("https://cnodejs.org/api/v1/topics", {
                params: {
                  tab,
                  limit: 20,
                  page,
                },
              })
              .then((res) => {
                this.items = [...res.data.data];
              })
              .catch((err) => {
                console.log(err);
              });
          },
        },
      };
      const chose = {
        template: `
        <div class="chose">
          <nav aria-label="Page navigation">
            <ul class="pagination">
              <li>
                <a href="#" aria-label="Previous">
                  <span aria-hidden="true">&laquo;</span>
                </a>
              </li>
              <li v-for="n in 5 " @click="send(n)"><span>{{n}}</span></li>
              <li>
                <a href="#" aria-label="Next">
                  <span aria-hidden="true">&raquo;</span>
                </a>
              </li>
            </ul>
          </nav>  
        </div>
      `,
        methods: {
          send(n) {
            bus.$emit("send-page", n);
          },
        },
      };


      const fotters={
        template:`
        <div class="fotter">
        <div class="fotter-container">
          <ul class="fotter-menu">
            <li>
              <span>RSS</span>
                |
              <span>源码地址</span>
            </li>
            <li>CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。</li>
            <li>
              服务器搭建在
              <img src="	https://static2.cnodejs.org/public/images/digitalocean.png" alt="">        
              ,存储赞助商为
              <img src="https://static2.cnodejs.org/public/images/qiniu.png" alt="">
            </li>
            <li>新手搭建 Node.js 服务器,推荐使用无需备案的 <a href="">DigitalOcean(https://www.digitalocean.com/)</a></li>
          </ul>
        </div>
      </div>
        `
      }
      Vue.component("labs", labs);
      Vue.component("lists", lists);
      Vue.component("chose", chose);
      Vue.component("heads", heads);
      Vue.component("fotters", fotters);
      const vm=new Vue({
        el: "#app",
      });

    </script>
  </body>
</html>
body{
  background: #e1e1e1;
}
.heads{
  width: 100%;
  height: 50px;
  line-height: 50px;
  background: #444444;
}
.head-container{
  width: 1400px;
  display: flex;
  margin: auto;
  justify-content: space-between;
}
.righthead ul{
  display: flex;
}
.righthead ul li{
  margin-right: 10px;
  color: #ccc;
}
.lefthead{
  display: flex;
  height: 50px;
  align-items: center;
}
.lefthead input{
  margin-left: 20px;
  width: 223px;
  height: 26px;
  background: #888888;
  padding-left: 20px;
  color: #fff;
  border: 1px solid #888888;
  border-radius: 10px;
}
.lefthead img{
  width: 124px;
  vertical-align: middle;
  height: 36px;
}
.labs{
  width: 1400px;
  margin: 30px auto;
  height: 40px;
  margin-bottom: 0;
  background-color: #f6f6f6;
}
.lists{
  width: 1400px;
  margin: auto;
  min-height: 100vh;
}
.labsmenu{
  height: 100%;
  width: 100%;
  padding-left: 10px;
  display: flex;
  align-items: center;
  justify-content: flex-start;
}
.labsmenu li{
  height: 26px;
  cursor: pointer;
  color: #80bd01;
  padding: 2px 5px 2px 5px;
  border-radius: 5px;
  margin-right: 20px;
}
.menushow{
  background: #80bd01;
  color: #fff !important;
}
.home{
  width: 1400px;
  margin: auto;
}
.chose{
  width: 1400px;
  margin: auto;
  cursor: pointer;
}
.lishe{
  height: 50px;
  padding-left: 5px;
  display: flex;
  align-items: center;
  padding-left: 10px;
  justify-content: space-between;
}
.lishe-left{
  display: flex;
  align-items: center;
}
.lishe-right img{
  width: 18px;
  height: 18px;
  border-radius: 2px;
}
.lishe-right span{
  font-size: 12px;
  color: #778087;
  margin-left: 10px;
}
p{
  margin-bottom: 0;
}
.attop{
  background: #80bd01;
    padding: 1px 4px 0px 4px;
    color: #fff;
    border-radius: 3px;
    margin-right: 5px;
    font-size: 12px;
    height: 20px;
}

.atshare{
  background: #afb1aa;
  padding: 1px 4px 0px 4px;
  color: #fff;
  border-radius: 3px;
  margin-right: 5px;
  font-size: 12px;
  height: 20px;
}
.atcount{
  margin-right: 10px;
}
.atcount>span:first-child{
  font-size: 16px;
}
.atcount>span:last-child{
  color: #afafaf;
}
.atpho{
  margin-right: 10px;
}
.atpho img{
  width: 30px;
    height: 30px;
  border-radius: 5px;
}
.attit{
  font-size: 16px;
}
.fotter{
  width: 100%;
  background: #fff;
}
.fotter-container{
  width: 90%;
  max-width: 1400px;
  min-width: 960px;
  margin: 0 auto;
  color: #bdb7b7;
  padding: 20px 0;
  font-size: 13px;
  line-height: 2em;
}
.fotter-menu li:nth-child(1) span{
  color: #666;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值