Vue3 notes

1.View3

Attrs and props

Attrs can contain all methods and string type parameters passed by the parent

Props can only be parameters and need to be declared above. Once props are declared, arrts will not be in reality. This parameter 1.
props must be declared first to get a value, attrs does not need to be declared first.
2. The declared attributes of props are not in attrs It will appear again
3. props does not contain events, attrs contains
4. props supports types other than string, attrs only has string type

toRefs()

toRefs() can convert the responsive object created by reactive() into a normal object whose content is the value of ref
responsive

Before figuring out the usage of toRefs(), we need to understand
the difference between reactive objects created with reactive() and ref():

1. For
a responsive object created with reactive(), the entire object is responsive, and each item in the object is a common value. When you expand it with the spread operator, the normal value of the entire object is not responsive;

2. The responsive value created with ref() is itself responsive and does not depend on other objects.

So when you need to expand the responsive objects created by reactive() and don't want them to lose their responsiveness, you need to convert them with toRefs():

// 定义响应式数据对象
const state = reactive({
    
    
count: 0
})
// 定义简单的函数,使count每次+1
const add = () => {
    
    
state.count++
}
// 将setup函数的内容return出去,供外界使用
return {
    
    
// 将 state 展开导出,同时将其属性都转化为 ref 形式的响应式数据
...toRefs(state),
add
}

Reactive ref

reactive: The function of reactive is to wrap the object into a responsive object ---
the object after proxying through Proxy.

ref: Returns a responsive, mutable ref object with only value as an attribute from the incoming value.

readonly()

Pass in a reactive object, plain object or ref
, and return a read-only object proxy. This proxy is deep and the data inside the object is also read-only.

Watch

insert image description here
insert image description here
insert image description here

isRef()

isRef() As the name implies, it is used to judge whether a value is a responsive value created by ref().

const unwrapper = isRef(foo) ? foo.value : foo

Dynamic img

insert image description here

Transition

transition class name change

  • v-enter→v-enter-from

  • v-leave →v-leave-from

<transition name="fade">
<div v-show="visible">这是一段文本</div>
</transition>

Style:
.fade-enter-active,
.fade-leave-active {
    
    
transition: all 2s ease;
}
.fade-enter-from,
.fade-leave-to {
    
    
opacity: 0;
}

Component v-model

Parent component: // In vue3, v-model is called modelValue by default, in vue2 it is called value

View 3

VuYear(v-model="curYear" @yearChange="clickYear")

Subassembly:

el-select(v-model="currentYear" @change="(val)=>clickYear(val)")
props:{
    
    
        modelValue:{
    
    
            type:Number,
            default: 0
        }
    },
