vue3 + ts

En vue3.2, solo necesitamos agregar la configuración en la etiqueta del script. Se puede hacer. Los componentes solo deben introducirse sin registro, los atributos y los métodos se pueden usar en la plantilla sin retorno, y no es necesario escribir funciones de configuración o exportar valores predeterminados. Incluso las instrucciones personalizadas se pueden obtener automáticamente en nuestra plantilla. .

1. Sintaxis de la plantilla

1. Usar expresiones de JavaScript

Solo vinculamos algunos nombres de propiedades simples en la plantilla. Pero Vue en realidad admite expresiones completas de JavaScript en todos los enlaces de datos:

{
   
   { number + 1 }}

{
   
   { ok ? 'YES' : 'NO' }}

{
   
   { message.split('').reverse().join('') }}

<div :id="`list-${id}`"></div>

2. Llame a la función

Un método expuesto por un componente se puede utilizar en una expresión vinculante:

<span :title="toTitleDate(date)">
  {
   
   { formatDate(date) }}
</span>

3. ref Consigue elementos

<template>
  <div id="haha" ref="haha"></div>
</template>

hay que  ref especificar el tipo HTMLElement

setup() {
  let haha = ref<HTMLElement|null>(null)
  console.log(haha)
    
  return {
    haha,
  }
},
haha.style.fontSize = '20px'

4.reactive 

{ {obj.name}} Puedes usarlo directamente en la plantilla. 

Modificar modificación directa obj[name] = ‘xxx’

La diferencia entre ref y reactivo:

  • ref: se utiliza para vincular datos receptivos a tipos de datos básicos. Al acceder, debe pasar la forma de .value , y tamplate se analizará automáticamente, y .value no es necesario

  • reactivo: se utiliza para vincular datos receptivos a tipos de datos complejos, simplemente acceda a ellos directamente

<template>
  <div>
    <p>{
   
   {title}}</p>
    <h4>{
   
   {userInfo}}</h4>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from "vue";
type Person = {
    name: string;
    age: number;
    gender: string;
};
const title = ref<string>("彼时彼刻,恰如此时此刻");
const userInfo = reactive<Person>({
  name: '树哥',
  age: 18
})
</script>

5.toRefs

setup() {
  const user = reactive({
    name: '小浪',
    age: 21,
  })

  let userObj = toRefs(user)

  return {
    ...userObj,
  }
}

6. ¿Cuál es la diferencia entre ref y reactivo?

En términos de función, ¡tanto ref como reactivo pueden realizar datos receptivos!

A nivel gramatical, los dos difieren. Los datos de respuesta definidos por ref deben cambiarse a [datos].valor; los datos definidos en reactivos deben cambiarse a [datos].[propiedad].

const actTitle: Ref<string> = ref('活动名称');

const actData = reactive({
    list: [],
    total: 0,
    curentPage: 1,
    pageSize: 10
});

actTitle.value = '活动名称2';

actData.total = 100;

Pero a nivel de aplicación, todavía hay diferencias.En términos generales: para un solo tipo común de datos, usamos ref para definir la capacidad de respuesta. En la escena del formulario, la escena que describe el objeto clave:valor de un formulario usa reactivo ; en algunos escenarios, un conjunto de datos de un determinado módulo generalmente usa el método reactivo para definir los datos.

Entonces, ¿los objetos tienen que definirse usando reactivos? De hecho, no lo es, se puede hacer, de acuerdo con sus propios escenarios comerciales, problemas específicos y análisis específicos. ref enfatiza el cambio de un valor de datos y reactivo enfatiza el cambio de un determinado atributo del objeto definido.

7. Función periódica    en Montado

import { defineComponent, ref, onMounted } from 'vue';
export default defineComponent({
    name: 'Gift',
    setup() {
        const counter = ref(0);
        onMounted(() => {
            // 处理业务,一般进行数据请求
        })
        return {
            counter
        }
    }
})

8. uso de la tienda

importar {  useStore  } desde "vuex";

 const store = useStore();
 const storeData =  computed (() => store); // Coopere con computed para obtener el valor de store.

import { useStore } from "vuex";
import { defineComponent, ref, computed } from 'vue';
export default defineComponent({
    name: 'Gift',
    setup() {
        const counter = ref(0);
        const store = useStore();
        const storeData = computed(() => store); // 配合computed,获取store的值。
        return {
            counter,
            storeData
        }
    }
})

9. El uso del enrutador

        importar {  useRouter  } desde "vue-router";

        const enrutador = usar enrutador ();
        const onClick = () => {  router.push ({ nombre: "AddGift" });         }
           

