Vue 分享交流

2021-05-27  本文已影响0人  蔬菜调料包
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>

上一篇 下一篇

猜你喜欢

热点阅读