过滤器、按键修饰符、指令、生命周期

# Vue 第二天

以做案例逐渐深入学习

打好基础很重要!

believe in yourself

# 品牌列表案例

<div id="app">
  <div class="panel panel-primary">
    <div class="panel-heading">
      <div class="panel-title">添加品牌</div>
    </div>
    <div class="panel-body form-inline">
      <label for="id">id: </label>
      <input type="text" class="form-control" v-model="id" id="id" />
      <label for="name">name: </label>
      <input type="text" class="form-control" v-model="name" id="name" />
      <button class="btn  btn-primary" @click="add">添加</button>
    </div>
  </div>
  <table class="table table-bordered table-hover table-striped">
    <thead>
      <tr>
        <th>id</th>
        <th>name</th>
        <th>ctime</th>
        <th>Operation</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="item in list" :key="item.id">
        <td>{{item.id}}</td>
        <td>{{item.name}}</td>
        <td>{{item.ctime}}</td>
        <td><a href="" @click.prevent="del(item.id)">删除</a></td>
      </tr>
    </tbody>
  </table>
</div>
<script>
  let vm = new Vue({
    el: "#app",
    data: {
      id: "",
      name: "",
      list: [
        {
          id: 1,
          name: "奔驰",
          ctime: new Date(),
        },
        {
          id: 2,
          name: "宝马",
          ctime: new Date(),
        },
      ],
    },
    methods: {
      add() {
        let car = { id: this.id, name: this.name, ctime: new Date() };
        this.list.push(car);
        this.name = this.id = "";
      },
      del(id) {
        let index = this.list.findIndex((item) => {
          if (item.id == id) {
            return true;
          }
        });
        this.list.splice(index, 1);
      },
    },
  });
</script>

mark

mark

mark

mark

# 增加搜索功能

# 方法一

<tr v-for="item in search(keywords)" :key="item.id">
  <td>{{item.id}}</td>
  <td>{{item.name}}</td>
  <td>{{item.ctime}}</td>
  <td><a href="" @click.prevent="del(item.id)">删除</a></td>
</tr>
<script>
  methods: {
      search(keywords){//根据关键字进行数据的搜索
          let newList=[]
          this.list.forEach((item)=>{
              if(item.name.indexOf(keywords)!= -1){
                  newList.push(item)
              }
          })
          return newList
      }
  }
</script>

# 方法二 (使用 filter)

<script>
  methods: {
      search(keywords){//根据关键字进行数据的搜索
          let newList = []
              //注意 :foreach some filter findIndex 这些都属于数组的新方法
              //都会对数组中的每一项,进行遍历,执行相关的操作
              //注意:Es6中,为字符串提供了一个新方法 ,叫做String.prototype.includes('要包含的字符串,如果包含返回true')
          newList = this.list.filter((item) => {
              // if(item.name.indexOf(keywords)!= -1)
              if (item.name.includes(keywords)) {
                  return item
              }
          })
          return newList
      }
  }
</script>

mark

mark

# 过滤器

# 全局过滤器

过滤器的定义语法Vue.filter (‘过滤器的名称’,function (){})

//过滤器中的function,第一个参数,已经被规定死了,永远都是 过滤器 管道符前面 传递过来的数据
Vue.filter("过滤器的名称", function (data) {
  return data + "123";
});

写一个例子

<div id="app">{{ msg | msgFormat}}</div>
<script>
  //定义一个Vue 全局的过滤器 名字叫做 msgFormat
  Vue.filter("msgFormat", function (msg) {
    //字符串 replace方法,第一个参数,除了可以写一个 字符串之外,还可以定义一个正则表达式
    // return msg.replace('拼尽全力','开心快乐')
    return msg.replace(/拼尽全力/g, "开心快乐");
  });
  let vm = new Vue({
    el: "#app",
    data: {
      msg: "人活着就要拼尽全力!拼尽全力,拼尽全力,拼尽全力!",
    },
  });
</script>

mark

# 使用过滤器时(传参数)

<div id="app">{{ msg | msgFormat('开心快乐')}}</div>
<script>
  //定义一个Vue 全局的过滤器 名字叫做 msgFormat
  Vue.filter("msgFormat", function (msg, arg) {
    //字符串 replace方法,第一个参数,除了可以写一个 字符串之外,还可以定义一个正则
    // return msg.replace('拼尽全力','开心快乐')
    return msg.replace(/拼尽全力/g, arg);
  });
  let vm = new Vue({
    el: "#app",
    data: {
      msg: "人活着就要拼尽全力!拼尽全力,拼尽全力,拼尽全力!",
    },
  });
