vue基礎知識

Vue基礎知識整理

vue實例方法:

    <div id="root">
      {{num}}
      <my-components></my-components>
    </div>
    <template id="tem">
      <div>
        <p>這是組件</p>
      </div>
    </template>
  </body>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script type="text/javascript">
    const app = new Vue({
      el: "#root",
      data: {
        num: 123,
        obj: {c: 666}
        
        
      },
      components: {
        "my-components": {
          
          template: "#tem"
        }
      }
    })
  </script>
  • app.$elapp.$refs都是獲取dom的節點,app.$el是組件掛載的節點,而app.$refs.xxx則是ref=xxx的節點
  • app.$data用於獲取data中的所有數據,如果要直接獲取數據可以通過app.$num某個屬性即可
  • app.$children獲取子組件
  • app.$root === app相等獲取vue實例
  • app.$options返回一個對象,裏面包含創建vue實例時傳入的參數以及默認的參數,所以可以通過app.$options.data().num來獲取數據;app.$options.render = (h) => h("div", {}, "頁面上數據重新update時觸發"),例如加個定時器,那麼h函數就會執行並渲染頁面
  • const unWatch = app.$watch('xx', (n, o) => {}),可用來監聽data中的數據變化,但是用app監聽是,watch不會自動關閉,需要手動關閉,unWatch()
  • app.$onapp.$emit,用來定義事件以及觸發事件,在父組件emit子組件的on事件

    vm.$on('test', (a ,b) => {     //vm.$once事件是代表只執行一次
        console.log('test is emit')
    })
    vm.$emit('test', 1, 2)  //可以傳遞給a, b
  • app.$forceUpdateapp.$set(app.obj, 'xx', 1)可以用來渲染當data中的obj並沒🈶定義a時,但在html中我們有寫入了a,原來a是不會被渲染出來的,但是這兩條語句都能使得a渲染出來;起到了類似強制刷新的作用
  • app.$nextTick(function() {}):常用來獲取dom更新後的數據,因爲dom更新數據時異步的,有時候並不能及時獲取到,則可用這麼方法;也可當做promise使用

    Vue.nextTick()
      .then(function () {
        // DOM 更新了
      })

vue的生命週期

  • vue創建到掛載
    beforeCreate () {
       this.$on('test', (a, b) => {
           console.log(a, b, '執行事件')
       })
       this.$emit('test', 1, 2)
        //事件已完成,但dom與數據不能進行操作
    },
    created () {
        console.log(this.msg)
        this.msg = 888
        console.log(this.msg)
        //能操作data中的數據但不能操作dom
    },
    beforeMount () {
        console.log(this.$refs.span, '還是不能操作獲取dom')
        //b不能獲取dom
    },
    //這中間會執行render函數,進行虛擬dom的渲染
    //接下來菜市mounted階段
    mounted () {
        console.log(this.$refs.span, 'mounted能進行dom的獲取與操作')
    }

如果new Vue()時沒有進行el的指定則不會進行beforeMount與mounted,我們可以手動vm.$mount("#app")
如果new Vue()時有template: '<div>888</div>',或者render (h) { h('div', {}, '888')}都會對el:#app的dom進行整體覆蓋

  • vue數據更新
    beforeUpdateupdated當數據發生變化時會執行這兩個鉤子函數,但是一般可以通過watch與Computed`進行監聽數據變化,執行相應操作,
    官方提到:
注意 updated 不會承諾所有的子組件也都一起被重繪。如果你希望等到整個視圖都重繪完畢,可以用 vm.$nextTick 替換掉 updated:
updated: function () {
  this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been re-rendered
  })
}
  • vue卸載

vm.$destroy()螚手動觸發beforeDestroydestroyed;卸載不是消除頁面上的dom,而是解除任何綁定

vue-data

  • data中存放着組件或者vue實例的數據;但是在new Vue()時,data則可以直接
    寫成一個對象,而在組件中時data必須爲一個方法,並且return一個對象,這是爲什麼呢?
    就是必須返回一個獨立的對象,防止組件之間相互影響

    當組件中的data爲一個對象時:因爲組件時可複用的,父組件A中使用了子組件b,並且對b組件中data的值進行了改變,那麼當父組件c再次使用子組件b時也會使用被A改變了的data,這是不合理的,所以在組件中data必須爲一個`function`並且返回一個對象

vue-html

<div v-html="html"></div>

data: {
    html: '<span>888</span>'  //會解析html結構並append進去
}

vue-bind

綁定dom的一些attribute

<div v-bind:class="{active: isActive}"></div>   //v-bind可省略

data: {
    isActive: true
}
//或者
<div :class="classname"></div>
computed: {
    classname () {
        return {
            active: !this.isActive
        }
    }
},

computed,watch,methods淺談區別

  • computed
    本質就是get方法,通常用的就是get方法去獲取數據,該數據不用放在data中;直接放在computed中,通過計算通過get方式獲取數據,默認第一次渲染就能獲取到,而不用等到重新渲染在獲取;(監聽多個data數據來get自己想要數據,不要出現無限循環)通常形式如下

    computed: {
        xx () {
            return 'xxx'
        }
    }
  • watch
    通常用於監聽data中的數據,有兩個參數(new, old)來改變相應的數據,看起來是一對多,與computed的多對一有區別;而且默認第一次渲染不刷新;可以手動handle並且不要改自身監聽的屬性的值

    watch: {
        xxx (new, old) {
            .... 
        }
    }                   //默認第一次渲染不刷新
    watch: {
        xxx: {
            handle (new, old) {
                ...
            }
        },
        immediate: true,
        deep: true      //深度監聽,例如監聽obj時其中的元素髮生變化,並不會監聽到,但是deep爲true時則會生效,這樣性能開銷會大
    } //通過handle第一次渲染刷新

    所以我們可以使用字符串形式,來指定監聽obj中的a

    watch: {
        'xxx.a': {              //監聽xxx對象中的a屬性
            handle (new, old) {
                ...
            }
        },
        immediate: true,
           } //通過handle第一次渲染刷新
  • methods
    computed不同,所有數據變化都會執行methods內的方法

vue原生指令

  • v-text等價於textContent,v-html等價於`innerHTML
  • v-show="bool"就是是否display:none;v-if,v-else-if,v-else是動態增刪dom會消耗性能不推薦使用
  • v-for
    <div id="app">
        <ul>
            <li v-for="(item, index) in arr" :key="item">{{item}}: {{index}}</li>
        </ul>
        <ul>
            <li v-for="(value, key, index) in obj" :key="key">{{key}}: {{value}} - {{index}}</li>
        </ul>
    </div>
    <script>
        Vue.config.devtools = true
        const vm = new Vue({
            el: '#app',
            data: {
                msg: 123,
                obj: {
                    'a': 12,
                    'b': 34
                },
                arr: [1, 2, 3, 4]
            }
        })
    </script>
  • v-on綁定事件,當綁定對象不是vue實例時,實際上是使用addEventListener進行事件添加,若是實例對象則vm.$on()
  • v-model
    <div id="app">
       <!-- <comp-one :value="num" @input="num = arguments[0]"></comp-one> -->
       <comp-one v-model="num"></comp-one>
       <div>{{num}}</div>
    </div>
    <script>
        Vue.config.devtools = true
        
        const component = {
            props: ['value'],
            template: "<input type='text' :value='value' @input='handleInput'/>",
            methods: {
                handleInput(e) {
                    this.$emit('input', e.target.value)
                }
            }
        }
        Vue.component('CompOne', component)
        const vm = new Vue({
            el: '#app',
            components: {
                CompOne: component
            },
            data: {
               num: 1
            }
            
        })
    </script>

