Vue3 이해하기

30969 단어 webdevvue
<script setup>는 SFC 내에서 Composition API를 사용하기 위한 컴파일 타임 구문 설탕입니다. Vuedocs에서 권장합니다.

3.0 프로젝트에서 Vue2 구성 요소를 계속 사용할 수 있습니다. Vue3 API의 변경 사항과 관련하여 일부 비호환성이 있을 수 있지만 전반적으로 잘 작동해야 합니다. 혼합하지 마십시오!

3.0에서는 변경 사항을 추적하기 위해 반응성 API를 사용하여 변수를 정의할 수 있습니다. API에는 ref() , reactive()가 포함됩니다.

SFC 템플릿




<template>
  <div> hello world: {{ count }} times </div>
  <button @click="count++">click me</button>
</template>

<script setup>
import {ref, computed, watch, onMounted, reactive} from "vue";

// mounted hook
onMounted(() => {console.log("mounted here")});

const count = ref(0);

watch(count, (newVal, oldVal) => {
  alert(newVal)
}) 
</script>
<style></style>


일부 Vue2 사용자에게는 혼란스러울 수 있지만 여기서 발생하는 것은 <script setup>에서 모든 것을 반환해야 한다는 것입니다. 그렇지 않으면 템플릿에서 함수나 변수를 사용할 수 없습니다.

이것은 또한 여기서 this를 더 이상 볼 수 없는 이유 중 하나입니다. 그렇게 하면 onMounted(() => console.log('this:', this)) 인쇄됩니다 this:undefined . 여기에는 더 이상 범위가 없고 모든 것이 반환되므로 this는 더 이상 필요하지 않습니다.

또한 여기서 정의할 필요가 없습니다components. 구성 요소는 자동으로 등록되며 템플릿 내에서 직접 구성 요소를 사용할 수 있습니다.

반응성 API: ref, 반응성



