美文网首页
Vue 基础

Vue 基础

作者: YM雨蒙 | 来源:发表于2018-06-21 13:55 被阅读11次

    Vue 实例

    1. Vue实例

    const app = new Vue({
      el: '#app',
      template: '<div ref="div">{{ num }}</div>'
      data: {
        num: 0
      },
      props: {
    
      },
      watch: {
        num (newNum, oldNum) {
          console.log(`${newNum} : ${oldNum}`)    // 1 : 0  自动注销
        }
      }
    })
    
    const app = new Vue({
    })
    app.$mount('#app')
    
    setTimeout(function(){
      app.num += 1
    }, 1000)
    

    2. 实例属性

    // Vue 实例观察的数据对象。Vue 实例代理了对其 data 对象属性的访问。
    console.log(app.$data)    // num : 0
    
    // 当前组件接收到的 props 对象。Vue 实例代理了对其 props 对象属性的访问。
    console.log(app.$props)    // undefined
    
    // Vue实例使用的根 DOM 元素
    console.log(app.$el)    // <div>0</div>
    
    // 用于当前 Vue 实例的初始化选项
    console.log(app.$options)    // {components: {…}, directives: {…}, filters: {…}, _base: ƒ, el: "#app", …}
    
    app.$options.render = (h) => {
      return h('div', {}, 'new render')    // 需重新渲染时才会生效
    }
    
    // 当前组件树的根 Vue 实例。如果当前实例没有父实例,此实例将会是其自己。
    console.log(app.$root)
    console.log(app.$root === app)    // true
    
    // 当前实例的直接子组件。需要注意 $children 并不保证顺序,也不是响应式的。
    console.log(app.$children)
    
    // 用来访问被插槽分发的内容。每个具名插槽有其相应的属性 (例如:`slot="foo"` 中的内容将会在 `vm.$slots.foo` 中被找到)。default 属性包括了所有没有被包含在具名插槽中的节点。
    console.log(app.$slots)
    console.log(app.$scopedSlots)
    
    // 一个对象,持有注册过 ref 特性的所有 DOM 元素和组件实例。
    console.log(app.$refs)    // {div: div}
    
    // 当前 Vue 实例是否运行于服务器。  一般服务端渲染才会用
    console.log(app.$isServer)
    

    3. 实例方法/数据

    //  Vue 实例变化的一个表达式或计算属性函数。回调函数得到的参数为新值和旧值
    const unwatch = app.$watch('num', (newNum, oldNum) => {
      console.log(`${newNum} : ${oldNum}`)    // 1 : 0
    })
    unwatch()    // 注销watch
    
    // 键路径
    vm.$watch('a.b.c', function (newVal, oldVal) {
      // 做点什么
    })
    
    // 函数
    vm.$watch(
      function () {
        return this.a + this.b
      },
      function (newVal, oldVal) {
        // 做点什么
      }
    )
    
    全局 Vue.set 的别名
    vm.$set( target, key, value )
    
    全局 Vue.delete 的别名。
    vm.$delete( target, key )
    
    const app = new Vue({
      el: '#app',
      template: '<div ref="div">{{ num }} {{ obj.a }}</div>',
      data: {
        num: 0,
        obj: {}
      },
      watch: {
        num (newNum, oldNum) {
          console.log(`${newNum} : ${oldNum}`)
        }
      }
    })
    
    let i = 0
    setTimeout(function(){
      i++
      app.$set('app.obj', 'a', i)
    
      app.$delete('app.obj', 'a')
      // app.obj.a = i
      // app.$forceUpdate()
    }, 1000)
    

    4. 实例方法/事件

    // 监听当前实例上的自定义事件。事件可以由vm.$emit触发。回调函数会接收所有传入事件触发函数的额外参数。
    app.$on('num', (a, b) => {
      console.log(`emit again ${a} ${b}`)
    })
    app.$emit('num', 1, 2)    // emit again 1 2
    
    vm.$on('test', function (msg) {
      console.log(msg)
    })
    vm.$emit('test', 'hi')
    // => "hi"
    
    // 监听一个自定义事件,但是只触发一次,在第一次触发之后移除监听器
    app.$once('num',() => {
    
    })
    

    5. 实例方法/生命周期

    // 迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。
    const app = new Vue({
      el: '#app',
      template: '<div ref="div">{{ num }} {{ obj.a }}</div>',
      data: {
        num: 0,
        obj: {}
      },
      watch: {
        num (newNum, oldNum) {
          console.log(`${newNum} : ${oldNum}`)
        }
      }
    })
    
    let i = 0
    setTimeout(function(){
      i++
      app.obj.a = i
      app.$forceUpdate()  // 强制重新渲染
    }, 1000)
    
    将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。
    它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。
    
    new Vue({
      // ...
      methods: {
        // ...
        example: function () {
          // 修改数据
          this.message = 'changed'
          // DOM 还没有更新
          this.$nextTick(function () {
            // DOM 现在更新了
            // `this` 绑定到当前实例
            this.doSomethingElse()
          })
        }
      }
    })
    

    Vue生命周期方法

    new Vue({
      el: '#app',
      template: '<div>{{ text }}</div>',
      data: {
        text: 0
      },
      beforeCreate () {
        console.log(this, 'beforeCreate')     // =>1  "beforeCreate"
      },
      created () {
        console.log(this, 'created')    // =>2   "created"
      },
      beforeMount () {
        console.log(this, 'beforeMount')    // =>3   "beforeMount"
      },
      mounted () {
        console.log(this, 'mounted')     // =>4 "mounted"
      },
      beforeUpdate () {
        console.log(this, 'beforeUpdate')
      },
      updated () {
        console.log(this, 'updated')
      },
      activated () {
        console.log(this, 'activated')
      },
      deactivated () {
        console.log(this, 'deactivated')
      },
      beforeDestroy () {
        console.log(this, 'beforeDestroy')
      },
      destroyed () {
        console.log(this, 'destroyed')
      }
    })
    
    Ajax 操作赋值 最早也要在 created中
    
    new Vue({
      // el: '#app',
      template: '<div>{{ text }}</div>',
      data: {
        text: 0
      },
      beforeCreate () {
        console.log(this, 'beforeCreate')    // => "beforeCreate"
      },
      created () {
        console.log(this, 'created')    // => "created"
      },
      beforeMount () {
        console.log(this, 'beforeMount')
      },
      mounted () {
        console.log(this, 'mounted')
      },
      beforeUpdate () {
        console.log(this, 'beforeUpdate')
      },
      updated () {
        console.log(this, 'updated')
      },
      activated () {
        console.log(this, 'activated')
      },
      deactivated () {
        console.log(this, 'deactivated')
      },
      beforeDestroy () {
        console.log(this, 'beforeDestroy')
      },
      destroyed () {
        console.log(this, 'destroyed')
      }
    })
    
    
    app.$mount('#app')
    
    beforeMount  mounted 是在实例挂载的时候才开始执行的, 跟挂在到页面上显示的内容有关系
    
    该钩子在服务器端渲染期间不被调用。 无DOM执行环境
    
    const app = new Vue({
      el: '#app',
      template: '<div>{{ text }}</div>',
      data: {
        text: 0
      },
      beforeCreate () {
        console.log(this, 'beforeCreate')    // => "beforeCreate"
      },
      created () {
        console.log(this, 'created')    // => "created"
      },
      beforeMount () {
        console.log(this, 'beforeMount')    // => beforeMount
      },
      mounted () {
        console.log(this, 'mounted')    // => Mounted
      },
      beforeUpdate () {
        console.log(this, 'beforeUpdate')    // => beforeUpdate
      },
      updated () {
        console.log(this, 'updated')    // => updated
      },
      activated () {
        console.log(this, 'activated')
      },
      deactivated () {
        console.log(this, 'deactivated')
      },
      beforeDestroy () {
        console.log(this, 'beforeDestroy')
      },
      destroyed () {
        console.log(this, 'destroyed')
      }
    })
    
    setTimeout(()=> {
      app.text += 1
    }, 1000)
    
    
    每次数据更新时开始执行 beforeUpdate updated
    beforeUpdate    数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
    updated    当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作
    
    const app = new Vue({
      el: '#app',
      template: '<div>{{ text }}</div>',
      data: {
        text: 0
      },
      beforeCreate () {
        console.log(this, 'beforeCreate')    // => "beforeCreate"
      },
      created () {
        console.log(this, 'created')    // => "created"
      },
      beforeMount () {
        console.log(this, 'beforeMount')    // => beforeMount
      },
      mounted () {
        console.log(this, 'mounted')    // => Mounted
      },
      beforeUpdate () {
        console.log(this, 'beforeUpdate')    // => beforeUpdate
      },
      updated () {
        console.log(this, 'updated')    // => updated
      },
      activated () {
        console.log(this, 'activated')
      },
      deactivated () {
        console.log(this, 'deactivated')
      },
      beforeDestroy () {
        console.log(this, 'beforeDestroy')    // => beforeDestroy
      },
      destroyed () {
        console.log(this, 'destroyed')    // => destroyed
      }
    })
    
    setTimeout(()=> {
      app.text += 1
    }, 1000)
    
    setTimeout(()=> {
      app.$destroy()    // 销毁
    },2000)
    
    beforeDestroy    实例销毁之前调用。在这一步,实例仍然完全可用。
    destroyed        Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
    
    打印  this.$el
    
    const app = new Vue({
      el: '#app',
      template: '<div>{{ text }}</div>',
      data: {
        text: 0
      },
      beforeCreate () {
        console.log(this.$el, 'beforeCreate')    // undefined  "beforeCreate"
      },
      created () {
        console.log(this.$el, 'created')    // undefined  "created"
      },
      beforeMount () {
        console.log(this.$el, 'beforeMount')     // <div id="app"></div>   "beforeMount"
      },
      mounted () {
        console.log(this.$el, 'mounted')    //  <div>0</div>  "mounted"
      },
      beforeUpdate () {
        console.log(this, 'beforeUpdate')
      },
      updated () {
        console.log(this, 'updated')
      },
      activated () {
        console.log(this, 'activated')
      },
      deactivated () {
        console.log(this, 'deactivated')
      },
      beforeDestroy () {
        console.log(this, 'beforeDestroy')
      },
      destroyed () {
        console.log(this, 'destroyed')
      }
    })
    
    跟 DOM 有关的操作一般放在 mounted 中
    跟数据有关的操作可以放在 created 或者 mounted
    

    Vue 数据绑定

    const app = new Vue({
      el: '#app',
      template: `
              <div>
                {{ isActive ? 'active' : 'not active' }}
                {{ arr.join('*') }}
                {{ Date.now() }}
                {{ html }}
                <p v-html="html"></p>
              </div>
      `,
      data: {
        isActive: false,
        arr: [1,2,3],
        html: '<span>123<span>'
      },
    })
    
    
    const app = new Vue({
      el: '#app',
      template: `
              <div :class="{ active : !isActive}" @click="handler" :id="aaa">
               <p v-html="html"></p>
              </div>
      `,
      data: {
        isActive: false,
        arr: [1,2,3],
        html: '<span>123<span>',
        aaa: 'main'
      },
      methods: {
        handler: function() {
          console.log('123')
        }
      }
    })
    

    computed & watch & methods

    new Vue({
      el: '#app',
      template: `
        <div>
          <span>Name: {{name}}</span>
          <br/>
          <span>Name: {{getName()}}</span>
          <br/>
          <span>Number: {{num}}</span>
          <p><input type = "text" v-model="num"></p>
          <p>firstName: <input type = "text" v-model="firstName"></p>
          <p>lastName: <input type = "text" v-model="lastName"></p>
        </div>
      `,
      data: {
        firstName: 'yym',
        lastName: 'Hello',
        num: 0
      },
      computed: {
        name () {
          console.log('new Name')
          return `${this.firstName} ${this.lastName}`
        }
      },
      methods: {
        getName () {
          console.log('getName invoked')
          return `${this.firstName} ${this.lastName}`
        }
      }
    })
    
    computed 计算属性是基于它们的依赖进行缓存的,计算属性只有在相关依赖发生改变时才会重新求值, 计算属性缓存
    
    // 计算属性缓存
    计算属性的值会被缓存, 只有在其某个反应依赖改变时才会重新计算
    
    // 计算setter
    计算属性computed 默认只有getter , 不过在需要时也可以提供一个 setter
    
      computed: {
        name : {
          // getter
          get: function () {
            return `${this.firstName} ${this.lastName}`
          }
          // setter
          set: function (newValue) {
            const name = newValue.split(' ')
            this.firstName = names[0]
            this.lastName = names[names.length - 1]
          }
        }
      },
    
    new Vue({
      el: '#app',
      template: `
        <div>
          <span>Name: {{name}}</span>
          <br/>
          <span>Name: {{getName()}}</span>
          <br/>
          <span>fullName: {{ fullName }}</span>
          <br/>
          <span>Number: {{num}}</span>
          <p><input type = "text" v-model="num"></p>
          <p>firstName: <input type = "text" v-model="firstName"></p>
          <p>lastName: <input type = "text" v-model="lastName"></p>
        </div>
      `,
      data: {
        firstName: 'yym',
        lastName: 'Hello',
        num: 0,
        fullName: ''
      },
      computed: {
        name () {
          console.log('new Name')
          return `${this.firstName} ${this.lastName}`
        }
      },
      methods: {
        getName () {
          console.log('getName invoked')
          return `${this.firstName} ${this.lastName}`
        }
      },
      watch:{
        firstName (newName,oldName) {
          this.fullName = newName + '' + this.lastName
        }
      }
    })
    
    
    watch 的数据开始是没有变化的, 当相应其他数据发生变化,watch数据的值才会变化
    
      watch:{
        firstName : {
          handler (newName,oldName) {
            this.fullName = newName + '' + this.lastName
          },
          immediate: true,
          deep:true
        }
      }
    
    数据立即执行  immediate: true
    为了发现对象内部值的变化,可以在选项参数中指定 deep: true
    
    watch 主要场景监听到某一数据变化,要去做某一个指定的变化, 需要watch 数据的变化
    

    相关文章

      网友评论

          本文标题:Vue 基础

          本文链接:https://www.haomeiwen.com/subject/atpyeftx.html