1. vue 的基礎(chǔ)使用和高級特性

vue 語法基礎(chǔ)
  1. 插值之剧、表達式 2.指令宾毒、動態(tài)屬性 3. v-html: 會有xss風險咽块,會覆蓋子組件
<template>
    <div>
        <p>文本插值 {{message}}</p>
        <p>JS 表達式 {{ flag ? 'yes' : 'no' }} (只能是表達式纪蜒,不能是 js 語句)</p>

        <p :id="dynamicId">動態(tài)屬性 id</p>

        <hr/>
        <p v-html="rawHtml">
            <span>有 xss 風險</span>
            <span>【注意】使用 v-html 之后瓤漏,將會覆蓋子元素</span>
        </p>
    </div>
</template>

<script>
export default {
    data() {
        return {
            message: 'hello vue',
            flag: true,
            rawHtml: '指令 - 原始 html <b>加粗</b> <i>斜體</i>',
            dynamicId: `id-${Date.now()}`
        }
    }
}
</script>

  1. computed
<template>
    <div>
        <p>num {{num}}</p>
        <p>double1 {{double1}}</p>
        <input v-model="double2"/>
    </div>
</template>

<script>
export default {
    data() {
        return {
            num: 20
        }
    },
    computed: {
        double1() {
            return this.num * 2
        },
        double2: {
            get() {
                return this.num * 2
            },
            set(val) {
                this.num = val/2
            }
        }
    }
}
</script>
  1. watch
<template>
    <div>
        <input v-model="name"/>
        <input v-model="info.city"/>
    </div>
</template>

<script>
export default {
    data() {
        return {
            name: '雙越',
            info: {
                city: '北京'
            }
        }
    },
    watch: {
        name(oldVal, val) {
            // eslint-disable-next-line
            console.log('watch name', oldVal, val) // 值類型,可正常拿到 oldVal 和 val
        },
        info: {
            handler(oldVal, val) {
                // eslint-disable-next-line
                console.log('watch info', oldVal, val) // 引用類型校套,拿不到 oldVal 价脾。因為指針相同,此時已經(jīng)指向了新的 val
            },
            deep: true // 深度監(jiān)聽
        }
    }
}
</script>
  1. class 和 style
<template>
    <div>
        <p :class="{ black: isBlack, yellow: isYellow }">使用 class</p>
        <p :class="[black, yellow]">使用 class (數(shù)組)</p>
        <p :style="styleData">使用 style</p>
    </div>
</template>

<script>
export default {
    data() {
        return {
            isBlack: true,
            isYellow: true,

            black: 'black',
            yellow: 'yellow',

            styleData: {
                fontSize: '40px', // 轉(zhuǎn)換為駝峰式
                color: 'red',
                backgroundColor: '#ccc' // 轉(zhuǎn)換為駝峰式
            }
        }
    }
}
</script>

<style scoped>
    .black {
        background-color: #999;
    }
    .yellow {
        color: yellow;
    }
</style>
  1. 條件渲染 v-if v-show(display:none)
<template>
    <div>
        <p v-if="type === 'a'">A</p>
        <p v-else-if="type === 'b'">B</p>
        <p v-else>other</p>

        <p v-show="type === 'a'">A by v-show</p>
        <p v-show="type === 'b'">B by v-show</p>
    </div>
</template>

<script>
export default {
    data() {
        return {
            type: 'a'
        }
    }
}
</script>
  1. 循環(huán)(列表)渲染
<template>
    <div>
        <p>遍歷數(shù)組</p>
        <ul>
            <li v-for="(item, index) in listArr" :key="item.id">
                {{index}} - {{item.id}} - {{item.title}}
            </li>
        </ul>

        <p>遍歷對象</p>
        <ul >
            <li v-for="(val, key, index) in listObj" :key="key">
                {{index}} - {{key}} -  {{val.title}}
            </li>
        </ul>
    </div>
</template>

<script>
export default {
    data() {
        return {
            flag: false,
            listArr: [
                { id: 'a', title: '標題1' }, // 數(shù)據(jù)結(jié)構(gòu)中笛匙,最好有 id 侨把,方便使用 key
                { id: 'b', title: '標題2' },
                { id: 'c', title: '標題3' }
            ],
            listObj: {
                a: { title: '標題1' },
                b: { title: '標題2' },
                c: { title: '標題3' },
            }
        }
    }
}
</script>
// v-for 和 v-if 不建議放在一起,會在循環(huán)中重復(fù)判斷
  1. 事件
    -> event事件膳算,自定義參數(shù)
    -> 事件修飾符座硕,按鍵修飾符
    -> 觀察事件被綁定到哪里?
<template>
    <div>
        <p>{{num}}</p>
        <button @click="increment1">+1</button>
        <button @click="increment2(2, $event)">+2</button>
    </div>
</template>

