>  기사  >  웹 프론트엔드  >  Vue3 개발 예제 코드 분석

Vue3 개발 예제 코드 분석

王林
王林앞으로
2023-05-17 09:44:181677검색

Get this

Vue2의 각 구성 요소에서 this는 현재 구성 요소 인스턴스를 가리킵니다. 여기에는 전역적으로 마운트된 항목도 포함되어 있습니다. 우리 모두는 this.xxx에 모든 것이 있다는 것을 알고 있습니다. 비슷한 사용법을 원하시면 두 가지 방법이 있습니다. 하나는 현재 컴포넌트 인스턴스를 얻는 것이고, 다른 하나는 글로벌 인스턴스를 얻는 것입니다. 다음과 같이 인쇄하여 직접 확인할 수 있습니다. )this.xxx 啥都有

而 Vue3 中没有 this,如果想要类似的用法有两种,一是获取当前组件实例,二是获取全局实例,如下自己可以去打印出来看看

<script setup>
import { getCurrentInstance } from &#39;vue&#39;

// proxy 就是当前组件实例,可以理解为组件级别的 this,没有全局的、路由、状态管理之类的
const { proxy, appContext } = getCurrentInstance()

// 这个 global 就是全局实例
const global = appContext.config.globalProperties
</script>

全局注册(属性/方法)

Vue2 中我们要往全局上挂载东西通常就是如下,然后在所有组件里都可以通过 this.xxx 获取到了

Vue.prototype.xxx = xxx

而 Vue3 中不能这么写了,换成了一个能被所有组件访问到的全局对象,就是上面说的全局实例的那个对象,比如在 main.js 中做全局注册

// main.js
import { createApp } from &#39;vue&#39;
import App from &#39;./App.vue&#39;
const app = createApp(App)
// 添加全局属性
app.config.globalProperties.name = &#39;沐华&#39;

在其他组件中调用

<script setup>
import { getCurrentInstance } from &#39;vue&#39;
const { appContext } = getCurrentInstance()

const global = appContext.config.globalProperties
console.log(global.name) // 沐华
</script>

获取 DOM

<template>
    <el-form ref="formRef"></el-form>
    <child-component />
</template>
<script setup lang="ts">
import ChildComponent from &#39;./child.vue&#39;
import { getCurrentInstance } from &#39;vue&#39;
import { ElForm } from &#39;element-plus&#39;

// 方法一,这个变量名和 DOM 上的 ref 属性必须同名,会自动形成绑定
const formRef = ref(null)
console.log(formRef.value) // 这就获取到 DOM 了

// 方法二
const { proxy } = getCurrentInstance()
proxy.$refs.formRef.validate((valid) => { ... })

// 方法三,比如在 ts 里,可以直接获取到组件类型
// 可以这样获取子组件
const formRef = ref<InstanceType<typeof ChildComponent>>()
// 也可以这样 获取 element ui 的组件类型
const formRef = ref<InstanceType<typeof ElForm>>()
formRef.value?.validate((valid) => { ... })
</script>

初始化

Vue2 中进入页面就请求接口,或者其他一些初始化的操作,一般放在 createdmounted,而 Vue3 中 beforeCreatedcreated 这俩钩子就不用了,因为 setup 在这俩之前执行,还要这俩的话就多此一举了

所以但凡是以前你用在 beforeCreated / created / beforeMounted / mounted 这几个钩子里的内容,在 Vue3 中要么放在 setup 里,要么放在 onMounted

<script setup>
import { onMounted } from &#39;vue&#39;

// 请求接口函数
const getData = () => {
    xxxApi.then(() => { ... })
}

onMounted(() => {
    getData()
})
</script>

解除绑定

Vue2 中一般清除定时器、监听之类的操作有两种方法:

  • 一是用$once 搭配 hook: BeforeDestroy 使用,这个 Vue3 不支持了

  • 二是用 beforeDestroy / deactivated 这俩钩子,Vue3 中只是把钩子函数重命名了一下

