Skip to content

0、vue3中使用过的一些插件

1、vue3 中 watch 详解

javascript
// watch 监控props中的值

/*
  immediate 默认值为 false,则第一次不会监听 watch 的执行
  immediate 设置为 true,则第一次也会监听 watch 的执行
  watch 位于子组件中时,子组件通过 v-if 和 v-show 控制显示时
*/
watch(
  () => props.changeName,
  (newValue, oldValue) => {
    console.log(newValue, oldValue, "watch-changeName");
  },
  {
    immediate: true,
  }
);

// watch 监控route路由中的值
watch(
  () => route.path,
  (newValue, oldValue) => {
    console.log(newValue, oldValue, route, "watch-path");
  },
  {
    immediate: true,
  }
);

// watch 监控vuex store仓库中的值
watch(
  () => store.state.headerMenu,
  (newValue, oldValue) => {
    console.log(newValue, oldValue, "watch-store");
  },
  {
    immediate: true,
  }
);

// watch 监控ref定义的值
const state = ref(0)

watch(state, (newValue, oldValue) => {
    console.log(newValue, oldValue, "watch-ref");
  },
  {
    immediate: true,
  }
);

// watch 监控reactive定义的值
// watch 监控ref定义的值
const state = reactive({count: 0})

watch(() => state.count, (newValue, oldValue) => {
    console.log(newValue, oldValue, "watch-reactive");
  },
  {
    immediate: true,
  }
);

2、vue 3 全局函数或者全局变量注入

javascript
// 全局函数注入
const app = createApp(App);
app.config.globalProperties.$filters = {
  currencyUSD(value: String) {
    console.log("currencyUSD" + value);
    return "$" + value;
  },
};

// 在组件中如何调用
import { getCurrentInstance } from "vue";
const { ctx, proxy } = getCurrentInstance;
// 开发环境中ctx和proxy都可以调用到函数
// 部署后发现ctx调用的函数为undefined,
/// 所以此处暂时用proxy代理,尤大支出少用proxy
ctx.$filters.currencyUSD("sssss");
proxy.$filters.currencyUSD("sssss");

3、vite 创建 vue 项目

  • 我平常习惯用 yarn,不过用 yarn 创建项目的时候报错,用 npm 是没问题的
  • yarn create @vitejs/app dvs-platform --template vue
  • npm init @vitejs/app dvs-platform -- --template vue

4、vue2 中的 this.$refs.form.validate 表单验证 ref 使用

记住formDom要在setup最后 return出来,要不然一直有问题

javascript
   <template>
      <el-form :model="formConfig.formData" label-width="120px" ref="formDom">
      </el-form>
      <el-button
        size="large"
        type="primary"
        style="margin-left: 120px; height: 50px"
        @click="submitForm"
        native-type="submit"
      >
        提交
      </el-button>
    </template>

      setup(){
        let formDom = ref(null);
        const submitForm = () => {
          formDom.value.validate((valid) => {
            if (valid) {
              console.log(valid, "this.valid");
            } else {
              console.log(valid, "验证失败");
            }
            return false;
          });
        };

        return {
          formDom
        }
      }

5、子组件中如何调用父组件中定义的函数通过 context.emit

javascript

  // 父组件中的代码
  <template>
    <HelloWorld @hello="sayHello" />
</template>
<script>
  export default defineComponent({
        setup(){
          const sayHello (params) {
            console.log(params)
          }
          return {sayHello}
        }
  })
</script>


// 子组件中的代码
<template>
  <div @click="say">你好</div>
</template>
<script>
  import { defineComponent } from 'vue'
  export default defineComponent({
  setup (props, context) {
    const say () {
      context.emit("hello", "hello 我时子组件")  // 调用父组件方法
    }
    return {
      say
    }
  }
})
</script>

6、vue2 中.sync 与子组件数据双向通信,用 vue3 中的 v-model 替换

```javascript

    // 父组件中引用子组件的传值通过v-model
    <vue-json-editor
      v-model:value="formConfig"
      :options="options"
      :plus="false"
      height="800px"
    />

    // 在子组件中想改变父组件中的value时
    setup(props,context) {
      context.emit('update:value', '子组件的变量值')
    }
```

7、事件总线的使用(npm install emittery -S)

```javascript
  // 在main.ts文件中引入
  const Emittery = require('emittery');

  // 注入全局函数中
  app = createApp(App);
  const emitter = new Emittery();
  app.config.globalProperties.$emmitter = emitter

  // 定义事件
  const instance = getCurrentInstance() // 必须在setup或者生命周期函数中调用,然后使用instance
  const mitt = instance.appContext.config.globalProperties.$emmitter
  mitt.on('foo', (value) => {
    console.log('foo', value )
    getList()
  });

  // 监听调用事件
  const instance = getCurrentInstance()
  const mitt = instance.appContext.config.globalProperties.$emmitter
  mitt.emit('foo', (value) => {
    console.log('foo', value)
  });
```

defineExpose 将子组件方法或属性,暴露给父组件调用

javascript
   // 子组件代码 child.vue
   const isFlag = ref (false)
   const testFunction = () => {
     console.log('调用子组件的方法')
   }

   defineExpose({
     isFlag,
     testFunction
   })

   // 在父组件中调用
   <child ref="refChild">
   import child from './child.vue'
   import  { ref, onMounted } from 'vue'
   let refChild = ref(null)
   onMounted(() => {
     console.log(refChild.value, 'refChild')

     //达到调用子组件的属性和方法
     const { isFlag, testFunction} = refChild.value
   })

vue3 keepalive 缓存

```javascript
  https://juejin.cn/post/7018508057793691656
  页面第一次进入的时候,钩子触发顺序时created->mounted->activated,所以别在mounted和activated方法中写相同的逻辑代码

```