<script>
export default {
    data() {
        return {
            num: 0
        }
    },
    methods: {
        increment1(event) {
            // eslint-disable-next-line
            console.log('event', event, event.__proto__.constructor) // 是原生的 event 對象
            // eslint-disable-next-line
            console.log(event.target)
            // eslint-disable-next-line
            console.log(event.currentTarget) // 注意涕蜂,事件是被注冊到當前元素的华匾,和 React 不一樣
            this.num++

            // 1. event 是原生的
            // 2. 事件被掛載到當前元素,并在當前元素被觸發(fā)
            // 和 DOM 事件一樣
        },
        increment2(val, event) {
            // eslint-disable-next-line
            console.log(event.target)
            this.num = this.num + val
        },
        loadHandler() {
            // do some thing
        }
    },
    mounted() {
        window.addEventListener('load', this.loadHandler)
    },
    beforeDestroy() {
        //【注意】用 vue 綁定的事件,組建銷毀時會自動被解綁
        // 自己綁定的事件机隙,需要自己銷毀V├!有鹿!
        window.removeEventListener('load', this.loadHandler)
    }
}
</script>
  1. 事件修飾符


    image.png
  2. 按鍵修飾符


    image.png
  3. 表單
    v-model
    常見的表單項 textarea checkbox radio select
    修飾符 lazy number trim

<template>
    <div>
        <p>輸入框: {{name}}</p>
        // 截取前后空格
        <input type="text" v-model.trim="name"/>
        // 防抖的效果
        <input type="text" v-model.lazy="name"/>
        <input type="text" v-model.number="age"/>

        <p>多行文本: {{desc}}</p>
        <textarea v-model="desc"></textarea>
        <!-- 注意旭旭,<textarea>{{desc}}</textarea> 是不允許的!4邪稀持寄! -->

        <p>復(fù)選框 {{checked}}</p>
        <input type="checkbox" v-model="checked"/>

        <p>多個復(fù)選框 {{checkedNames}}</p>
        <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
        <label for="jack">Jack</label>
        <input type="checkbox" id="john" value="John" v-model="checkedNames">
        <label for="john">John</label>
        <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
        <label for="mike">Mike</label>

        <p>單選 {{gender}}</p>
        <input type="radio" id="male" value="male" v-model="gender"/>
        <label for="male">男</label>
        <input type="radio" id="female" value="female" v-model="gender"/>
        <label for="female">女</label>

        <p>下拉列表選擇 {{selected}}</p>
        <select v-model="selected">
            <option disabled value="">請選擇</option>
            <option>A</option>
            <option>B</option>
            <option>C</option>
        </select>

        <p>下拉列表選擇(多選) {{selectedList}}</p>
        <select v-model="selectedList" multiple>
            <option disabled value="">請選擇</option>
            <option>A</option>
            <option>B</option>
            <option>C</option>
        </select>
    </div>
</template>

<script>
export default {
    data() {
        return {
            name: '雙越',
            age: 18,
            desc: '自我介紹',

            checked: true,
            checkedNames: [],

            gender: 'male',

            selected: '',
            selectedList: []
        }
    }
}
</script>

父子組件如何通訊-props 和 emit 組件間通訊-自定義事件-原理: Vue 實例 上封裝了emit onoff

  1. 組件生命周期
    單個組件
 掛載 mounted 
 更新 updated
 銷毀 destoryed
created 之前 new Vue 的實例還沒有生成,只存在于 js 內(nèi)存模型中
mounted 組件還沒有渲染在頁面上娱俺,網(wǎng)頁繪制完成
beforeDestory 里面需要解除綁定稍味,銷毀子組件以及事件監(jiān)聽器

父子組件生命周期

父組件 created
子組件 created
子組件 mounted 
父組件 mounted

父組件 beforeUpdated
子組件 beforeUpdated
子組件 updated
父組件 updated
vue 高級特性
  1. 自定義 v-model
<template>
    <!-- 例如:vue 顏色選擇 -->
    <input type="text"
        :value="text1"
        @input="$emit('change1', $event.target.value)"
    >
    <!--
        1. 上面的 input 使用了 :value 而不是 v-model
        2. 上面的 change1 和 model.event1 要對應(yīng)起來
        3. text1 屬性對應(yīng)起來
    -->
</template>

<script>
export default {
    model: {
        prop: 'text1', // 對應(yīng) props text1
        event: 'change1'
    },
    props: {
        text1: String,
        default() {
            return ''
        }
    }
}
</script>
  1. $nextTick refs (組件更新之后如何獲取最新DOM)
  vue是異步渲染
  data 改變之后,DOM不會立刻渲染
  $nextTick 會在 DOM 渲染之后被觸發(fā)荠卷,以獲取最新的DOM節(jié)點
<template>
  <div id="app">
    <ul ref="ul1">
        <li v-for="(item, index) in list" :key="index">
            {{item}}
        </li>
    </ul>
    <button @click="addItem">添加一項</button>
  </div>
</template>