</script>

# 使用过滤器时(传多个参数)

<div id="app">{{ msg | msgFormat('开心快乐','123')}}</div>
<script>
  //定义一个Vue 全局的过滤器 名字叫做 msgFormat
  Vue.filter("msgFormat", function (msg, arg, arg2) {
    //字符串 replace方法,第一个参数,除了可以写一个 字符串之外,还可以定义一个正则
    // return msg.replace('拼尽全力','开心快乐')
    return msg.replace(/拼尽全力/g, arg + arg2);
  });
  let vm = new Vue({
    el: "#app",
    data: {
      msg: "人活着就要拼尽全力!拼尽全力,拼尽全力,拼尽全力!",
    },
  });
</script>

mark

# 使用过滤器时(多次调用)

<div id="app">{{ msg | msgFormat('开心快乐','123') | test}}</div>
<script>
  //定义一个Vue 全局的过滤器 名字叫做 msgFormat
  Vue.filter("msgFormat", function (msg, arg, arg2) {
    //字符串 replace方法,第一个参数,除了可以写一个 字符串之外,还可以定义一个正则
    // return msg.replace('拼尽全力','开心快乐')
    return msg.replace(/拼尽全力/g, arg + arg2);
  });

  Vue.filter("test", function (msg) {
    return msg + "test";
  });

  let vm = new Vue({
    el: "#app",
    data: {
      msg: "人活着就要拼尽全力!拼尽全力,拼尽全力,拼尽全力!",
    },
  });
</script>

mark

# 修改品牌列表案例,进行时间的格式化

# 关键代码:

<td>{{item.ctime | dataFormat}}</td>
<script>
  //全局的过滤器,进行时间的格式化
  Vue.filter("dataFormat", function (data) {
    //根据给定的时间字符串,得到特定的时间
    let dt = new Date(data);
    let y = dt.getFullYear();
    let m = dt.getMonth() + 1;
    let d = dt.getDate();
    // return y + '-' + m + '-' + d
    return `${y}-${m}-${d}`;
  });
</script>

mark

# 功能改进

<td>{{item.ctime | dataFormat('')}}</td>
<script>
  //全局的过滤器,进行时间的格式化
  Vue.filter("dataFormat", function (data, pattern) {
    //根据给定的时间字符串,得到特定的时间
    let dt = new Date(data);
    let y = dt.getFullYear();
    let m = dt.getMonth() + 1;
    let d = dt.getDate();
    // return y + '-' + m + '-' + d
    if (pattern && pattern.toLowerCase() === "yyyy-mm-dd") {
      return `${y}-${m}-${d}`;
    } else {
      let hh = dt.getHours();
      let mm = dt.getMinutes();
      let ss = dt.getSeconds();
      return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
    }
  });
</script>

mark

# 局部过滤器

过滤器调用的时候,采用的是就近原则如果私有过滤器和全局过滤器名称一致了,这时候优先调用私有过滤器

<div id="app1">{{msg | dataFormat}}</div>
<div id="app2">{{msg}}</div>
<script>
  let vm1 = new Vue({
    el: "#app1",
    data: {
      msg: new Date(),
    },
    methods: {},
    filters: {
      dataFormat: function (data, pattern) {
        let dt = new Date(data);
        let y = dt.getFullYear();
        let m = dt.getMonth() + 1;
        let d = dt.getDate();
        if (pattern && pattern.toLowerCase() === "yyyy-mm-dd") {
          return `${y}-${m}-${d}`;
        } else {
          let hh = dt.getHours();
          let mm = dt.getMinutes();
          let ss = dt.getSeconds();
          return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
        }
      },
    },
  });
  let vm2 = new Vue({
    el: "#app2",
    data: {
      msg: new Date(),
    },
  });
</script>

mark

# 时间补 0 的情况(如:2019-03-29 21:48:20)

# padStart () 的运用

let m = (dt.getMonth() + 1).toString().padStart(2, "0");
let d = dt.getDate().toString().padStart(2, "0");