setup(props:any, context:any) {
    
    
        const clickYear = (val:any) => {
    
    
            context.emit('yearChange',val)
        }
        const currentYear = computed({
    
    
            set(value){
    
    
              context.emit('update:modelValue',value)  
            },
            get(){
    
    
                return props.modelValue
            }
        })
        return {
    
    
            clickYear,
            currentYear
        }

Custom name:

parent component

VuYear(v-model:title="title"v-model="currentYear"@yearChange="clickYear")

Subassembly:

el-select(v-model="currentYear" @change="(val)=>clickYear(val)")

props:{
    
    
        modelValue:{
    
    
            type:Number,
            default: 0
        }title:{
    
    

            type:Number,

            default: 0

        }

    },
setup(props:any, context:any) {
    
    
        const clickYear = (val:any) => {
    
    
			context.emit('update:title', val+'标题') // 更新title
            context.emit('yearChange',val)
        }
        const currentYear = computed({
    
    
            set(value){
    
    
              context.emit('update:modelValue',value)  
            },
            get(){
    
    
                return props.modelValue
            }
        })
        return {
    
    
            clickYear,
            currentYear
        }

provide/inject

1. Define symbol as a globally unique identifier
symbol.ts

import type {
    
     CloseSelectTs } from '@/types/common'

export const closeSelectKey: InjectionKey<Ref<CloseSelectTs>> = Symbol()

use:
father:

import {
    
      closeSelectKey } from '@/symbols'
const data = reactive({
    
    
    selectData: {
    
    
        year: Number(dayjs().format('YYYY')),
        areaCode: '',
        type: 0,
    }
})
// 注入筛选框数据(利用computed可以触发子组件接收到的变量也是响应式,方便自组件监听变化)
provide(closeSelectKey, computed(() => data.selectData))

offspring

import {
    
     closeSelectKey, globalKey } from '@/symbols'
const selectData = inject(closeSelectKey)
// 注意不可以使用selectData.value 监听,这样会失去响应式
selectData && watch(selectData, (val) => {
    
    
    getChart({
    
     year: val.year, areaCode: val.areaCode })
}, {
    
     deep: true })
或者:
watch(() => selectData?.value, (val) => {
    
    
    if (!val) return
    getChart({
    
     year: val.year, areaCode: val.areaCode })
}, {
    
     deep: true })

Why can it be monitored by returning value in the form of a method? to be resolved,
what is known now is that

isRef(selectData) // true
isReactive(selectData) // false

isRef(selectData?.value) // false
isReactive(selectData?.value) // true

2. Vuex

Directory Structure:

insert image description here

State.ts

export default {
    
    
    glMapPop:'close'
}

Mutation.ts

export default {
    
    
    SET_GL_MAP_POP(state:any, data:any) {
    
    
        state.glMapPop = data
    }
}

Getter.ts


export default{
    
    
    getMapPop: (state: any) => state.glMapPop
}

Action.ts

export default {
    
     // 应该封装异步这边就没写
    ADD_ACOUNTVUEX(store: any, countVuex: Number) {
    
    
        store.commit('ADD_ACOUNTVUEX', countVuex)
    }
}

AppStore/Index.ts

import state from './state'
import actions from './actions'
import mutations from './mutations'
import getters from './getters'
const appStore = {
    
    
    state,
    mutations,
    actions,
    getters,
}
export default appStore;
export default appStore;

index.ts

import {
    
     createStore, Store } from 'vuex'

import appStore from './appStore'

export default createStore({
    
    

    modules: {
    
    

        appStore,

    },

})

// vuex数据可持续化 以及state, mutation, action监听

export const storeInit = (storePublics:Store<any>) => {
    
    

    /**

     *
全局监听,页面刷新的时候将store里state的值存到sessionStorage中,然后从sessionStorage中获取,再赋值给store。

     * 然后再把session里面存的删除即可,相当于中间件的作用。

     */

    //在页面加载时读取sessionStorage里的状态信息 '刷新后'

    if (window.sessionStorage.getItem('store')) {
    
    

        storePublics.replaceState(Object.assign({
    
    }, storePublics.state,
JSON.parse(sessionStorage.getItem('store') as string)))

        window.sessionStorage.removeItem('store')

    }

    //在页面刷新时将vuex里的信息保存到sessionStorage里 '刷新前'

    window.addEventListener('beforeunload', () => {
    
    

        sessionStorage.setItem('store',
JSON.stringify(storePublics.state))

    })

    // 这里是store的生命周期,特殊需求的可用

      storePublics.watch((state)=>{
    
    

        state.name + state.name1

        console.log('当state值发生改变就会触发回调函数')

      },()=>{
    
    

        console.log('回调函数')

      })

      storePublics.subscribe((mutation,state)=>{
    
    

        console.log(mutation)

        console.log(mutation.payload)  // 每次传的参数

        console.log('每次调用mutations 都会执行这个函数')
      })
      storePublics.subscribeAction((action, state) => {
    
    
          console.log(action)
          console.log(action.payload) // 每次传的参数
          console.log('监听action')
      })
}

Main.ts

import vuex from "@/store/index";
app.use(vuex)

app.vue

import {
    
     useStore } from 'vuex'
import {
    
     storeInit } from "@/store/index";
store = useStore()
storeInit(store)
{
    
    ...mapState(['glMapPop'])} // 括号内写名称
{
    
    ...mapMutations(['SET_GL_MAP_POP'])}
{
    
    ...mapActions([])} // 如果不写则为空
{
    
    ...mapGetters([])}

3. Setup syntax sugar

Component introduction uses {#Component introduction uses .list-paragraph}

import EarthLeftPanel from '@components/earth EarthLeftPanel.vue'

Use:
earth-left-panel or
EarthLeftPanel

Module export to template {#module export to template.list-paragraph}

const {
    
     defaultCheckedLists } = toRefs(data)

define name

<script lang='ts' setup name="EarthComprehensive">

defineProps

defineProps({
    
    
    info:{
    
    
        type:String,
        default:'--'
    },
    time:{
    
    
        type:String,
        default:'0分钟'
    },
})

defineEmits

 import {
    
    defineEmits} from 'vue'
//  使用defineEmits创建名称,接受一个数组\
let $myemit=defineEmits(['myAdd','myDel'])
let hander1Click=():void=>{
    
    
    $myemit('myAdd','新增的数据')
}

let hander2Click=():void=>
    $myemit('myDel','删除的数据')
}

defineExpose

// 将组件中的属性暴露出去,这样父组件可以获取\
defineExpose({
    
    
    sex,
    info
})

v-memo

v-memod remembers a subtree of templates that can be used on both elements and components.
This instruction receives a fixed-length array as a dependent value for [memory comparison].
If every value in the array is the same as it was last rendered, the update of the entire subtree is skipped.
Even the VNode creation of the virtual DOM will be skipped, since the memorized copy of the subtree can be reused.
So the rendering speed will be very fast.
It is important to note that it is important to declare memory arrays correctly.
It is the developer's responsibility to specify the correct dependency array to avoid necessary updates being skipped.

<li v-for="item in listArr"  :key="item.id"  v-memo="['valueA','valueB']">
    {
    
    {
    
     item.name   }}
</li>

The instructions of v-memod are less used, and its function is to cache part of the data in the template.
Only created once and will not be updated in the future. In other words, memory is exchanged for time.

Guess you like

Origin blog.csdn.net/Ndbsa/article/details/127937693