vue組件

  • 創建
  • 方法1:全局創建一個組件
    const component = {
        template: '<span>{{text}}</span>',
        data () {
            return {
                text: 123456
            }
        }
    }
    Vue.component('CompOne', component)
    const vm = new Vue({
        el: '#app',
        template: '<comp-one></comp-one>',
    })
  • 組件內部創建組件
    const component = {
        template: '<span>{{text}}</span>',
        data () {
            return {
                text: 123456
            }
        }
    }
    const vm = new Vue({
        el: '#app',
        components: {
            CompOne: component
        },
        data: {
           arr: [1, 2, 3]
        }
    })
  • props屬性
    通過父組件向子組件傳遞數據,但props是單項數據流,不能有子組件進行改變,需要父組件傳遞一個函數,由父組件來決定怎麼改變props的值
    <div id="app">
       <comp-one :prop-one="num" :on-change="handleChange"></comp-one>
       //<comp-one :prop-one="num" @change="handleChange"></comp-one>
    </div>
    <script>
        Vue.config.devtools = true
        
        const component = {
            template: '<span @click="handleClick">{{propOne}}</span>',
            props:{
                propOne: Number,
                onChange: Function //這便可省略用$emit
            },
            methods: {
                handleClick() {
                    this.onChange()
                    //this,$emit('change')
                }
            }

        }
        Vue.component('CompOne', component)
        const vm = new Vue({
            el: '#app',
            components: {
                CompOne: component
            },
            data: {
               num: 1,
            },
            methods: {
                handleChange() {
                    this.num += 1
                }
            }
        })
    </script>
  • extend屬性
    const component = {
        template: '<span @click="handleClick">{{propOne}}{{text}}</span>',
        props:{
            propOne: Number,
            
        },
        data () {
            return {
                text: 888
            }
        },
        mounted () { 
            console.log('component mounted')  //先執行
        },
        methods: {
            handleClick() {
                // this.onChange()
                this.$emit('change')
            }
        }
    
    }
    const compVue = Vue.extend(component) //生成vue子類並擁有組件的屬性
    //也可通過新建一個組件並繼承上個組件屬性(extend:component),並new Vue()
    new compVue({
        el:'#app',
        propsData: {
            propOne: 12356   //用propsData進行賦值
        },
        data: {
        
            text: 666    //後覆蓋繼承組件的data中的值
        },
        mounted () {
            console.log('compVue mounted')  //後執行
        }
    })

vue-插槽

父組件決定放什麼內容,子組件決定放哪

  • 具名插槽
<div id="app">
    <comp-one> 
    <span slot="body">具名插槽</span> 
    <span slot="foot" slot-sc>{{value}}</span>
    <span slot-scope="props">{{props.value}}作用域插槽</span>
    </comp-one>
</div>
<script>
    Vue.config.devtools = true;

    const component = {
    template: `
        <div>
            <div>   
                <slot name='body'></slot>
            </div>
            <div>
                <slot name='foot'></slot>
            </div>
            <div>
                <slot :value="value"></slot>
            </div>
        </div>
        `,
    data () {
        return {
            value: 888
        }
    }
    };
    const vm = new Vue({
    el: "#app",
    components: {
        CompOne: component
    },
    data: {
        value: 666
    }
    });
</script>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章