<script>
export default {
  name: 'app',
  data() {
      return {
        list: ['a', 'b', 'c']
      }
  },
  methods: {
    addItem() {
        this.list.push(`${Date.now()}`)
        this.list.push(`${Date.now()}`)
        this.list.push(`${Date.now()}`)

        // 1. 異步渲染模庐,$nextTick 待 DOM 渲染完再回調(diào)
        // 3. 頁面渲染時會將 data 的修改做整合,多次 data 修改只會渲染一次
        this.$nextTick(() => {
          // 獲取 DOM 元素
          const ulElem = this.$refs.ul1
          // eslint-disable-next-line
          console.log( ulElem.childNodes.length )
        })
    }
  }
}
</script>
  1. slot 父組件想向子組件中插入一部分內(nèi)容
        <!-- slot -->
        <!-- <SlotDemo :url="website.url">
            {{website.title}}
        </SlotDemo> -->
        <!-- <ScopedSlotDemo :url="website.url">
            <template v-slot="slotProps">
                {{slotProps.slotData.title}}
            </template>
        </ScopedSlotDemo> -->
// 基本使用
// SlotDemo 
<template>
    <a :href="url">
        <slot>
            默認內(nèi)容油宜,即父組件沒設(shè)置內(nèi)容時掂碱,這里顯示
        </slot>
    </a>
</template>

<script>
export default {
    props: ['url'],
    data() {
        return {}
    }
}
</script>
// 作用域插槽
// ScopedSlotDemo 
<template>
    <a :href="url">
        <slot :slotData="website">
            {{website.subTitle}} <!-- 默認值顯示 subTitle ,即父組件不傳內(nèi)容時 -->
        </slot>
    </a>
</template>

<script>

export default {
    props: ['url'],
    data() {
        return {
            website: {
                url: 'http://wangEditor.com/',
                title: 'wangEditor',
                subTitle: '輕量級富文本編輯器'
            }
        }
    }
}
</script>

// 具名插槽


image.png
  1. 異步組件
 <!-- 動態(tài)組件 --> 根據(jù)數(shù)據(jù)慎冤,動態(tài)渲染的場景疼燥,即組件類型不確定
語法: :is="xxx"  xxx 組件的名字
<component :is="NextTickName"/>
  1. 異步組件
   * import() 函數(shù)
   * 按需加載,異步加載大組件
 <!-- 異步組件 -->
 <FormDemo v-if="showFormDemo"/>
 <button @click="showFormDemo = true">show form demo</button> 
 export default {
     components: {
        FormDemo: () => import('../BaseUse/FormDemo')
     }
  }
  1. keep-alive (vue 如何緩存組件)適用場景:需要頻繁切換的組件
* activated
   <keep-alive> <!-- tab 切換 -->
        <KeepAliveStageA v-if="state === 'A'"/>
        <KeepAliveStageB v-if="state === 'B'"/>
        <KeepAliveStageC v-if="state === 'C'"/>
    </keep-alive>
  1. mixin (vue組件代碼抽取蚁堤,多個組件有相同的邏輯醉者,抽離出來)
* 變量來源不明確;
* mixin抽離的代碼 data 里面的命名變量不能相同,會存在覆蓋的問題湃交;命名沖突;
* mixin 和 組件可能出現(xiàn)多對多的關(guān)系藤巢,復(fù)雜度比較高搞莺;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市掂咒,隨后出現(xiàn)的幾起案子才沧,更是在濱河造成了極大的恐慌,老刑警劉巖绍刮,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件温圆,死亡現(xiàn)場離奇詭異,居然都是意外死亡孩革,警方通過查閱死者的電腦和手機岁歉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來膝蜈,“玉大人锅移,你說我怎么就攤上這事”ゲ” “怎么了非剃?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長推沸。 經(jīng)常有香客問我备绽,道長,這世上最難降的妖魔是什么鬓催? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任肺素,我火速辦了婚禮,結(jié)果婚禮上深浮,老公的妹妹穿的比我還像新娘压怠。我一直安慰自己,他們只是感情好飞苇,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布菌瘫。 她就那樣靜靜地躺著,像睡著了一般布卡。 火紅的嫁衣襯著肌膚如雪雨让。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天忿等,我揣著相機與錄音栖忠,去河邊找鬼。 笑死,一個胖子當著我的面吹牛庵寞,可吹牛的內(nèi)容都是我干的狸相。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼捐川,長吁一口氣:“原來是場噩夢啊……” “哼脓鹃!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起古沥,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤瘸右,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后岩齿,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體太颤,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年盹沈,在試婚紗的時候發(fā)現(xiàn)自己被綠了龄章。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡襟诸,死狀恐怖瓦堵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情歌亲,我是刑警寧澤菇用,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站陷揪,受9級特大地震影響惋鸥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜悍缠,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一卦绣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧飞蚓,春花似錦滤港、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至著榴,卻和暖如春添履,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背脑又。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工暮胧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留锐借,地道東北人。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓往衷,卻偏偏與公主長得像钞翔,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子席舍,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359

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