Vue---生命周期的钩子函数和组件的相关属性

计算属性

  • 计算属性 - 表单的验证提示信息

    根据表单的值而变化

  • 购物车 - 计算商品的总数以及总价

    根据商品的信息而变化

只要你的这个值可以通过 一部分 基础数据计算而来,就可以使用计算属性

任何复杂的业务逻辑,我们都应当使用计算属性,但不是必须

侦听属性 - 监听属性

7a536641159cd472738ee892801f26fe.png

假设此案例使用计算属性实现

956f002e864fd1a43866a4cccbfb5570.png

计算属性PK方法

36475d686082b77c1c239120a0074f67.png

446f792a041c428698c93c5dbbccd14e.png

面试题:在vue如何监听一个对象下面的属性的变化
fb282119d9eca584528a290de561b3eb.png
d00574146fcb58b641993955a84273b1.png

watch 监听某个对象user,user书写形式为 一个对象,设置handler 函数属性,记录变化,使用deep设置为深度监听,使用immediate设置立即以表达式的当前值触发回调

vue的生命周期钩子函数

每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。

c52fc0b5ccdc03b7ea7e626427de3304.png

742486ea7549633c32424ea0c4fd9423.png

  • beforeCreate --- 怀孕之前
    在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
    一般不用

  • created ---- 怀上了
    在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前尚不可用。
    视情况而定,使用它可以请求数据

  • beforeMount --- 马上要生了 -- 预产期
    在挂载开始之前被调用:相关的 render 函数首次被调用。
    一般不用

  • mounted - 生下了
    实例被挂载后调用,这时 el 被新创建的 vm.el 替换了。 如果根实例挂载到了一个文档内的元素上,当mounted被调用时vm.el也在文档内。
    用的很多,可以进行数据请求,可以进行DOM操作,可以设置定时器,计时器等,类似于js中的 window.onload

  • beforeUpdate ---- 变化前
    数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
    一般不用

  • updated ---- 变化后
    当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作
    可以进行DOM操作,但是千万不要修改状态,状态改变,就会触发此钩子 -- 无限循环

  • beforeDestroy
    实例销毁之前调用。在这一步,实例仍然完全可用。
    移除事件绑定等操作

  • destroyed
    实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。
    用的相对较少

<body>
  <div id="app">
    {{ msg }}
    <button @click="msg += 1">更新</button>
    <button @click="gameover">gameover</button>
  </div></body><script>
  var app = new Vue({
    el: '#app',
    data: {
      msg: 'hello'
    },
    methods: {
      gameover () {
        console.log(this.msg)
        this.$destroy()
      }
    },
    beforeCreate () {
      console.log('beforeCreate')
    },
    created () {
      console.log('created')
    },
    beforeMount () {
      console.log('beforeMount')
    },
    mounted () {
      console.log('mounted')
    },
    beforeUpdate () {
      console.log('beforeUpdate')
    },
    updated () {
      console.log('updated')
    },
    beforeDestroy () {
      console.log('beforeDestroy')
    },
    destroyed () {
      console.log('destroyed')
    }
  })
</script>

数据请求

XMLHttpRequest / ActiveXObject

jQuery - $.ajax() / $.get / $.post / $.getJson() / $.getScript() / $.load()

vue vue-resource / fetch / axios

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script>

接口无跨域 app.js, 过滤了banner的token验证
728e28e0035baa0719895e1f65cd7422.png
d1163b6a4ce90380a3450c192380ea0d.png

