Vue 02- Vue如何实现数据共享

基础概念

1. 什么是Vue的组件?

组件是可复用的 Vue 实例, 把一些公共的模块抽取出来,然后写成单独的的工具组件或者页面,在需要的页面中就直接引入即可那么我们可以将其抽出为一个组件进行复用。例如 页面头部、侧边、内容区,尾部,上传图片,等多个页面要用到一样的就可以做成组件,提高了代码的复用率。

2.什么是子组件,什么是父组件?

子组件在父组件的 template 属性或者是模板中。

Vue传值的方式

1. 子向父传值,通过通过props关键字接收

父组件:

<template>
  <div id="root">
    <div class="todo-container">
      <div class="todo-wrap">
        <Header :addTodo="addTodo"></Header>
        <List :todos="todos" :checkTodo="checkTodo" :deleteTodo="deleteTodo"></List>
        <Footer :todos="todos" :checkAllTodo="checkAllTodo" :clearAllTodo="clearAllTodo"></Footer>
      </div>
    </div>
  </div>
</template>

<script>
import Header from "@/components/Header";
import List from "@/components/List";
import Footer from "@/components/footer";

export default {
  name: 'App',
  data() {
    return {
      todos:JSON.parse(localStorage.getItem('todos')) || []
      // todos: [
      //   {id: '001', title: '测试数据1', done: false},
      //   {id: '002', title: '测试数据2', done: true},
      //   {id: '003', title: '测试数据3', done: false}
      // ]
    }
  }, methods: {
    addTodo(todoObj) {
      this.todos.unshift(todoObj);
    },
    /* 勾选或者 取消勾选   */
    checkTodo(id) {
      this.todos.forEach((todo) => {
        if (todo.id == id) {
          todo.done = !todo.done;
          return;
        }
      });
    },
    deleteTodo(id) {
      this.todos = this.todos.filter(todo=>todo.id != id);
    },
    /* 全选 与 全反选 */
    checkAllTodo(done){
      this.todos.forEach(todo=> todo.done = done);
    },clearAllTodo(){
      this.todos = this.todos.filter(todo=> !todo.doen);
    }
  },
  watch:{
    todos:{
      deep:true,
      handler(value){
        localStorage.setItem('todos',JSON.stringify(value))
      }
    }
  },
  components: {
    Footer,
    List,
    Header
  }
}
</script>

子组件之一

<template>
  <ul class="todo-main">
    <Item
      v-for="todo in todos"
      :key="todo.id"
      :todo="todo"
      :checkTodo="checkTodo"
      :deleteTodo="deleteTodo"
    >
    </Item>
  </ul>
</template>

<script>
import Item from "@/components/Item";

export default {
  name: "List",
  components: {Item},
  props: ['todos', 'checkTodo', 'deleteTodo']
}
</script>

<style scoped>
  .todo-main{
    margin-left: 0px;
    border: 1px solid #ccc;
    border-radius: 2px;
    padding: 0px;
  }

</style>

通过props子组件可以接到值,而且子组件可以再向里套用子组件。

2. $emit  子组件向父组件传值

什么是全局事件总线?

一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。

如图,这就是全局事件总线的执行流程,值是单项传递的。这种传值方式组件之间可以没有任何关系。

学校组件:

<template>
  <div>
    <h2>学校名称:{{ name }}</h2>
    <h2>学校地址:{{ address }}</h2>
  </div>
</template>

<script>
export default {
  name: "School",
  data() {
    return {
      name: '猿究院',
      address: '太白南路'
    }
  }, methods: {
    myShowInfo(data) {
      console.log("这是School组件,收到了数据:"+data);
    }
  },
  mounted() {
    this.$bus.$on('showInfo',this.myShowInfo)
  },beforeDestroy() {
      this.$bus.$off('showInfo');
  }
}
</script>

<style scoped>

</style>

学生组件

 

<template>
  <div>
    <h2>学生姓名:{{ name }} </h2>
    <h2>学生性别:{{ sex }} </h2>
    <button @click="sendStudentName">点我传递学生信息</button>
  </div>
</template>

<script>
export default {
  name: "Student",
  data() {
    return {
      name: '张三',
      sex: '男'
    }
  },methods:{
    sendStudentName(){
      //  $emit 触发事件   >>> $emit(eventName)
      this.$bus.$emit('showInfo',this.name);
    }

  }
}
</script>

<style scoped>

</style>

 App组件:

<template>
  <div>
  
    <School></School>
    <Student ></Student>
  </div>
</template>
<script>
import Student from "@/components/Student";
import School from "@/components/School";

export default {
  name: 'App',
  data() {
    return {}
  }, components: {
    School,
    Student
  }

}
</script>

 这种方式虽然简单好用。但是订阅和发布必须成对出现,不然就没有意义,由于在页面使用里的灵活性,一旦事件多了后,难以对事件进行维护。另外在订阅事件的组件里,必须手动销毁监听,否则会引发多次执行,对于一些包含业务逻辑的通信,复用性差,需要在多个地方重复写逻辑。

3. 通过ref属性获取值

调用方式:

this.$refs.ref名称.属性 和 this.$refs.ref名称.方法()

父组件:


<child :name="name" ref="child" />

mounted() {
    console.log(this.$refs.child.year); 
    this.$refs.child.showName()   
}

子组件:

export default {
  data(){
    return {
      year:2022
    }
  },
  methods:{
    showName(){
      console.log('toby:'+ this.year);
    }
  }
};

总结

Vue的传值方式有很多种,单个组件内可用插值表达式去实现,如果需要储存一些数据,也可以用localstorage方法去储存这些多次使用的数据。不过组件之间的传值方式需要注意使用的场景。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值