import { useStore } from "vuex";
import { useRouter } from "vue-router";
import { defineComponent, ref, computed } from 'vue';
export default defineComponent({
    name: 'Gift',
    setup() {
        const counter = ref(0);
        const router = useRouter();
        const onClick = () => {
            router.push({ name: "AddGift" });
        }
        return {
            counter,
            onClick
        }
    }
})

10. Separación de preocupaciones

La separación de inquietudes debe dividirse en dos significados: el primer significado es que la configuración de Vue3 en sí misma reúne los datos relacionados y la lógica de procesamiento. Este es un tipo de agregación de inquietudes, que es más conveniente para nosotros para ver el código comercial.

La segunda capa significa que cuando la configuración se vuelve más grande, podemos extraer una pieza de negocio relacionada dentro de la configuración para lograr la separación de preocupaciones en la segunda capa.

import { useStore } from "vuex";
import { useRouter } from "vue-router";
import { defineComponent, ref, computed } from 'vue';
import useMerchantList from './merchant.js';
export default defineComponent({
    name: 'Gift',
    setup() {
        const counter = ref(0);
        const router = useRouter();
        const onClick = () => {
            router.push({ name: "AddGift" });
        }
        // 在该示例中,我们把获取商家列表的相关业务分离出去。也就是下面的merchant.ts
        const {merchantList} = useMerchantList();
        return {
            counter,
            onClick,
            merchantList
        }
    }
})

comerciante.ts    

import { getMerchantlist } from "@/api/rights/gift";
import { ref, onMounted } from "vue";

export default function useMerchantList(): Record<string, any> {
  const merchantList = ref([]);
  const fetchMerchantList = async () => {
    let res = await getMerchantlist({});
    merchantList.value = res.data.child;
  };

  onMounted(fetchMerchantList);

  return {
    merchantList
  };
}

11.interfaz

Al usar TS para el desarrollo comercial, una idea central es centrarse primero en la estructura de datos y luego desarrollar páginas basadas en la estructura de datos. El modelo de desarrollo front-end anterior consistía en escribir primero la página y luego centrarse en los datos.

Por ejemplo, para escribir una página de lista de regalos, es posible que necesitemos definir dichas interfaces. En general, debemos prestar atención a: la interfaz de los datos de la página, el tipo de datos devuelto por la interfaz, el tipo de parámetro de entrada de la interfaz, etc.

// 礼品创建、编辑、列表中的每一项,都会是这个数据类型。
interface IGiftItem {
  id: string | number;
  name: string;
  desc: string;
  [key: string]: any;
}

// 全局相应的类型定义
// 而且一般来说,我们不确认,接口返回的类型到底是什么(可能是null、可能是对象、也可能是数组),所以使用范型来定义interface
interface IRes<T> {
    code: number;
    msg: string;
    data: T
}
// 接口返回数据类型定义

interface IGiftInfo {
    list: Array<IGiftItem>;
    pageNum: number;
    pageSize: number;
    total: number;
}

En una solicitud de interfaz común, generalmente usamos TS para definir una solicitud de datos, el tipo de solicitud de la solicitud de datos y el tipo res de la solicitud de datos.

export const getGiftlist = (
  params: Record<string, any>
): Promise<IRes<IGiftInfo>> => {
  return Http.get("/apis/gift/list", params);
};

12. Admite múltiples modelos v

//父组件
<template>
  <child v-model="name" v-model:email="email" />
  <p>姓名:{
   
   { name }}</p>
  <p>邮箱:{
   
   { email }}</p>
</template>

<script lang="ts" setup>
import child from './child.vue'
import { ref } from 'vue'

const name = ref<string>('张三')
const email = ref<string>('[email protected]')
</script>
// 子组件
<template>
  <button @click="updateName">更新name</button>
  <button @click="updateEmail">更新email</button>
</template>

<script lang="ts" setup>
// 定义emit
const emits = defineEmits<{
  (e: 'update:modelValue', value: string): void
  (e: 'update:email', value: string): void
}>()

const updateName = () => {
  emits('update:modelValue', '李四')
}

const updateEmail = () => {
  emits('update:email', '[email protected]')
}
</script>

Si v-modelno se usa ningún parámetro, su valor predeterminado modelValuees el primero de arriba v-model. Tenga en cuenta que ya no se usa como Vue2 en este momento $emit('input'), pero se usa de manera uniforme update:xxx.

13. reloj   

reloj(datos,()=>{},{})

  • Parámetro uno, los datos monitoreados

  • Parámetro dos, la función de devolución de llamada se activa cuando cambian los datos (newVal, oldVal)

  • El parámetro tres, el elemento de configuración de opciones, es un objeto

  • 1. Escuche los datos de respuesta definidos por ref.

<script setup lang="ts">
import { ref, watch } from "vue";

