Vue 基礎(chǔ)

Vue 實(shí)例

1. Vue實(shí)例

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  自動(dòng)注銷
    }
  }
})

const app = new Vue({
})
app.$mount('#app')

setTimeout(function(){
  app.num += 1
}, 1000)

2. 實(shí)例屬性

// Vue 實(shí)例觀察的數(shù)據(jù)對象踩麦。Vue 實(shí)例代理了對其 data 對象屬性的訪問游昼。
console.log(app.$data)    // num : 0

// 當(dāng)前組件接收到的 props 對象煤蹭。Vue 實(shí)例代理了對其 props 對象屬性的訪問码泛。
console.log(app.$props)    // undefined

// Vue實(shí)例使用的根 DOM 元素
console.log(app.$el)    // <div>0</div>

// 用于當(dāng)前 Vue 實(shí)例的初始化選項(xiàng)
console.log(app.$options)    // {components: {…}, directives: {…}, filters: {…}, _base: ?, el: "#app", …}

app.$options.render = (h) => {
  return h('div', {}, 'new render')    // 需重新渲染時(shí)才會(huì)生效
}

// 當(dāng)前組件樹的根 Vue 實(shí)例逝变。如果當(dāng)前實(shí)例沒有父實(shí)例,此實(shí)例將會(huì)是其自己必逆。
console.log(app.$root)
console.log(app.$root === app)    // true

// 當(dāng)前實(shí)例的直接子組件萍嬉。需要注意 $children 并不保證順序,也不是響應(yīng)式的腰池。
console.log(app.$children)

// 用來訪問被插槽分發(fā)的內(nèi)容尾组。每個(gè)具名插槽有其相應(yīng)的屬性 (例如:`slot="foo"` 中的內(nèi)容將會(huì)在 `vm.$slots.foo` 中被找到)。default 屬性包括了所有沒有被包含在具名插槽中的節(jié)點(diǎn)示弓。
console.log(app.$slots)
console.log(app.$scopedSlots)

// 一個(gè)對象讳侨,持有注冊過 ref 特性的所有 DOM 元素和組件實(shí)例。
console.log(app.$refs)    // {div: div}

// 當(dāng)前 Vue 實(shí)例是否運(yùn)行于服務(wù)器奏属。  一般服務(wù)端渲染才會(huì)用
console.log(app.$isServer)

3. 實(shí)例方法/數(shù)據(jù)

//  Vue 實(shí)例變化的一個(gè)表達(dá)式或計(jì)算屬性函數(shù)跨跨。回調(diào)函數(shù)得到的參數(shù)為新值和舊值
const unwatch = app.$watch('num', (newNum, oldNum) => {
  console.log(`${newNum} : ${oldNum}`)    // 1 : 0
})
unwatch()    // 注銷watch

// 鍵路徑
vm.$watch('a.b.c', function (newVal, oldVal) {
  // 做點(diǎn)什么
})

// 函數(shù)
vm.$watch(
  function () {
    return this.a + this.b
  },
  function (newVal, oldVal) {
    // 做點(diǎn)什么
  }
)
全局 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. 實(shí)例方法/事件

// 監(jiān)聽當(dāng)前實(shí)例上的自定義事件勇婴。事件可以由vm.$emit觸發(fā)≈鲂龋回調(diào)函數(shù)會(huì)接收所有傳入事件觸發(fā)函數(shù)的額外參數(shù)耕渴。
app.$on('num', (a, b) => {
  console.log(`emit again ${a} $`)
})
app.$emit('num', 1, 2)    // emit again 1 2

vm.$on('test', function (msg) {
  console.log(msg)
})
vm.$emit('test', 'hi')
// => "hi"
// 監(jiān)聽一個(gè)自定義事件齿兔,但是只觸發(fā)一次橱脸,在第一次觸發(fā)之后移除監(jiān)聽器
app.$once('num',() => {

})

5. 實(shí)例方法/生命周期

// 迫使 Vue 實(shí)例重新渲染。注意它僅僅影響實(shí)例本身和插入插槽內(nèi)容的子組件分苇,而不是所有子組件添诉。
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()  // 強(qiáng)制重新渲染
}, 1000)
將回調(diào)延遲到下次 DOM 更新循環(huán)之后執(zhí)行。在修改數(shù)據(jù)之后立即使用它组砚,然后等待 DOM 更新吻商。
它跟全局方法 Vue.nextTick 一樣,不同的是回調(diào)的 this 自動(dòng)綁定到調(diào)用它的實(shí)例上糟红。

