vue3 基础学习

392 阅读2分钟

vue3 基础学习

学习一下vue3基础

  • 变量定义
  • 方法定义
  • watch
  • computed
  • 生命周期
  • 组件
export default {
  setup () {
    const pageTitle = '页面名称' // 定义一个不需改变的常量

    /**
     * @用户信息模块
     **/
    let sex = 0 // 0-女,1-男。定义一个需要改变但不需响应式的变量

    const username = ref('Justplay') // 定义一个响应式变量username
    // 为啥不推荐 const username = $ref('Justplay')
    // 我们都知道使用$ref后,username的赋值就变成了`username = xxx`,
    // 与不需要响应式的变量如何区分呢,图一时的简单,不顾后期的维护,其可乎?
    // 作者读书少,思想境界有限,不接受反驳
    const changeUsername = name => {  // 定义改变username的方法
      userName.value = name
    }

    // 定义对象
    const userInfoObj = reactive({ username, desc: '自我介绍'})
    const changeUserInfoObj = obj => {
      userInfoObj.username = obj.username
      userInfoObj.desc = obj.desc
    }
    
    // 定义数组
    const userImgs = ref([])  // 赋值:userImgs.value = [1, 2, 3]
    // const userImgs = reactive([])  // 直接赋值响应式会消失:userImgs = [1, 2, 3]
    // 需要使用数组方法改变数组值 userImgs.push(...[1, 2, 3])

    const stop = watchEffect(() => {
      console.log(username.value, sex)
    })
    stop() // 可以手动停止监听

    count count = ref(0)
    const plusAdd = computed(() => {
      return count.value ++
    })

    // 生命周期
    onMounted(() => {
      console.log('onMounted')
    })
    onUpdated(() => {
      console.log('onUpdated')
    })
    onUnmounted(() => {
      console.log('onUnmounted')
    })

    return {
      pageTitle,
      sex,
      username,
      changeUsername,
      userInfoObj,
      changeUserInfoObj,
      plusAdd
    }
  }
}

组件

  • 组件应该是对代码逻辑、代码结构的拆分和复用
  • 好的组件应该平衡代码逻辑、代码结构
  • 组件应尽量独立,并最好遵循vue数据流单向的原则。
  • 数据从父组件流到子组件,而后逻辑的处理和展示都在子组件中完成
  • 需要返回父组件结果的,也尽量将数据处理逻辑在组件中处理,父组件只做简单的数据接收
  • 如果一个页面做了大量的组件后页面的逻辑还是很复杂,那说明页面组件封装/结构是有问题的

// 父组件index.vue

<template>
  <!-- 注意:vue3中支持多个根结点了 -->
  <div>parent title</div>
  <div>
    parent content {{ authName }}
    <child-one ref="childOneRef" />
    <child-two :name="authName" :age="999" @changeName="changeName" />
  </div>
</template>
<script setup>
import ChildOne from 'ChildOne'
import ChildTwo from 'ChildTwo'

const authName = ref('Justplay')
const changeName = name => {
  authName.value = name
}

// 组件通讯--provide/inject
provide('authName', authName)
// 组件通讯--$parent/$children 
// 最新的文档中已被$children删除,并且setup中不允许访问this,因此this.$parent也不建议使用
// getCurrentInstance 在最新的官方文档中也已删除
// setup中访问全局变量建议使用provide/inject[可能后续的vue plugin会讲]
const childOneRef = ref()
// 组件通讯--props/emits
// 组件通讯--store、eventBus[可能后面会讲]

mounted(() => {
  console.log(childOneRef.value.number) // 12345678
})

</script>

// 子组件--ChildOne
<template>
  <div>
    child {{ authName }}
  </div>
</template>
<script setup>
// 组件通讯--provide/inject
const authName = inject('authName', 'defaut value: authName为空时使用')
const number = 12345678
</script>

// 子组件--ChildTwo
<template>
  <div @click="click">
    child {{ authName }}
  </div>
</template>
<script setup>
// 组件通讯--provide/inject
const authName = inject('authName', 'defaut value: authName为空时使用')

// 定义组件属性
const props = defineProps({
  name: { // props定义尽量详尽,建议至少应该定义type和default
    type: String,
    default: ''
  },
  age: {
    type: [String, Number],
    default: 0
  }
})

// 定义事件
const emit = defineEmits(['changeName'])

const click = () => {
  emit('changeName', 'name')
}
</script>

小tips

  • 区分常量、变量、响应式、数组、对象的实际情况,不要遇见变量就ref
  • 推荐响应式变量使用.value,$ref并不优雅,而且影响后期的代码阅读,特别是复杂的场景
  • setup中避免使用this。访问全局变量或方法可以参考provide/inject

玫瑰花宝典