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>
    原文作者:Infinity
    原文地址: https://segmentfault.com/a/1190000018033885
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