const str = ref('彼时彼刻')

//3s后改变str的值
setTimeout(() => { str.value = '恰如此时此刻' }, 3000)

watch(str, (newV, oldV) => {
  console.log(newV, oldV) //恰如此时此刻 彼时彼刻
})

</script>
  • 2. Escuche múltiples referencias

En este momento, el método de escritura se convierte en la forma de una matriz

<script setup lang="ts">
import { ref, watch } from "vue";

let name = ref('树哥')
let age = ref(18)

//3s后改变值
setTimeout(() => {
  name.value = '我叫树哥'
  age.value = 19
}, 3000)

watch([name, age], (newV, oldV) => {
  console.log(newV, oldV) // ['我叫树哥', 19]  ['树哥', 18]
})

</script>
  • 3. Escuche el objeto receptivo definido por Reactive

<script setup lang="ts">
import { reactive, watch } from "vue";

let info = reactive({
  name: '树哥',
  age: 18
})

//3s后改变值
setTimeout(() => {
  info.age = 19
}, 3000)

watch(info, (newV, oldV) => {
  console.log(newV, oldV) 
})

</script>
  • 4. Escuche reactivo para definir un solo atributo de un objeto receptivo

    <script setup lang="ts">
    import { reactive, watch } from "vue";
    
    let info = reactive({
      name: '树哥',
      age: 18
    })
    
    //3s后改变值
    setTimeout(() => {
      info.age = 19
    }, 3000)
    
    
    watch(()=>info.age, (newV, oldV) => {
      console.log(newV, oldV) // 19 18
    }
    
    </script>

  • deja de escuchar

Cuando se llama a watchEffect en la función setup() de un componente o en un enlace de ciclo de vida, el oyente se vincula al ciclo de vida del componente y se detiene automáticamente cuando el componente se desmonta.

Pero creamos un oyente de forma asíncrona. En este momento, el oyente no está vinculado al componente actual, por lo que incluso si el componente se destruye, el oyente aún existe.

En este momento podemos llamar explícitamente para dejar de escuchar

<script setup lang="ts">
import { watchEffect } from 'vue'
// 它会自动停止
watchEffect(() => {})
// ...这个则不会!
setTimeout(() => {
  watchEffect(() => {})
}, 100)

const stop = watchEffect(() => {
  /* ... */
})

// 显式调用
stop()
</script>

(igual abajo)

Monitoreo de diferentes tipos de datos

  Seguimiento de tipos de datos básicos:

const nombre = ref<cadena>('Zhang San')


reloj (nombre, ( nuevoValor, antiguoValor ) => {   console.log('observar===', nuevoValor, antiguoValor) })

Supervisión de tipos de datos complejos:

interface  UserInfo  {   nombre: string   edad: número } const  userInfo  = reactivo< UserInfo >({   nombre: 'Zhang San',   edad: 10 }) // monitorea todo el objeto watch( userInfo , (newValue, oldValue)  =>  {   consola .log('ver userInfo', newValue, oldValue) }) // monitorear una propiedad watch( () => userInfo.name , (newValue, oldValue)  =>  {   console.log('ver nombre', newValue, oldValue) })
















Soporte para escuchar múltiples fuentes

const name = ref<string>('Zhang San')
const userInfo = reactive({   age: 18 }) // Supervisar el atributo de edad de name y userInfo al mismo tiempo watch([name, () => userInfo.age ] ([ nuevoNombre, nuevaEdad], [antiguoNombre, antiguaEdad]) => {   //  })






14. watchy watchEffectdiferencia:

1. Watch es ejecución diferida, es decir, solo se ejecutará cuando cambie el valor monitoreado, pero watchEffect es diferente, y watchEffect se ejecutará cada vez que se cargue el código (ignore la configuración del tercer parámetro de watch, si no modificar el elemento de configuración, también se puede implementar inmediatamente.

2. Watch necesita pasar el objeto monitoreado, watchEffect no necesita

3. Watch solo puede monitorear datos receptivos: atributos definidos por ref y objetos definidos por reactivo.Si monitorea directamente los atributos en el objeto definido por reactivo, no está permitido a menos que use una función para convertirlo.

4. WatchEffect no funciona si monitorea el objeto definido por reactivo, solo puede monitorear las propiedades en el objeto.

15. calculado

<template>
  <div>
    <p>{
   
   {title}}</p>
    <h4>{
   
   {userInfo}}</h4>
    <h1>{
   
   {add}}</h1>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive,computed } from "vue";
const count = ref(0)

// 推导得到的类型:ComputedRef<number>
const add = computed(() => count.value +1)

</script>

おすすめ

転載: blog.csdn.net/admin12345671/article/details/129640919