1. Vue + TypeScript 项目的创建
# 1.安装node.js https://nodejs.org/zh-cn/
# 2.安装vue-cli https://cli.vuejs.org/zh/
npm install -g @vue/cli
# 3.创建项目
vue create hello-world
# 或者
vue ui
# 更多自定义配置详见 https://cli.vuejs.org/zh/config/
# Vue文档 https://cn.vuejs.org/v2/guide/
image.png
2. Vue的一些优化
// 1. 长列表性能优化 vue-virtual-scroller组件
export default {
data: () => ({
users: []
}),
async created() {
const users = await axios.get("/api/users");
this.users = Object.freeze(users);
},
methods:{
// 改变值不会触发视图响应
this.users[0] = newValue
// 改变引用依然会触发视图响应
this.users = newArray
}
// 2. 动态组件
<component v-bind:is="currentTabComponent"></component>
// 使用<keep-alive> 标签缓存 避免反复重渲染导致的性能问题
// 注意这个 <keep-alive> 要求被切换到的组件都有自己的名字 name 属性
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
// 3. 异步组件
new Vue({
// ...
components: {
'my-component': () => import('./my-async-component')
}
})
// 4. v-once 只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过
<ul>
<li v-for="i in list" v-once>{{i}}</li>
</ul>
// 5. 事件修饰符
@click.stop:阻止冒泡
@click.prevent:阻止默认行为
@click.once: 只触发一次
// 6. v-on监听原生事件
// v-on 只会监听自定义事件 (组件用 $emit 触发的事件)。如果要监听根元素的原生事件,可以使用 .native 修饰符
<my-component @click.native="doSomething"></my-component>
// 7. v-for v-if 不能一起使用
// 当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级。
// 8. this.$once
mounted () {
window.addEventListener('resize', this.resizeHandler);
},
beforeDestroy () {
window.removeEventListener('resize', this.resizeHandler);
}
————————————————
window.addEventListener('resize', this.resizeHandler);
this.$once("hook:beforeDestroy", () => {
window.removeEventListener('resize', this.resizeHandler);
})
————————————————
// 9. ts vue 中的一些声明周期注册 beforeDestroy beforeRouteEnter beforeRouteLeave beforeRouteUpdate
import Component from 'vue-class-component';
// import { Component } from 'vue-property-decorator';
Component.registerHooks(['beforeDestroy']);
// 10 this.$set
// 当你利用索引直接设置一个数组项时或你修改数组的长度时,由于 Object.defineprototype()方法限制,数据不响应式更新,或者出现input使用v-model 不能输入
this.$set(arr,index,item)
this.$set(obj,key,value)
// 11 ::v-deep深度选择 与scoped 局部作用
// 12 vue-cli3 别名
// vue.config.js中
const path = require('path'); // 引入path模块
function resolve(dir) {
return path.join(__dirname,dir) //path.join(_dirname)设置绝对路径
}
module.exports = {
chainWebpack: config => {
config.resolve.alias
//第一个参数:别名 第二个参数:路径
.set('components', resolve('src/components'))
.set('assets', resolve('src/assets'));
}
};
// 12 vue浏览器调试工具 vue-devtools
3. 自定义组件
// 子组件
<template>
<div class="child">
子组件:<input type="text" :value="inputValue" @input="inputHandle($event)"/>
<span>{{title}}</span>
<button @click="changeTitle"> change title</button>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import { Component, Model, Prop } from 'vue-property-decorator';
@Component({ name: 'Chlid ' }) //! 默认为类名
export default class Chlid extends Vue {
@Prop({ required: false, type: String, default: '' })
title!: boolean;
// Object/Array 类型需要使用函数返回
@Prop({ required: false, type: Array, default: () => [] })
data!: any[];
// 1 实现v-model
@Model('change', { type: String })
readonly inputValue!: string;
// 2 实现v-model
inputHandle(event) {
this.$emit('change', event.target.value);
}
// 调用子组件方法
getData(){
console.log('child getData ---')
}
// async 修饰符
changeTitle(){
this.$emit('update:title', 'newTitle')
}
}
</script>
// 父组件
<template>
<div class="Model">
<Chlid v-model="val" value="some value" ref='child' :title.sync="title"/>
<div>父组件 value: {{val}}</div>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import Chlid from './Chlid.vue';
@Component({ components: { Chlid } })
export default class Parent extends Vue {
public val = 'hello';
public title = 'vue demo'
callChildFn(){
this.$refs?.child?.getData()
}
}
</script>
网友评论