ref() 및 reactive()를 사용하면 반응 상태, 계산 상태 및 감시자를 직접 만들 수 있습니다.
  • ref()를 사용하여 Boolean, Number, String와 같은 기본 데이터 유형을 추적합니다.
  • reactive()를 사용하여 Array와 같은 보다 복잡한 데이터 유형 추적

  • 행동 양식



    2에서는 다음과 같은 방법을 정의합니다.

    methods : {
      add(a, b){
        return a + b;
      }
    


    methods는 다시 작성하기 가장 쉬운 부분이며 기본적으로 3에서 함수가 됩니다.

    function add(a, b){
      return a + b
    }
    


    계산




    data(){
      return {
        count: 0
      }
    },
    computed: {
      newCount(){
        return this.count + 1
      }
    }
    


    3으로 다시 작성하면 다음과 같이 됩니다.

    import {ref, computed} from "vue"; 
    
    const count = ref(1);
    const newCount = computed(() => {
      return count + 1
    })
    


    defineProps 및 defineEmits



    1. defineProps

    <script setup>
      import { defineProps } from "vue";
      const props = defineProps({
        title: String
      })
    const { title } = props;
    </script>
    


    2. 정의 방출

    <script setup>
      import { defineEmits } from 'vue'
      const emit = defineEmits(['change', 'delete'])
    </script>
    


    보다



    다음은 SFC에서 count라는 props 값에 대한 감시를 표시하는 방법입니다.

    watch(() => props.count, (newVal, oldVal) => {
      if (newVal !== oldVal){
        console.log('value changes')
      }
    }
    


    슬롯 및 속성




    <script setup>
      import { useAttrs, useSlots } from 'vue'
    
      const attrs = useAttrs()
      const slots = useSlots()
    </script>
    


    뷰엑스



    2.0에서는 vuex에서 제공하는 mapState , mapMutation 를 직접 사용할 수 있지만 3.0에서는 자체 메서드로 래핑해야 합니다.

    2.0에서:

    <template>
      <div>
        {{ count }}
        {{ countIsOdd }}
        {{ countIsEven }}
      </div>
    </template>
    <script>
    import { mapGetters } from 'vuex'
    export default {
      computed: {
        ...mapGetters(['count', 'countIsOdd', 'countIsEven'])
      }
    }
    </script>
    


    3.0:

    <script setup>
    import { computed } from 'vue'
    import { useStore } from 'vuex'
    
    const store = useStore()
    const count = computed(() => store.getters.count)
    const countIsOdd = computed(() => store.getters.countIsOdd)
    const countIsEven = computed(() => store.getters.countIsEven)
    </script>
    


    중복을 피하기 위해 외부 파일을 정의할 수도 있습니다. 이 경우에는 map-state.js라는 파일을 만듭니다.

    import { computed } from 'vue'
    import { useStore } from 'vuex'
    
    const mapGetters = () => {
      const store = useStore()
      return Object.fromEntries(
        Object.keys(store.getters).map(
          getter => [getter, computed(() => store.getters[getter])]
        )
      )
    }
    
    export { mapGetters }
    


    다음과 같이 사용할 수 있습니다.

    <template>
      <div>
        {{ count }}
        {{ countIsOdd }}
        {{ countIsEven }}
      </div>
    </template>
    <script setup>
    import { mapGetters } from '../map-state'
    const { count, countIsOdd, countIsEven } = mapGetters()
    </script>
    


    물론 map-state.js 파일을 더 확장할 수 있습니다.

    import { computed } from 'vue'
    import { useStore } from 'vuex'
    const mapState = () => {
      const store = useStore()
      return Object.fromEntries(
        Object.keys(store.state).map(
          key => [key, computed(() => store.state[key])]
        )
      )
    }
    const mapGetters = () => {
      const store = useStore()
      return Object.fromEntries(
        Object.keys(store.getters).map(
          getter => [getter, computed(() => store.getters[getter])]
        )
      )
    }
    const mapMutations = () => {
      const store = useStore()
      return Object.fromEntries(
        Object.keys(store._mutations).map(
          mutation => [mutation, value => store.commit(mutation, value)]
        )
      )
    }
    const mapActions = () => {
      const store = useStore()
      return Object.fromEntries(
        Object.keys(store._actions).map(
          action => [action, value => store.dispatch(action, value)]
        )
      )
    }
    export { mapState, mapGetters, mapMutations, mapActions }
    


    글로벌 구성



    예를 들어 js에서 $message 또는 $dialog를 사용하여 플러그인을 사용하거나 전역 구성 요소를 중단하려고 할 때도 차이가 발생합니다.

    Amplitude(js sdk를 사용한 데이터 추적 도구) 플러그인 생성:

    /* Amplitude.js */
    import amplitude from 'amplitude-js';
    
    export default {
        install: (Vue, { apiKey, userId }) => {
            amplitude.getInstance().init(apiKey, userId, {
                includeUtm: true,
                includeReferrer: true,
                deviceIdFromUrlParam: true
            });
    
    // in 2.0 it was Vue.prototype.$amplitude = amplitude;
    Vue.config.globalProperties.$amplitude = amplitude;
        }
    };
    
    

    main.js에서 사용합니다.

    /* main.js */
    import AmplitudePlugin from './plugins/amplitude';
    const app = createApp(App);
    // in 2.0 it was Vue.use(......)
    app.use(AmplitudePlugin, {
        apiKey: process.env.VUE_APP_AMPLITUDE_API_KEY,
        userId: userInfo?.id
    });
    


    메시지 구성 요소의 경우 하나를 생성하고 전역으로 등록한 후 예를 들면 다음과 같습니다.

    // import all local fundamental components you build for your project, things like message, button, drawer, etc --> not business components
    import * as components from './components';
    
    export default {
        install: app => {
            Object.keys(components).forEach(key => {
                app.component(key, components[key]);
                if (key === 'DPMessage') {
    
    // register your $message method globally
            app.config.globalProperties.$message = components[key];
                }
            });
        }
    };
    


    물론 당신은 그것을 사용해야합니다:

    <template>
      <div><button @click="showSuccessMessage">click me to show success message</button>
    </template>
    <script setup>
    const { proxy } = getCurrentInstance();
    
    const showErrorMessage = () => {
    //better to have a '?' here, just in case Vue does not find the method
        proxy?.$message({ type: 'error', text: 'hey this is sam test' });
    };
    </script>
    

    axios와 같은 다른 유용한 플러그인은 전역적으로 사용할 수 있는지 여부는 사용자에 따라 다릅니다.

    좋은 웹페이지 즐겨찾기