# Vue computed、watch

# watch 监听

immediate第一次渲染时是否执行函数

deep监听对象时是否查看对象内部属性变化

语法:https://cn.vuejs.org/v2/api/#watch

# 监听变化

new Vue({
  data: {
    n: 0,
    obj: {
      a: "a"
    }
  },
  template: `
    <div>
      <button @click="n += 1">n+1</button>
      <button @click="obj.a += 'hi'">obj.a + 'hi'</button>
      <button @click="obj = {a:'a'}">obj = 新对象</button>
    </div>
  `,
  created(){
    this.$watch('n',function() {
      console.log("n 变了");
    },{immediate:true})
  },
  watch: {
    obj: {
      handler(){
        console.log("obj 变了");
      },
      deep: true       
    },
    "obj.a": function() {
      console.log("obj.a 变了");
    }
  }
}).$mount("#app");

obj原本是{a:'a'},现在obj={a:'a'},obj变了,a没变。

简单类型看值,复杂类型看地址

# deep:true

如果 object.a 变了, 需要 object也算变了,那么 obj在监听过程中使用 deep选项

# immediate: true

该回调将会在侦听开始之后被立即调用

# computed 计算属性

用来计算值,调用时不需加括号;

根据依赖会自动缓存

// 引用完整版 Vue
import Vue from "vue/dist/vue.js";

Vue.config.productionTip = false;

new Vue({
  data: {
    user: {
      email: "yafanison@qq.com",
      nickname: "fanfan",
      phone: "13812312312"
    }
  },
  computed: {
    displayName: {
      get() {
        const user = this.user;
        return user.nickname || user.email || user.phone;
      },
      set(value) {
        console.log(value);
        this.user.nickname = value;
      }
    }
  },
  template: `
    <div>
      {{displayName}}
      <div>
      {{displayName}}
      <button @click="add">set</button>
      </div>
    </div>
  `,
  methods: {
    add() {
      console.log("add");
      this.displayName = "圆圆";
    }
  }
}).$mount("#app");

# 给三个按钮加事件处理函数

思路一:点击之后改 users

import Vue from "vue/dist/vue.js";

Vue.config.productionTip = false;
let id = 0;
const createUser = (name, gender) => {
  id += 1;
  return { id, name, gender };
};
new Vue({
  data() {
    return {
      users: [
        createUser("方方", "男"),
        createUser("圆圆", "女"),
        createUser("小新", "男"),
        createUser("小葵", "女")
      ],
      displayUsers : []
    };
  },
  created(){
    this.displayUsers = this.users
  },
  methods:{
    showMale(){
      this.displayUsers = this.users.filter( u=> u.gender === "男");
    },
    showFemale(){
      this.displayUsers = this.users.filter( u=> u.gender === "女");
    },
    showAll(){
      this.displayUsers = this.users
    }
  },
  template: `
    <div>
      <div>
        <button @click="showAll">全部</button>
        <button @click="showMale">男</button>
        <button @click="showFemale">女</button>
      </div>
      <ul>
        <li v-for="u in displayUsers" :key="u.id">
          {{u.name}} - {{u.gender}}
        </li>
      </ul>
    </div>
  `,

}).$mount("#app");

思路二:使用 computed

// 引用完整版 Vue,方便讲解
import Vue from "vue/dist/vue.js";

Vue.config.productionTip = false;
let id = 0;
const createUser = (name, gender) => {
  id += 1;
  return { id, name, gender };
};
new Vue({
  data() {
    return {
      users: [
        createUser("方方", "男"),
        createUser("圆圆", "女"),
        createUser("小新", "男"),
        createUser("小葵", "女")
      ],
      gender:''
    };
  },
  computed:{
    displayUsers() {
      const hash = {
        male: '男',
        female: '女',
      }
      const {users, gender} = this
      if( gender === ""){
        return users;
      }else if(gender === "male" || gender === "female"){
      //else if( typeof gender === "string" ){
        return users.filter( u => u.gender === hash[gender])
      }
    }
  },
  methods:{
    setGender(string){
      this.gender = string;
    }
  },
  template: `
    <div>
      <div>
        <button @click="setGender('')">全部</button>
        <button @click="setGender('male')"></button>
        <button @click="setGender('female')"></button>
      </div>
      <ul>
        <li v-for="u in displayUsers" :key="u.id">
          {{u.name}} - {{u.gender}}
        </li>
      </ul>
    </div>
  `,

}).$mount("#app");