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
### 创建 Vue 项目 为了在浏览器中显示 TodoList 组件内容,首先需要创建一个 Vue 项目。可以通过使用 [Vue CLI](https://cli.vuejs.org/) 来快速搭建一个 Vue 应用程序。 ```bash # 安装 Vue CLI(如果尚未安装) npm install -g @vue/cli # 创建新项目 vue create todo-app # 进入项目目录 cd todo-app # 启动开发服务器 npm run serve ``` 执行上述命令后,开发服务器将在 `http://localhost:8080` 上运行,并且浏览器会自动打开并加载 Vue 项目[^2]。 --- ### 编写 TodoList 组件 在 `src/components/` 目录下创建两个组件文件:`TodoList.vue` `TodoItem.vue`。这些组件将用于构建待办事项列表的核心功能。 #### TodoItem.vue 此组件负责渲染单个待办事项条目,包括复选框删除按钮。 ```vue <template> <li :class="{ done: isDone }"> <input type="checkbox" v-model="isDone" /> <span>{{ text }}</span> <button @click="$emit('remove')">删除</button> </li> </template> <script> export default { props: ['text', 'done'], data() { return { isDone: this.done, }; }, }; </script> <style scoped> .done { text-decoration: line-through; } </style> ``` #### TodoList.vue 此组件管理整个待办事项列表的状态,并提供添加删除任务的功能。 ```vue <template> <div> <input v-model="newTodo" @keyup.enter="addTodo" placeholder="输入新任务..." /> <ul> <todo-item v-for="(item, index) in todos" :key="index" :text="item.text" :done="item.done" @remove="removeTodo(index)" ></todo-item> </ul> </div> </template> <script> import TodoItem from './TodoItem.vue'; export default { components: { TodoItem }, data() { return { newTodo: '', todos: [], }; }, methods: { addTodo() { if (this.newTodo.trim()) { this.todos.push({ text: this.newTodo, done: false }); this.newTodo = ''; } }, removeTodo(index) { this.todos.splice(index, 1); }, }, }; </script> ``` --- ### 在 App.vue 中引入 TodoList 组件 修改 `src/App.vue` 文件以包含 `TodoList` 组件,这样可以在浏览器中看到完整的待办事项页面。 ```vue <template> <div id="app"> <h1>我的待办事项</h1> <todo-list></todo-list> </div> </template> <script> import TodoList from './components/TodoList.vue'; export default { name: 'App', components: { TodoList, }, }; </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; margin: 60px auto; max-width: 600px; } </style> ``` --- ### 使用本地存储保存数据 为了使用户刷新页面时仍然保留之前的数据,可以利用浏览器的 `localStorage` API。以下是实现方式: ```javascript // 在 TodoList.vue 的 methods 中添加以下方法 mounted() { const savedTodos = localStorage.getItem('todos'); if (savedTodos) { this.todos = JSON.parse(savedTodos); } }, watch: { todos: { deep: true, handler(newVal) { localStorage.setItem('todos', JSON.stringify(newVal)); }, }, }, ``` 通过这种方式,当用户添加、修改或删除任务时,数据会被持久化到浏览器中[^1]。 --- ### 浏览器中查看效果 完成以上步骤后,确保开发服务器仍在运行。打开浏览器并访问 `http://localhost:8080`,即可看到待办事项页面的内容。输入新的任务并按下回车键,任务将会被添加到列表中,并且状态更改删除操作也会实时反映在界面上[^3]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值