<script setup>
import { onBeforeUnmount, onDeactivated } from &#39;vue&#39;

// 组件卸载前,对应 Vue2 的 beforeDestroy
onBeforeUnmount(() => {
    clearTimeout(timer)
    window.removeAddEventListener(&#39;...&#39;)
})

// 退出缓存组件,对应 Vue2 的 deactivated
onDeactivated(() => {
    clearTimeout(timer)
    window.removeAddEventListener(&#39;...&#39;)
})
</script>

ref 和 reactive

这两都是用于创建响应式对象,ref 通常用于创建基础类型,reactive 通常用于创建响应式,这是官方推荐的,现实中也不尽然,有人也用 ref 来定义数组,也有人一个组件只定义一个 reactive,所有数据都放里面,就像 Vue2 的 data 一样,也有人都用

需要知道的有两点:

  • ref 如果传入的是引用类型,内部源码也是调用 reactive 来实现的

  • ref 返回的属性在 template 中使用,直接用就是了,但是在 JS 中使用,需要通过 .value 获取,如下。因为 ref 返回的是一个包装对象

<template>
    <div>{{ count }}</div>
</template>
<script setup>
import { ref, reactive } from &#39;vue&#39;
const count = ref(1)

// 有人这么用 
const arr = ref([])
console.log(arr.value) // []

// 也有人这么用,一个组件里所有的属性全部定义在一个对象里,有点 Vue2 data 的味道
const data = reactive({
    name: &#39;沐华&#39;,
    age: 18,
    ...
})
console.log(data.name) // 沐华

// 也有人一个组件里 ref 和 reactive 两种都用,随便你
</script>

为什么 ref 要返回一个包装对象?Vue2 中 data 都是返回一个对象这都知道

因为对象引用类型,可以用来做代理或劫持,如果只返回基础类型的话,存储在栈中,执行栈里执行完就回收了,没有办法添加代理或劫持,自然就没办法追踪后续的变化,所以不得不返回一个对象,这样才能有响应式

toRef 和 toRefs

这两共同点就是用来创建响应式的引用的,主要用来取出响应式对象里的属性,或者解构响应式对象,解构出来的属性值依然是响应式属性,如果不用这两直接解构的话是会丢失响应式效果的

主要就是方便我们使用直接变量 xxx,而不需要 data.xxx。并且我们修改 xxx 的时候也是直接修改源对象属性的

这两的区别:带 s 和不带 s,就是单数和复数嘛,意思就是取一个和取一堆咯

<script setup>
import { reactive, toRef, toRefs } from &#39;vue&#39;

const data = reactive({
    name: &#39;沐华&#39;,
    age: 18
})

// 这样虽然能拿到 name / age,但是会变成普通变量,没有响应式效果了
const { name, age } = data

// 取出来一个响应式属性
const name = toRef(data, &#39;name&#39;)

// 这样解构出来的所有属性都是有响应式的
const { name, age } = toRefs(data)

// 不管是 toRef 还是 toRefs,这样修改是会把 data 里的 name 改掉的
// 就是会改变源对象属性,这才是响应式该有的样子
name.value = &#39;沐沐华华&#39;
</script>

watch

watch 就是用来监听一个已有属性,发生变化的时候做某些操作,Vue2 中常用有如下三种写法

watch: {
    userId: &#39;getData&#39;,
    userName (newName, oldName) {
        this.getData()
    },
    userInfo: {
        handler (newVal, newVal) { this.getData() },
        immediate: true,
        deep: true
    }
}

而 Vue3 中监听的写法就丰富得多了

Vue3 的 watch 是一个函数,能接收三个参数,参数一是监听的属性,参数二是接收新值和老值的回调函数,参数三是配置项

<script setup>
import { watch, ref, reactive } from &#39;vue&#39;

const name = ref(&#39;沐华&#39;)
const data = reactive({
    age: 18,
    money: 100000000000000000000,
    children: []
})

// 监听 ref 属性
watch(name, (newName, oldName) => { ... })

// 监听其他属性、路由或者状态管理的都这样
watch(
    () => data.age, 
    (newAge, oldAge) => { ... }
)

// 监听多个属性,数组放多个值,返回的新值和老值也是数组形式
watch([data.age, data.money], ([newAge, oldAge], [newMoney, oldMoney]) => { ... })

// 第三个参数是一个对象,为可配置项,有5个可配置属性
watch(data.children, (newList, oldList) => { ... }, {
    // 这两个和 Vue2 一样,没啥说的
    immediate: true,
    deep: true,
    // 回调函数的执行时机,默认在组件更新之前调用。更新后调用改成post
    flush: &#39;pre&#39;, // 默认值是 pre,可改成 post 或 sync
    // 下面两个是调试用的
    onTrack (e) { debugger }
    onTrigger (e) { debugger }
})
</script>

关于副作用,在 watch 回调函数中能接收第三个参数,为清除副作用的函数,它的执行机制默认在更新之前调用,比如如下代码,当 key 触发更新时会先打印 222 再打印 沐华,如果需要在更新之后调用,可以在 watch 第三个配置项中添加 flush: post

Vue2에서는 전역적으로 마운트하는 방법이 일반적으로 다음과 같으며, 모든 컴포넌트

// 回调函数接收一个参数,为清除副作用的函数
watch(key, (newKey, oldKey, onInvalidate) => {
    console.log(&#39;沐华&#39;)
    // 获取DOM默认获取到的是更新前的dom,如果是flush: post,可以获取到更新后的dom
    console.log(&#39;DOM节点:&#39;, dom.innterHTML)
    onInvalidate(() => {
        console.log(2222)
    })
})

에서 this.xxx를 통해 얻을 수 있습니다. 그러나 Vue3에서는 작성할 수 없습니다. 얻는 전역 개체는 위에서 언급한 전역 인스턴스의 개체로 대체됩니다. 예를 들어 main.js

// 停止监听
const unwatch = watch(&#39;key&#39;, callback)
const unwatchEffect = watchEffect(() => {})
// 需要的时候手动停止监听
unwatch()
unwatchEffect()

Call

<script setup>
import { watchEffect } from &#39;vue&#39;

// 正常使用
watchEffect(() => {
    // 会自动收集这个函数使用到的属性作为依赖,进行监听
    // 监听的是 userInfo.name 属性,不会监听 userInfo
    console.log(userInfo.name)
})

// 有两个参数,参数一是触发监听回调函数,参数二是可选配置项
watchEffect(() => {...}, {
    // 这里是可配置项,意思和 watch 是一样的,不过这只有3个可配置的
    flush: &#39;pre&#39;,
    onTrack (e) { debugger }
    onTrigger (e) { debugger }
})

// 回调函数接收一个参数,为清除副作用的函数,和 watch 的同理
watchEffect(onInvalidate => {
    console.log(&#39;沐华&#39;)
    onInvalidate(() => {
        console.log(2222)
    })
})
</script>
에서 전역 등록을 수행하세요.

다른 구성 요소에서 DOM

watchEffect(() => {...}, {
    flush: &#39;post&#39;,
})
// 和下面这个是一样的
watchPostEffect(() => {})
-----------------------------
watchEffect(() => {...}, {
    flush: &#39;sync&#39;,
})
// 和下面这个是一样的
watchSyncEffect(() => {})

Initialization
  • 을 얻으려면 Vue2에서 페이지에 들어갈 때 일반적으로 created 또는 mounted에 배치되는 인터페이스 또는 기타 초기화 작업을 요청하세요. code>, Vue3에서는 beforeCreatedcreated 이 두 후크가 필요하지 않습니다. 이 두 후크 전에 설정이 실행되기 때문입니다. 그것은 불필요할 것입니다

    그래서 beforeCreated/created/beforeMounted/ code>에서 사용했다면 이 후크의 내용은 setup 또는 에 배치됩니다. Vue3의 onMounted
  • <script setup>
    import { computed } from &#39;vue&#39;
    
    // 获取 url 上的 type 属性
    const type = computed(() => Number(this.$route.query.type || &#39;0&#39;))
    
    // 对象写法
    const visible = computed({
        get () { return this.visible },
        set (val) { this.$emit(&#39;input&#39;, val) }
    })
    
    // computed 第二个参数也是一个对象,调试用的
    const hehe = computed(参数一上面两种都可, {
        onTrack (e) { debugger }
        onTrigger (e) { debugger }
    })
    </script>
  • Unbinding

    Vue2에서는 일반적으로 지워짐 타이머 및 모니터링과 같은 작업에는 두 가지 방법이 있습니다. 🎜🎜🎜🎜하나는 와 함께 <code>$once를 사용하는 것입니다. Hook: BeforeDestroy. 이는 Vue3에서 지원되지 않습니다 🎜🎜🎜 🎜두 번째는 beforeDestroy / deactivated 두 개의 후크를 사용하는 것입니다. Vue3에서는 후크 기능의 이름이 바뀌었습니다🎜🎜 ul>
    <script setup>
    import { nextTick} from &#39;vue&#39;
    
    // 方式 一
    const handleClick = async () => {
      await nextTick()
      console.log(&#39;沐华&#39;)
    }
    
    // 方式二
    nextTick(() => {
        console.log(&#39;沐华&#39;)
    })
    
    // 方式三
    nextTick().then(() => {
        console.log(&#39;沐华&#39;)
      })
    </script>
    🎜ref 및active🎜🎜둘 다 반응형 객체를 생성하는 데 사용되며, ref는 일반적으로 기본 유형을 생성하는 데 사용되며, reactive는 일반적으로 반응형 유형을 생성하는 데 사용됩니다. 이는 공식적으로는 권장되지만 실제로는 항상 그런 것은 아닙니다. ref 를 사용하여 배열을 정의하는 사람도 있고, 각 구성요소에 대해 하나의 reactive만 정의하는 사람도 있습니다. Vue2의 data와 마찬가지로 모든 데이터가 여기에 저장되어 있으므로 일부 사람들은 이를 사용합니다. 🎜🎜 알아야 할 두 가지 사항이 있습니다: 🎜🎜🎜🎜ref 유형이 전달되면 내부 소스 코드도 reactive 🎜🎜🎜🎜ref 를 호출하여 구현됩니다. 반환된 속성은 template에서 사용되며 다음을 수행할 수 있습니다. 다만, JS에서 사용할 경우에는 아래와 같이 .value를 통해 얻어야 합니다. ref가 래퍼 객체를 반환하기 때문에🎜🎜
// xxx.js
expport const getData = () => {}
export default function unInstance () {
    ...
    return {...}
}

// xxx.vue
import unInstance, { getData } from &#39;xx.js&#39;
const { ... } = unInstance()
onMounted(() => {
    getData()
})
🎜 ref가 래퍼 객체를 반환하는 이유는 무엇인가요? Vue2의 데이터는 객체를 반환한다는 것을 우리는 모두 알고 있습니다🎜🎜객체 참조 유형이 프록시 또는 하이재킹으로 사용될 수 있기 때문에 기본 유형만 반환되면 스택에 저장되고 실행 스택에서 실행 후 재활용됩니다. 추가하거나 하이재킹할 수 있는 방법이 없으므로 당연히 후속 변경 사항을 추적할 수 없으므로 반응형 🎜🎜toRef 및 toRefs🎜🎜을 사용할 수 있습니다. 반응형 참조를 생성하는 데 주로 사용됩니다. 반응형 객체의 속성 또는 반응형 객체를 분해하는 경우, 분해된 속성 값은 여전히 ​​반응형 속성입니다. 이 두 가지 직접 분해를 사용하지 않으면 반응형 효과를 잃게 됩니다🎜 🎜주로 data.xxx 대신 직접 변수 xxx를 사용하는 것을 용이하게 하기 위한 것입니다. 그리고 xxx를 수정할 때 소스 객체 속성도 직접 수정합니다. s가 있는 것과 없는 것의 차이점은 단수형과 복수형입니다. 즉, 하나를 취하고 여러 개를 취한다는 의미입니다.
// 父组件写法
<template>
    <child v-model:name="name" v-model:age="age" />
</template>
<script setup>
import { ref } from "vue"
const name = ref(&#39;沐华&#39;)
const age = ref(18)
</script>

// 子组件
<script setup>
const emit = defineEmits([&#39;update:name&#39;, &#39;update:age&#39;])

const handleClick = () => {
    console.log(&#39;点击了&#39;)
    emit(&#39;update:name&#39;, &#39;这是新的名字&#39;)
}
</script>
🎜watch🎜🎜watch는 기존 속성을 모니터링하고 변경 시 특정 작업을 수행하는 데 사용됩니다. Vue2에서는 다음 세 가지 작성 방법이 일반적으로 사용됩니다🎜
<script setup>
import { useRoute, useRouter } from "vue-router"

// route 对应 this.$route
const route = useRoute()

// router 对应 this.$router
const router = useRouter()
</script>
🎜그리고 Vue3에서 모니터링하는 작성 방법이 훨씬 더 풍부해졌습니다🎜🎜Vue3 watch 3개의 매개변수를 받을 수 있는 함수입니다. 첫 번째 매개변수는 모니터링 속성, 두 번째 매개변수는 새 값과 이전 값을 받는 콜백 함수, 세 번째 매개변수는 구성 항목🎜
<template>
    <div>1</div>
    <div>2</div>
</template>
🎜입니다. watch 콜백 함수는 부작용을 제거하는 함수인 세 번째 매개변수를 받을 수 있습니다. 해당 실행 메커니즘은 기본적으로 업데이트 전에 호출됩니다. 예를 들어 다음 코드에서는 키가 업데이트를 트리거할 때 먼저 222를 입력하고 Muhua를 인쇄합니다. 업데이트 후에 호출해야 하는 경우 watch의 세 번째 구성 항목에 flush: post를 추가할 수 있습니다. 🎜
<style scoped>
// 这样写不生效的话
.el-form {
    .el-form-item { ... }
}
// Vue2 中这样写
/deep/ .el-form {
    .el-form-item { ... }
}
// Vue3 中这样写
:deep(.el-form) {
    .el-form-item { ... }
}
</style>

// 别再这样加一个没有 scoped 的 style 标签了,全都加到全局上去了
// <style lang="scss">
//  .el-form {
//     .el-form-item { ... }
//  }
// </style>
🎜모니터링은 아직 안 끝났어요🎜🎜유다: 헤헤~🎜🎜watchEffect 🎜🎜Vue3에는 watch 외에 watchEffect도 추가되어 있어요. 차이점은 다음과 같습니다. 🎜🎜🎜🎜watch는 전달된 하나 이상의 값을 모니터링하는 것입니다. 트리거되면 새 값과 이전 값을 반환하며 기본적으로 처음 실행되지 않습니다. 🎜watchEffect는 값을 전달하고 즉시 실행하는 기능이므로 기본적으로 처음 실행되며 모니터링 내용을 전달할 필요가 없습니다. 종속성이 변경되면 함수가 다시 실행되고(계산된 것과 약간 비슷함) 새 값과 이전 값을 반환하지 않습니다 🎜
  • 清除副作用和副作用的刷新时机是一样的,区别是 watch 中会作为回调的第三个参数传入,watchEffect 中是回调函数的第一个参数

  • 正常情况下组件销毁/卸载后这两都会自动停止监听,但也有例,比如异步的方式在 setTimeout 里创建的监听就都需要手动停止监听,停止方式如下

  • // 停止监听
    const unwatch = watch(&#39;key&#39;, callback)
    const unwatchEffect = watchEffect(() => {})
    // 需要的时候手动停止监听
    unwatch()
    unwatchEffect()

    watchEffect 使用:

    <script setup>
    import { watchEffect } from &#39;vue&#39;
    
    // 正常使用
    watchEffect(() => {
        // 会自动收集这个函数使用到的属性作为依赖,进行监听
        // 监听的是 userInfo.name 属性,不会监听 userInfo
        console.log(userInfo.name)
    })
    
    // 有两个参数,参数一是触发监听回调函数,参数二是可选配置项
    watchEffect(() => {...}, {
        // 这里是可配置项,意思和 watch 是一样的,不过这只有3个可配置的
        flush: &#39;pre&#39;,
        onTrack (e) { debugger }
        onTrigger (e) { debugger }
    })
    
    // 回调函数接收一个参数,为清除副作用的函数,和 watch 的同理
    watchEffect(onInvalidate => {
        console.log(&#39;沐华&#39;)
        onInvalidate(() => {
            console.log(2222)
        })
    })
    </script>

    watchEffect 如果需要修改配置项 flush 为 post 或 sync 时,可以直接使用别名,如下

    watchEffect(() => {...}, {
        flush: &#39;post&#39;,
    })
    // 和下面这个是一样的
    watchPostEffect(() => {})
    -----------------------------
    watchEffect(() => {...}, {
        flush: &#39;sync&#39;,
    })
    // 和下面这个是一样的
    watchSyncEffect(() => {})

    computed

    Vue2 中 computed 最见的使用场景一般有: mapGetters/mapState 获取状态管理的属性、 获取 url 上的属性、条件判断、类型转换之类的,支持函数和对象两种写法

    而 Vue3 中 computed 不再是一个对象,而是一个函数,用法其实基本差不多,函数第一个参数是侦听器源,用于返回计算的新值,也支持对象写法,第二个参数可用于调试

    <script setup>
    import { computed } from &#39;vue&#39;
    
    // 获取 url 上的 type 属性
    const type = computed(() => Number(this.$route.query.type || &#39;0&#39;))
    
    // 对象写法
    const visible = computed({
        get () { return this.visible },
        set (val) { this.$emit(&#39;input&#39;, val) }
    })
    
    // computed 第二个参数也是一个对象,调试用的
    const hehe = computed(参数一上面两种都可, {
        onTrack (e) { debugger }
        onTrigger (e) { debugger }
    })
    </script>

    nextTick

    nextTick 的使用方法,除了不能用 this 其他的和 Vue2 一模一样,还是三种方式

    <script setup>
    import { nextTick} from &#39;vue&#39;
    
    // 方式 一
    const handleClick = async () => {
      await nextTick()
      console.log(&#39;沐华&#39;)
    }
    
    // 方式二
    nextTick(() => {
        console.log(&#39;沐华&#39;)
    })
    
    // 方式三
    nextTick().then(() => {
        console.log(&#39;沐华&#39;)
      })
    </script>

    mixins 和 hooks

    Vue2 中逻辑的抽离复用一般用 mixins,缺点有三:

    • 没有独立命名空间,mixins 会和组件内部产生命名冲突

    • 不去翻代码不知道引入的 mixins 里面有啥

    • 引入多个 mixins 时不知道自己使用的是来自哪一个 mixins 的

    在Vue3中,逻辑可重用的hooks语法实际上是一个函数,可以接受参数并返回值,从而被使用。在Vue3中,编写封装公共方法的方法与平时相同

    // xxx.js
    expport const getData = () => {}
    export default function unInstance () {
        ...
        return {...}
    }
    
    // xxx.vue
    import unInstance, { getData } from &#39;xx.js&#39;
    const { ... } = unInstance()
    onMounted(() => {
        getData()
    })

    关于 hooks 如何写出更优雅的代码,还个需要多写,多实践

    组件通信

    Vue3 组件通信的方式,有如下几种

    • props + defineProps

    • defineEmits

    • defineExpose / ref

    • useAttrs

    • v-model(支持多个)

    • provide / inject

    • Vuex / Pinia

    关于 Vue 组件通信的使用方式,去年我写过一篇文章,上面都罗列的很详细了,就不搬过来了

    Vue3的8种和Vue2的12种组件通信

    多个 v-model

    Vue2 中每个组件上只能写一个 v-model,子组件没有写 model 的话,默认在 props 接收 value 即可,修改就是用 this.$emit('input') 事件

    Vue3 中每个组件每个组件上支持写多个 v-model,没有了 .syncmodel 重命名的操作,也不需要了,写v-model 的时候就需要把命名一起写上去了,如下:

    // 父组件写法
    <template>
        <child v-model:name="name" v-model:age="age" />
    </template>
    <script setup>
    import { ref } from "vue"
    const name = ref(&#39;沐华&#39;)
    const age = ref(18)
    </script>
    
    // 子组件
    <script setup>
    const emit = defineEmits([&#39;update:name&#39;, &#39;update:age&#39;])
    
    const handleClick = () => {
        console.log(&#39;点击了&#39;)
        emit(&#39;update:name&#39;, &#39;这是新的名字&#39;)
    }
    </script>

    状态管理

    Vuex 会的就不用说了,不会的就直接学 Pinia 吧

    Pinia 的使用方式,我之前也写过一篇文章,也不搬过来了

    上手 Vue 新的状态管理 Pinia,一篇文章就够了

    路由

    Vue2 中的 $route$router 如下,可以自己打印出来看一下

    <script setup>
    import { useRoute, useRouter } from "vue-router"
    
    // route 对应 this.$route
    const route = useRoute()
    
    // router 对应 this.$router
    const router = useRouter()
    </script>

    template

    Vue2 中只能有一个根节点,而 Vue3 中支持多个根节点,这个大家都知道

    其实本质上 Vue3 每个组件还是一个根节点,因为 DOM 树只能是树状结构的,只是 Vue3 在编译阶段新增了判断,如果当前组件不只一个根元素,就添加一个 fragment 组件把这个多根组件的给包起来,相当于这个组件还是只有一个根节点

    <template>
        <div>1</div>
        <div>2</div>
    </template>

    CSS 样式穿透

    Vue2 中在 scoped 中修改子组件或者组件库中的组件样式,改不了的情况下,就可以用样式穿透,不管是 Less 还是 SASS 都是用 /dee/ .class {} 来做样式穿透,而 Vue3 中就不支持 /deep/ 的写法了,换成 :deep(.class)

    <style scoped>
    // 这样写不生效的话
    .el-form {
        .el-form-item { ... }
    }
    // Vue2 中这样写
    /deep/ .el-form {
        .el-form-item { ... }
    }
    // Vue3 中这样写
    :deep(.el-form) {
        .el-form-item { ... }
    }
    </style>
    
    // 别再这样加一个没有 scoped 的 style 标签了,全都加到全局上去了
    // <style lang="scss">
    //  .el-form {
    //     .el-form-item { ... }
    //  }
    // </style>

    CSS 绑定 JS 变量

    就是 CSS 中可以使用 JS 的变量来赋值,如下

    <template>
        <div class="name">沐华</div>
    </template>
    <script setup>
    import { ref } from "vue"
    const str = ref(&#39;#f00&#39;) // 红色
    </script>
    <style scoped lang="scss">
    .name {
        background-color: v-bind(str); // JS 中的色值变量 #f00 就赋值到这来了
    }
    </style>

    위 내용은 Vue3 개발 예제 코드 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제