# 按键修饰符

# 按回车键添加数据(不用按添加按钮)

<input
  type="text"
  class="form-control"
  v-model="name"
  id="name"
  @keyup.enter="add"
/>
<button class="btn  btn-primary" @click="add">添加</button>

# 自定义全局按键修饰符

<input
  type="text"
  class="form-control"
  v-model="name"
  id="name"
  @keyup.f2="add"
/>
<script>
  //自定义全局按键修饰符
  Vue.config.keyCodes.f2 = 113;
</script>

mark

# 自定义全局(私有)的指令

# 自定义全局指令

# 自定义一个自动获取焦点的指令(v-focus)

//参数一:指令的名称,在定义的时候,指令的名称前面,不需要加 v- 前缀,
//在调用的时候,必须 在指令名称前 加上 v- 前缀来调用
//参数二:是一个对象,在这个对象身上,有一些指令相关的函数,这些函数可以在特定的阶段执行相关的操作
Vue.directive("focus", {
  bind: function (el) {
    //每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次
    //注意:在每个函数中,第一个参数永远是el,表示被绑定了指令的那个元素,这个el 参数,是一个元素的JS对象
    //在元素 刚绑定指令的时候,还没有插入到 DOM 中去,这时候,调用 focus 方法没有作用
    //因为,一个元素,只有插入 DOM 之后,才能获取焦点
    // el.focus()
  },
  inserted: function (el) {
    //inserted 表示元素 插入到DOM中的时候,会执行 inserted 函数                                  【触发一次】
    el.focus();
    //和JS行为有关的操作,最好在 inserted 中去执行,防止 JS 行为不生效
  },
  updated: function () {
    //当vNode更新的时候,会执行 updated,可能会触发多次
  },
});

一个指令定义对象可以提供如下几个钩子函数 (均为可选):参考文档

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。

  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

  • unbind:只调用一次,指令与元素解绑时调用。

  • 指令钩子函数会被传入以下参数:

    • el:指令所绑定的元素,可以用来直接操作 DOM 。
    • binding:一个对象,包含以下属性:
      name:指令名,不包括 v- 前缀。
      value:指令的绑定值,例如:v-my-directive=“1 + 1” 中,绑定值为 2。
      oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
      expression:字符串形式的指令表达式。例如 v-my-directive=“1 + 1” 中,表达式为 “1 + 1”。
      arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 “foo”。
      modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 {foo: true, bar: true}。
      vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
      oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

mark

# 自定义一个 设置字体颜色的 指令(v-color)

//样式,只要通过指令绑定了元素,不管这个元素有没有被插入到页面中去,这个元素肯定有了一个内联的样式
//将来元素肯定会显示到页面中去,这时候,浏览器的渲染引擎必然会解析样式,应用给这个元素
bind: function (el) {
    el.style.color = 'red'
    //和样式相关的操作,一般都可以在 bind 执行
  }
})

# 自定义一个 设置字体颜色的 指令 (传参数)

<input
  class="form-control"
  id="search"
  type="text"
  v-model="keywords"
  v-color="'blue'"
  v-focus
/>
<script>
  Vue.directive("color", {
    bind: function (el, binding) {
      el.style.color = binding.value;
      //对比 value 和 expression
      console.log(binding.value);
      console.log(binding.expression);
    },
  });
</script>

mark

# 自定义私有指令

let vm1 = new Vue({
  el: "#app1",
  data: {},
  methods: {},
  directives: {
    //自定义私有指令
    fontweight: {
      bind: function (el, binding) {
        el.style.fontWeight = binding.value;
      },
    },
  },
});

# 函数简写

大多数情况下,我们可能想在 bindupdate 钩子上做重复动作,并且不想关心其它的钩子函数。可以这样写:

Vue.directive("color-swatch", function (el, binding) {
  el.style.backgroundColor = binding.value;
});

例如:自定义一个字体大小的指令

directives: { //自定义私有指令
        'fontsize': function (el, binding) { //这个 function 等同于 把代码写到 bind 和 	update 中去
            el.style.fontSize = parseInt(binding.value)+ 'px'
        }
}

# Vue 实例的生命周期

  1. 生命周期钩子 = 生命周期函数 = 生命周期事件
  2. 举例说明:
<div id="app">
  <button @click="msg='no'">修改msg</button>
  <h3 id="h3">{{msg}}</h3>