<body>
  <div id="app">
    <img :src="item.img" v-for="item of bannerlist" :key="item.bannerid" alt="">
  </div></body><script>
  new Vue({
    el: '#app',
    data: {
      bannerlist: []
    },
    // 也可以在created中作数据请求
    mounted () {
      // 启动 node 接口  (数据库 + node接口)
      // 遇到跨域 --- 服务器端解决跨域 -- 自定义一个中间件
      /***
       * app.js文件中添加如下代码 - 解决跨域问题
       * // 自定义中间件 ---  解决跨域问题
        var allowCrossDomain = (req, res, next) => {
          // 所有接口均可以访问服务器
          res.header('Access-Control-Allow-Origin', '*')
          res.header('Access-Control-Allow-Headers', '*')
          next()
        }
        // 使用自定义跨域中间件
        app.use(allowCrossDomain)
       * */
      // vue-resource
      this.$http.get('http://localhost:3000/api/banner')
        .then((res) => {
          console.log(res)
          this.bannerlist = res.body.data
        }, () => {
          console.log('请求失败处理');
        })
    }
  })
</script>
  • fetch

基于Promise而设计的原生js支持的一种数据请求的方式,不需要安装或者依赖任何的东西,直接就可以使用,好比XMLHttpRequest对象

fetch 请求默认返回的是一个promise对象,需要先行转换为一个json对象,然后再去做业务逻辑

fetch 默认使用的就是 get请求

9688f09fecdc6f433affbfe212501d55.png

假设如果是post请求

fetch(url, {
    method: 'post',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: 'name=111&password=122''
})

7a9a6cbc1b9994b5a51de86900858134.png
c3d75c416883ad64c8f080caca786eba.png

fetch(url, {
    method: 'post',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({
        name: 111,
        password: 122
    })
})

ebf884bb7eac95190500b303c71154ab.png
32c9d02645ba8edf89d8ac835a525ed8.png

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
7391f83c6505e3c562e70c859e93f6cf.png

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

get

axios.get(url + '?a=1&b=2'').then(res => {}).catch(() => {})
axios.get(url, { params: { a: 1, b:2 }}).then(res => {}).catch(() => {})

axios({
    method: 'get',
    url: url,
    data: {
        a: 1,
        b: 2
    }
}).then(res => {}).catch(() => {})

53487a29e07d6bae70228aa93cf9d57d.png
df14adca0fbe1b86b630b3841745210a.png
30a839ee4a5509d059727adcc4cce401.png

post

axios.post(url, {a: 1, b:2}).then().catch()

axios({
    method: 'post',
    url: url,
    data: {
        a: 1,
        b: 2
    }
}).then(res => {}).catch(() => {})

dcc9d75e1617e0e7a1927171a97a263c.png

面试题: 如果一个页面有很多歌请求,如何保证所有请求都结束之后才执行下一步

promise.all实现,我们常用的是axios所以使用的就是axios.all()

function getdata1 () {
    return axios.get(url1)
}
function getdata2 () {
    return axios.get(url2)
}

axios.all([getdata1(), getdata2()]).then(axios.spread((data1, data2) => {
    console.log(data1)
    console.log(data2)
))

自定义axios

<body>
  <div id="app">
    <img :src="item.img" v-for="item of bannerlist" :key="item.bannerid" alt="">
  </div></body><script>
  // 自定义axios
  var instance = axios.create({
    baseURL: 'http://localhost:3000/api'
  })
  // 假设如果很多接口都需要使用 token验证,可以把token信息放在请求头
  instance.defaults.headers.token = '1231654984561646546565464654654646321654asdasdasd'
  new Vue({
    el: '#app',
    data: {
      bannerlist: []
    },
    mounted () {
      // instance({
      //   method: 'get',
      //   url: '/banner'
      // }).then(res => {
      //   this.bannerlist = res.data.data
      // }).catch(() => {})
      instance.get('/banner').then(res => {
        this.bannerlist = res.data.data
      })
    }
  })
</script>

拦截器的使用 - 并不是自定义之后才能设置,只要有axios就可以
4c07f434d43dcb68cbadcb2ecf8f4c3c.png

-------------------------------------------------------文章来自吴大勋(大勋说
posted @ 2020-04-20 23:33  haccer  阅读(219)  评论(0)    收藏  举报