new Vue({
  // ...
  methods: {
    // ...
    example: function () {
      // 修改數(shù)據(jù)
      this.message = 'changed'
      // DOM 還沒有更新
      this.$nextTick(function () {
        // DOM 現(xiàn)在更新了
        // `this` 綁定到當(dāng)前實(shí)例
        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 是在實(shí)例掛載的時(shí)候才開始執(zhí)行的, 跟掛在到頁面上顯示的內(nèi)容有關(guān)系

該鉤子在服務(wù)器端渲染期間不被調(diào)用艾帐。 無DOM執(zhí)行環(huán)境
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)


每次數(shù)據(jù)更新時(shí)開始執(zhí)行 beforeUpdate updated
beforeUpdate    數(shù)據(jù)更新時(shí)調(diào)用,發(fā)生在虛擬 DOM 打補(bǔ)丁之前盆偿。這里適合在更新之前訪問現(xiàn)有的 DOM柒爸,比如手動(dòng)移除已添加的事件監(jiān)聽器。
updated    當(dāng)這個(gè)鉤子被調(diào)用時(shí)事扭,組件 DOM 已經(jīng)更新捎稚,所以你現(xiàn)在可以執(zhí)行依賴于 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    實(shí)例銷毀之前調(diào)用。在這一步,實(shí)例仍然完全可用今野。
destroyed        Vue 實(shí)例銷毀后調(diào)用葡公。調(diào)用后,Vue 實(shí)例指示的所有東西都會(huì)解綁定条霜,所有的事件監(jiān)聽器會(huì)被移除催什,所有的子實(shí)例也會(huì)被銷毀。
打印  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 有關(guān)的操作一般放在 mounted 中
跟數(shù)據(jù)有關(guān)的操作可以放在 created 或者 mounted

Vue 數(shù)據(jù)綁定

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 計(jì)算屬性是基于它們的依賴進(jìn)行緩存的,計(jì)算屬性只有在相關(guān)依賴發(fā)生改變時(shí)才會(huì)重新求值, 計(jì)算屬性緩存

// 計(jì)算屬性緩存
計(jì)算屬性的值會(huì)被緩存, 只有在其某個(gè)反應(yīng)依賴改變時(shí)才會(huì)重新計(jì)算

// 計(jì)算setter
計(jì)算屬性computed 默認(rèn)只有g(shù)etter , 不過在需要時(shí)也可以提供一個(gè) 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 的數(shù)據(jù)開始是沒有變化的, 當(dāng)相應(yīng)其他數(shù)據(jù)發(fā)生變化,watch數(shù)據(jù)的值才會(huì)變化

  watch:{
    firstName : {
      handler (newName,oldName) {
        this.fullName = newName + '' + this.lastName
      },
      immediate: true,
      deep:true
    }
  }

數(shù)據(jù)立即執(zhí)行  immediate: true
為了發(fā)現(xiàn)對象內(nèi)部值的變化宰睡,可以在選項(xiàng)參數(shù)中指定 deep: true

watch 主要場景監(jiān)聽到某一數(shù)據(jù)變化,要去做某一個(gè)指定的變化, 需要watch 數(shù)據(jù)的變化
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蒲凶,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子拆内,更是在濱河造成了極大的恐慌旋圆,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件麸恍,死亡現(xiàn)場離奇詭異灵巧,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)或南,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門孩等,熙熙樓的掌柜王于貴愁眉苦臉地迎上來艾君,“玉大人采够,你說我怎么就攤上這事”ⅲ” “怎么了蹬癌?”我有些...
    開封第一講書人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長虹茶。 經(jīng)常有香客問我逝薪,道長,這世上最難降的妖魔是什么蝴罪? 我笑而不...
    開封第一講書人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任董济,我火速辦了婚禮,結(jié)果婚禮上要门,老公的妹妹穿的比我還像新娘虏肾。我一直安慰自己,他們只是感情好欢搜,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般挂洛。 火紅的嫁衣襯著肌膚如雪斩郎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,115評(píng)論 1 296
  • 那天,我揣著相機(jī)與錄音缘琅,去河邊找鬼粘都。 笑死,一個(gè)胖子當(dāng)著我的面吹牛刷袍,可吹牛的內(nèi)容都是我干的驯杜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼做个,長吁一口氣:“原來是場噩夢啊……” “哼鸽心!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起居暖,我...
    開封第一講書人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬榮一對情侶失蹤顽频,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后太闺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體糯景,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年省骂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蟀淮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡钞澳,死狀恐怖怠惶,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情轧粟,我是刑警寧澤策治,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站兰吟,受9級(jí)特大地震影響通惫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜混蔼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一履腋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惭嚣,春花似錦遵湖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至载矿,卻和暖如春垄潮,著一層夾襖步出監(jiān)牢的瞬間烹卒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來泰國打工弯洗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留旅急,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓牡整,卻偏偏與公主長得像藐吮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子逃贝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 一沐扳、模版指令 通過模版指令(寫在html中的)泥从,即是html和vue對象的粘合劑。 數(shù)據(jù)渲染 v-text沪摄、v-h...
    EndEvent閱讀 2,402評(píng)論 3 56
  • Vue實(shí)例 Vue實(shí)例創(chuàng)建和作用 -- 1. app.$data -> 所有data的數(shù)據(jù) [obj](app.d...
    胖太_91bf閱讀 3,515評(píng)論 0 3
  • 相關(guān)概念 混合開發(fā)和前后端分離 混合開發(fā)(服務(wù)器端渲染) 前后端分離后端提供接口躯嫉,前端開發(fā)界面效果(專注于用戶的交...
    他愛在黑暗中漫游閱讀 2,790評(píng)論 4 45
  • Vue簡介 Vue是數(shù)據(jù)驅(qū)動(dòng)組件,為現(xiàn)代化的Web頁面而生杨拐,與ReactJS的中心思想一樣祈餐,都是一切皆是組件。他是...
    Victor細(xì)節(jié)閱讀 628評(píng)論 2 3
  • 每個(gè) Vue 應(yīng)用都是通過用 Vue 函數(shù)創(chuàng)建一個(gè)新的 Vue 實(shí)例開始的: 實(shí)例生命周期鉤子 每個(gè) Vue 實(shí)例...
    Timmy小石匠閱讀 1,380評(píng)論 0 11