</div>
<script>
  let vm = new Vue({
    el: "#app",
    data: {
      msg: "ok",
    },
    methods: {
      show() {
        console.log("执行了show方法");
      },
    },
    beforeCreate() {
      //这是我们遇到的第一个生命周期函数,表示实例完全被创建出来之前,会执行它
      // console.log(this.msg) //undefined
      // this.show()           //TypeError: this.show is not a function
      // 注意:在beforeCreate 生命周期函数执行的时候,data和methods 中的数据未被初始化
    },
    created() {
      //这是我们遇到的第二个生命周期函数
      // console.log(this.msg) //ok
      // this.show()  //执行了show方法
      //在 created中,data 和 methods 都已经被初始化好了!
      //如果要调用 methods 中的方法,或者操作 data中的数据,最早,只能在 created 中操作
    },
    beforeMount() {
      //这是我们遇到的第三个生命周期函数,表示模板已经在内存中编辑完成了,但是尚未把 模板渲染到 页面中
      console.log(document.getElementById("h3").innerText); // {{msg}}
      //在 beforeMount 执行的时候,页面中的元素,还没有被真正替换过来,只是之前写的一些模板字符串
    },
    mounted() {
      //这是我们遇到的第四个生命周期函数,表示内存中的模板,已经真实的挂载到页面中去,用户可以看到渲染好的页面
      console.log(document.getElementById("h3").innerText); // ok
      //注意:mounted 是 实例创建期间的最后一个生命周期函数,当执行完 mounted 就表示,实例已经被完全创建好了,
      // 此时,如果没有其它操作,这个实例,就静静的 躺在内存中,一动不动。
    },

    //接下来是运行中的两个事件
    beforeUpdate() {
      //这时候表示,我们的界面还没有被更新 【数据被更新了吗?数据肯定被更新了】
      // console.log(document.getElementById('h3').innerText) //没有输出任何东西
      console.log(
        "界面上元素的内容:" + document.getElementById("h3").innerText
      ); //界面上元素的内容:ok
      console.log("data中 msg 数据是:" + this.msg); //data中 msg 数据是:no
      //得出结论:当执行 beforeUpdate 的时候,页面中显示的数据还是旧的,此时 data 数据是最新的,页面尚未和最新的数据 保持同步
    },
    updated() {
      console.log(
        "界面上元素的内容:" + document.getElementById("h3").innerText
      ); //界面上元素的内容:no
      console.log("data中 msg 数据是:" + this.msg); //data中 msg 数据是:no
      // updated 事件执行的时候,页面和 data 数据已经保持同步了,都是最新的
    },
  });
</script>

mark

# Vue-resource 实现 get,post,jsonp 请求

Vue-resource 和 axios 的区别

Vue-resource 的基本使用

<script src="../../vue.min.js"></script>
<script src="../../vue-resource-1.3.4.js"></script>
<div id="app">
  <button @click="getInfo">get请求</button>
</div>
<script>
  let vm = new Vue({
    el: "#app",
    data: {
      msg: "这是一句话!",
    },
    methods: {
      getInfo() {
        this.$http.get("../../data.json").then(function (result) {
          console.log(result);
        });
      },
    },
  });
</script>

mark

  • get,post,jsonp 请求
<div id="app">
  <button @click="getInfo">get请求</button>
  <button @click="postInfo">post请求</button>
  <button @click="jsonpInfo">jsonp请求</button>
</div>
<script>
  let vm = new Vue({
    el: "#app",
    data: {
      msg: "这是一句话!",
    },
    methods: {
      getInfo() {
        //发起 get 请求
        this.$http.get("../../data.json").then(function (result) {
          //通过 result.body 拿到服务器返回的成功的数据
          console.log(result.body);
        });
      },
      postInfo() {
        //发起 post  请求
        this.$http.post("../../data.json", {}, {}).then(function (result) {
          //通过 result.body 拿到服务器返回的成功的数据
          console.log(result.body);
        });
      },
      jsonpInfo() {
        //发起 jsonp 请求
        this.$http.jsonp("../../data.json").then(function (result) {
          //通过 result.body 拿到服务器返回的成功的数据
          console.log(result.body);
        });
      },
    },
  });
</script>
Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2015-2021 zhou chen
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信