vuejs 的watch 和 $emit

本文深入探讨了Vue.js中关键的API,包括watch用于响应式数据变化监测,$emit实现父子组件间的事件通信。通过具体示例展示了如何利用这些API进行高效开发。

vue有很多像watch,prop,emit等这种api,自己看官网

现在给出两个简单的例子:

watch 有两种,一种是深度监听,一种是浅度监听

watch

  • 类型: { [key: string]: string | Function | Object }

  • 详细:

    一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个属性。

  • 示例:

           
    var vm = new Vue({
    data: {
    a: 1,
    b: 2,
    c: 3
    },
    watch: {
    a: function (val, oldVal) {
    console.log( 'new: %s, old: %s', val, oldVal)
    },
    // 方法名
    b: 'someMethod',
    // 深度 watcher
    c: {
    handler: function (val, oldVal) { /* ... */ },
    deep: true
    }
    }
    })
    vm.a = 2 // -> new: 2, old: 1

    注意,不应该使用箭头函数来定义 watcher 函数 (例如 searchQuery: newValue => this.updateAutocomplete(newValue))。理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,this.updateAutocomplete 将是 undefined。

  • 参考: 实例方法 - vm.$watch

  • Source

vm.$emit( event, […args] )

  • 参数:

    • {string} event
    • [...args]

    触发当前实例上的事件。附加参数都会传给监听器回调。

  • Source


Emit, 实际上是定义一种事件,然后父vue在调用子vue的时候,如果子vue定义了一种事件,那么父vue在调用子vue时 就可以 <son-vue @newEvent='handlerFunction' ></son-vue>

代码实例:

父vue

 <el-col v-for="(value, key) in chartSort" :span="computedSpan" :offset="computedOffset" v-if="value == true" >
        <fly-chart :chart="key" :chartData="chartData" @close="closeOneChart"></fly-chart>
 </el-col>
子vue

<template>
    <el-row>
      <el-row align="top">
        <el-col :span="1" :offset="23">
          <el-button size="mini" icon="close" @click="closeChart"></el-button>
        </el-col>
      </el-row>
      <el-row>
        <el-col v-if="chart == 'line'">
          <line-chart :chartData="chartData"></line-chart>
        </el-col>
        <el-col v-if="chart == 'bar'">
          <bar-chart :chartData="chartData"></bar-chart>
        </el-col>
      </el-row>
    </el-row>
</template>

<script>
  import BarChart from './../basicChart/BarChart'
  import LineChart from './../basicChart/LineChart'
  export default {
    name: 'fly-chart',
    props: ['chart', 'chartData'],
    components: {
      LineChart: LineChart,
      BarChart: BarChart
    },
    data: function(){
      return {

      }
    },
    methods: {
      closeChart: function(){
        var self = this;
        this.$emit('close', self.chart);  // 定义一个临时事件,然后父组件可以监听到
      }
    }
  }
</script>

<style>

</style>

事件和指令是不一样的,如果要学指令,看 http://www.runoob.com/vue2/vue-custom-directive.html


src目录中有App.vue,main.js,src/components/todo-list目录中有index.vue,list-item.vue, 以下是index.vue的代码 <script> import ListItem from './list-item.vue'; export default { name: "TodoList", components: { ListItem }, data() { return { newTodo: '', items: [] } }, created() { setTimeout(() => { this.items = [ { id: 1, title: "吃饭", done: true }, { id: 2, title: "睡觉", done: false }, { id: 3, title: "学习", done: false }, ] }, 1000) }, mounted() { }, methods: { addNewTodo() { if (!this.newTodo) { alert("您还没有输入代办内容!") return } this.items.push({ id: this.items.length + 1, title: this.newTodo, done: false }) this.newTodo = "" }, updateTodo(param) { // console.log(param); const index = this.items.findIndex(e => e.id === param.id) this.items[index].done = param.checked // const item = this.items.find(e => e.id === param.id) // if (!item) { // alert("没找到!") // return // } // item.done = param.checked // this.$set(this.items, i, {}) }, deleteTodo(id){ // const index = this.items.findIndex(e => e.id === id) // if (index < 0) { // alert("没找到!") // return // } // this.items.splice(index, 1) this.items = this.items.filter(e => e.id !== id) } } // 在子组件中修改父组件值(props): // emit v-on // props } </script> <template> <input v-model="newTodo" /><button @click="addNewTodo">添加代办</button> <list-item v-for="(item, index) in items" :key="item.id" :item="item" @done-item="updateTodo" :deleteTodo="deleteTodo"></list-item> <!-- <div v-for="item in items" :key="item.id"> <span>{{ item.title }}</span> <span>{{ item.done ? '√' : "×" }}</span> </div> --> </template> 以下是list-item.vue的代码 <script> export default { name: "ListItem", props: { item: { type: Object, required: true, default() { return {} }, }, deleteTodo: Function // item: Object }, data() { return { } }, watch: { // item(newV, oldV) { // console.log(newV, oldV); // } item: { handler(newV, oldV) { console.log(JSON.stringify(newV), JSON.stringify(oldV)); }, // deep: true, // immediate: true } }, computed: { // myItem() { // return this.item.title + "---" + this.item.id // }, myItem: { get() { return this.item.title + "---" + this.item.id }, set(val) { console.log(val); }, } }, mounted(){ this.myItem = '123' }, methods: { changeDone(e) { // console.log(e.target.checked); this.$emit('done-item', { id: this.item.id, checked: e.target.checked }) }, handleDelete() { // this.$emit('delete-item') if (this.deleteTodo && this.deleteTodo instanceof Function) { this.deleteTodo(this.item.id) } }, } } </script> <template> <div> {{ myItem }} <input type="checkbox" :checked="item.done" @change="changeDone" /> <span>{{ item.title }}</span> <span>{{ item.done ? '√' : "×" }}</span> <button @click="handleDelete">删除</button> </div> </template> 如何在浏览器显示这些内容
07-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值