VUE基础知识点

    技术2022-07-10  165

    学习vue,顺手记录下的基础点笔记。

    一定要有随手保存代码的习惯,除非你的开发工具设置了自动保存。

    1. 组件使用

    组件定义时名称为驼峰,例如HelloWorld,但在html里使用时用小写字母横杆连接,hello-world

    自定义的组件在single-file components(.vue文件)/string template/jsx中使用时采用自闭合单标签形式,但是在html中使用时,要采用双标签,自闭合的单标签在默认情况下根本不管用。例如:<app/><hello-world/>这种写法浏览器只会渲染<app>组件,而会把<hello-world/>认为是<app></app>内容以至于被<app>的template覆盖了

    2. 关于scoped
    <style scoped></style>style标签加上scoped属性,是指这里包含的css样式只会应用在包含它的组件的元素上同一个组件里,既可以有加scoped属性的style标签,也可以有不加scoped属性的style标签,它们作用域不同,前者是组件内,后者是全局范围生效(一般不这么用,全局的还是写在全局的css文件里)加了scoped的样式不会影响子组件里的元素,只会影响子组件的根节点如果想要父组件的加了scoped的样式影响到子组件,可以用>>> combinator,但有些预处理器可能不认>>> combinator,这种情况下可以用/deep/或者::v-deep代替,这俩是>>>的别名,效果完全一样。例如.a >>> .b { },可以影响子组件中的class名是b的元素的样式当加了scoped的样式里有属性选择器时,浏览器渲染样式会几倍的慢,建议使用类选择器或id选择器,就跟不加scoped的性能差不多了
    3. ref属性

    用于快速定位到dom结构。

    html使用<div ref='test'></div>

    js使用this.$refs.test => div这个元素对象

    4. @import ‘./*.css’
    5. ‘./a.css’和’…/a.css’区别
    6. assets文件夹和static文件夹
    assets文件夹,主要放项目里用到的图片等静态资源static文件夹,主要放第三方的静态资源,比如字体
    7. v-if例子和v-show例子
    <!-- flag变量值为1时显示aa,2时显示bb,其他情况显示cc --> <p v-if="flag === 1">aa</p> <p v-else-if="flag === 2">bb</p> <p v-else>cc</p> <!-- flag为1时显示aa --> <span v-show="flag === 1">aa</span>
    8. v-show和v-if区别

    v-if条件不符合时不会渲染对应元素

    v-show条件不符合时会渲染对应元素,但样式设为display:none;

    所以在选择使用哪个时,看使用场景,如果值不会频繁变化,就用v-if,但如果值会频繁变化时,使用v-show性能更好一些,因为v-if的元素切换时要渲染DOM元素这个过程是需要大量计算的,所以出于性能考虑我们一般是不赞成频繁进行DOM元素渲染的。

    9. v-for遍历数组和遍历对象例子
    <!-- 循环arr数组,每条数据显示顺序号和name属性 --> <ul> <li v-for="(item, index) in arr" :key="item.id"> <span>{{index + 1}}-{{item.name}}</span> </li> </ul> <!-- 循环obj对象,每条数据显示顺序号-key-value --> <ul> <li v-for="(value, key, idx) in obj" :key="key"> {{idx + 1}}-{{key}}-{{value}} </li> </ul>
    10. v-for跟v-if不建议一起用,有需要这样用的场景,可以使用computed属性,v-for绑定对原始数组进行filter之后返回的数组
    11. 动态属性,比如<span v-bind:id='myId'>ss</span> myId是data里定义的变量,简写就是<span :id="myId">ss</span>。

    动态class的两种写法,对象和数组,当然也可以是单个变量

    <span :class="{class1: hasClass1, class2: hasClass2}">ss</span>其中hasClass1和hasClass2是布尔型变量

    <span :class=[class1, class2]>ss</span>其中class1和class2是字符串型变量,class名

    动态style绑定的是对象,其中样式名称用驼峰写法例如font-size写成fontSize

    12. v-html有xss风险,会覆盖标签内容和子组件
    13. vue事件中不用传参数时可以直接获取到event,有参数时需要把event参数传到事件处理函数中;vue的event参数是原生的,event.target是引起触发事件的元素,event.currentTarget是事件处理函数挂载的元素
    14. `带格式的字符串`,这个符号包起来的字符串可以有格式,不需要写\n之类的换行
    15. computed有缓存,data不变就不会重新计算;watch默认是浅度监听,就是只监听表层变化,除非设置deep:true(配合handler)才会递归遍历监听对象各属性进行watch;watch如果监听引用类型是拿不到oldVal的
    16. computed使用
    export default { data () { return { num: 1, // 值类型 obj: { // 引用类型 pro: '哈哈' } } }, computed: { com1() { // 跟get方式一样 return this.num + 1 }, com2: { // get set方式 get() { return this.num + 1 }, set(val) { this.num = val - 1 } } }, watch: { num(oldVal, val) { console.log('watch', oldVal, val); }, obj: { handler(oldVal, val) { console.log('deep watch', oldVal, val) }, deep: true // 深度监听 } } } // 使用时 <span>{{num}}</span> <span>{{com1}}</span> <span>{{com2}}</span> <input v-model="com2" />
    17. 事件修饰符
    <!-- stop阻止事件继续传播 --> <div v-on:click.stop="func"></div> <!-- prevent阻止事件默认行为,例如submit事件的重载页面,a标签点击跳转等 --> <form v-on:submit.prevent="func"></form> <!-- 修饰符可以串联 --> <a v-on:click.stop.prevent="func"></a> <!-- 可以只有修饰符不加事件处理 --> <form v-on:submit.prevent></form> <!-- capture事件捕获期的事件处理函数 --> <div v-on:click.capture="func">...</div> <!-- self只有event.target是当前元素时触发的处理函数 --> <div v-on:click.self="func">...</div>
    18. 按键修饰符
    .ctrl .alt .shift .meta .enter .tab .delete .esc .space .up .down .left .right <!-- 只要按下指定键,就算有其他按键一起按下也会触发 --> <button v-on:keyup.ctrl="func">xx</button> <!-- exact,只按下指定键时触发 --> <button v-on:keyup.ctrl.exact="func">xx</button> <!-- 没有任何系统修饰符被按下的时候才触发 --> <button v-on:keyup.exact="func">xx</button>
    19. 表单修饰符
    <!-- trim去掉首尾的空格 --> <input v-model.trim="myInput" /> <!-- lazy防抖,从input触发变成change触发,离开输入框才进行输入的内容跟数据绑定的内容进行同步,因为v-model默认是每次值变化都会同步数据,所以可能造成画面抖动 --> <input v-model.lazy="myInput" /> <!-- number把输入的内容转换成数字,因为默认输入的都会变成字符串,加上number修饰符就可以把输入的数字转化成数值型,对非数字内容不起作用 --> <input v-model.number="myInput" />
    20. 页面回到顶部
    <div id="headDiv"></div> // 调用headDiv.scrollIntoView()使顶部div可见达到目的
    21. slot 插槽

    父组件往子组件里插入内容

    <!-- 常规使用 --> <!-- 子组件 --> <template> <p> <slot> 默认显示,当父组件没有往子组件插入内容 </slot> </p> </template> <!-- 父组件 --> <myComponent> {{parentData.title}} </myComponent> <!-- 如果父组件想插入子组件的值 --> <!-- 子组件 --> <template> <p> <slot :childData="childDa"> 默认显示,当父组件没有往子组件插入内容 </slot> </p> </template> <!-- 父组件 --> <myComponent> <template v-slot="props"> {{props.childData.property}} </template> </myComponent> <!-- 具名插槽:子组件好几个slot设置name --> <!-- 子组件 --> <template> <p> <slot name="slot1"></slot> </p> <p> <slot></slot> </p> <p> <slot name="slot2"></slot> </p> </template> <!-- 父组件 --> <myComponent> <template v-slot:slot1></template> <template></template> <template #slot2></template> </myComponent>
    22. 动态组件
    <component :is="namename" />
    23. $nextTick

    页面数据更改后立刻获取DOM元素,不会获取到最新的,因为还没有渲染,这时想要得到最新的DOM,可以把访问DOM的代码放到 n e x t T i c k 里 。 nextTick里。 nextTicknextTick是基于Promise.resolve().then()执行的回调,所以会比setTimeout的回调执行的早一些,效率高。

    export default { data() { return { list: ['1', '2'] } } methods: { test() { this.list.push('3') this.list.push('4') // 访问DOM元素放到$nextTick里 this.$nextTick(() => { console.log(this.$refs.listDom.childNodes.length) }) } } } // 不管list里push几个,会将data修改做整合,都只会渲染一次,异步渲染,$nextTick会在DOM渲染完之后回调。 // 上面代码如果不把访问DOM放到$nextTick里,它会打印出来2也就是push前的长度而不是我们需要的4.
    24. 异步组件
    // 如果直接在这import就不是异步的,加载这个页面时就会加载组件 // import asyncComponent from './asyncComponent' export default { components: { asyncComponent: () => import('../asyncComponent') } }
    25. keep-alive

    场景:缓存组件,tab频繁切换不需要重复渲染的情况,性能优化方式之一

    当然,如果组件比较简单,也可以用v-show通过原生css来控制

    使用方式:

    <keep-alive> <myComponent1 v-if="flag==1"></myComponent1> <myComponent2 v-if="flag==2"></myComponent2> <myComponent3 v-if="flag==3"></myComponent3> </keep-alive>
    26. 自定义v-model
    27. vue生命周期

    单个组件:

    beforeCreate->created(实例初始化完毕)->beforeMount(生成虚拟DOM)->mounted(DOM渲染完毕)->beforeUpdate->updated->beforeDestroy(要解除自定义事件以及clearTimeout等)->destroyed

    实例初始化各项目顺序:props -> methods ->data -> computed -> watch

    父子组件:

    父组件beforeCreate->父组件created->父组件beforeMount->子组件beforeCreate->子组件created->子组件beforeMount->子组件mounted->父组件mounted->父组件beforeUpdate->子组件beforeUpdate->子组件updated->父组件updated->父组件beforeDestroy->子组件beforedestroy->子组件destroyed->父组件destroyed

    总结:初始化实例是父组件先初始化完毕,渲染是子组件先渲染完毕,更新是父先开始,子先更新完毕,销毁是父先开始销毁,子组件先销毁完毕。

    28. 组件间通讯

    父传子:props

    子传父:this.$emit(‘事件名’,参数)

    其他级别组件:event.$on(‘自定义事件名’,处理函数)

    触发时使用event.$emit(‘自定义事件名’,参数)

    组件销毁时移除自定义事件防止内存溢出 event.$off(‘自定义事件名’,处理函数)

    29. mixin

    mixin慎用,可能造成代码混乱,不易理解维护。

    Processed: 0.018, SQL: 9