Vue3(重点笔记)

Vue3官方文档


1.指令

v-bind

用于动态地绑定一个或多个属性,或一个组件 prop 到表达式。

<!-- 绑定一个属性 -->
<img v-bind:src="imageSrc">

<!-- 使用对象语法同时绑定多个属性 -->
<img v-bind="{ src: imageSrc, alt: imageAlt }">

<!-- 缩写 -->
<img :src="imageSrc">
v-model

在表单控件元素上创建双向数据绑定。

<input v-model="message" placeholder="编辑我...">
<p>消息是:{{ message }}</p>
v-for

用于基于源数据多次渲染一个元素或模板块。

<ul>
  <li v-for="item in items" :key="item.id">
    {{ item.text }}
  </li>
</ul>
v-if / v-else-if / v-else

条件性地渲染一块内容。

<p v-if="user.isLoggedIn">欢迎回来,{{ user.name }}!</p>
<p v-else>请登录。</p>
v-show

通过切换 CSS 属性 display 来条件性地渲染元素。

<p v-show="isVisible">现在你看到我了</p>
v-on

监听 DOM 事件,并在事件触发时执行表达式。

<button v-on:click="sayHello">点击我</button>

<!-- 缩写 -->
<button @click="sayHello">点击我</button>
v-once

只渲染元素和组件一次,随后的重新渲染将不会更新。

<span v-once>This will never change: {{msg}}</span>
v-cloak

与 CSS 结合使用,用于在 Vue 实例被创建之前保持原始的 HTML,避免闪烁。

<style>
  [v-cloak] {
    display: none;
  }
</style>
<div v-cloak>
  {{ message }}
</div>
v-text 和 v-html
  • v-text:更新元素的文本内容。
  • v-html:更新元素的 HTML 内容,需要小心使用以避免 XSS 攻击。
<!-- 文本内容 -->
<p v-text="message"></p>

<!-- HTML 内容 -->
<div v-html="rawHtml"></div>
v-memo

对子树的响应性依赖进行跟踪,并仅在依赖发生变化时重新渲染。

<template v-memo="memoKey">
  <!-- 复杂的模板 -->
</template>
自定义指令

除了内置指令,Vue 也允许你定义自己的指令。

javascript复制

// 注册一个全局自定义指令 `v-focus`
app.directive('focus', {
  // 当绑定元素插入到 DOM 中时...
  mounted(el) {
    // 聚焦元素
    el.focus();
  }
})

// 使用
<input v-focus>

2.插槽 slot /

2.1默认插槽

默认插槽是未指定名称的插槽,子组件中使用 <slot> 标签来定义,默认情况下,所有未被具名插槽匹配的内容都会被分发到默认插槽。

子组件(ChildComponent.vue):

<template>
  <div>
    <slot></slot> <!-- 默认插槽 -->
  </div>
</template>

父组件(ParentComponent.vue):

<template>
  <ChildComponent>
    <p>这里是一些插入的内容</p>
  </ChildComponent>
</template>
2.2具名插槽

具名插槽允许你定义多个插槽,每个插槽都有一个名字。在子组件中,使用 <slot> 标签的 name 属性来定义具名插槽。

子组件(ChildComponent.vue):

<template>
  <div>
    <slot name="header"></slot> <!-- 具名插槽 -->
    <slot name="footer"></slot> <!-- 具名插槽 -->
  </div>
</template>

父组件(ParentComponent.vue):

<template>
  <ChildComponent>
    <template v-slot:header>
      <h1>这是头部内容</h1>
    </template>
    <template v-slot:footer>
      <p>这是底部内容</p>
    </template>
  </ChildComponent>
</template>

Vue 3 引入了 # 符号作为 v-slot 的缩写,使得具名插槽的写法更加简洁。

<ChildComponent>
  <template #header>
    <h1>这是头部内容</h1>
  </template>
  <template #footer>
    <p>这是底部内容</p>
  </template>
</ChildComponent>
2.3作用域插槽

作用域插槽允许子组件将数据作为插槽的一部分传递回父组件。在子组件中,使用 v-slot 指令来定义作用域插槽。

子组件(ChildComponent.vue):

<template>
  <ul>
    <li v-for="item in items" :key="item.id">
      <slot :item="item">{{ item.defaultText }}</slot> <!-- 作用域插槽 -->
    </li>
  </ul>
</template>
<script>
export default {
  data() {
    return {
      items: [{ id: 1, defaultText: '默认文本1' }, { id: 2, defaultText: '默认文本2' }]
    };
  }
}
</script>

父组件(ParentComponent.vue):

<template>
  <ChildComponent>
    <template v-slot:default="slotProps">
      <span>{{ slotProps.item.id }} - {{ slotProps.item.text }}</span>
    </template>
  </ChildComponent>
</template>

使用 # 符号简化作用域插槽的写法:

<ChildComponent>
  <template #default="slotProps">
    <span>{{ slotProps.item.id }} - {{ slotProps.item.text }}</span>
  </template>
</ChildComponent>

3.v:bind 的同名简写

  1. :id=id 可以写成 :id

4.前端Vue异常

  • 信息、警告(可能版本问题等,根错误不同)

5.VUE声明响应式数据

  1. 使用ref( )就行,
  2. reactive( ) 只能声明引用数据类型

6.计算属性:computed(就是有依赖缓存)

使用场景:(常用的就是get函数,set函数不太常用)

  1. 需要的数据JS中没有
  2. 可以通过现有的数据通过操作得到数据

7.v-if 和 v-for 优先级

  1. vue2中 v-if > v-for
  2. vue3中 v-if < v-for

8.element-ui 框架使用思路

直接‘快速开始’ 看需要安装什么对应的安装,比如使用到了图标就去安装图标,

然后使用组件,找到对应的组件以及对应的代码开始测试。

9. 组件通信 Vue3官方文档

父子组件通信
  • 父到子(Props)

    父组件通过props向子组件传递数据。子组件通过声明props来接收。

    // 子组件
    <script setup>
    import { defineProps } from 'vue';
    
    const props = defineProps({
      dataName: String // 或其他类型
    });
    </script>
    
  • 子到父(Events)

    :子组件通过$emit向父组件发送事件和数据,父组件监听这些事件。

    // 子组件
    <script setup>
    import { defineEmits } from 'vue';
    
    const emit = defineEmits(['update:name']);
    
    function updateData() {
      emit('update:name', newValue);
    }
    </script>
    

    父组件监听 update:name 事件:

    <!-- 父组件 -->
    <ChildComponent @update:name="handleNameUpdate" />
    

    父组件中处理事件:

    function handleNameUpdate(newValue) {
      // 更新数据
    }
    
爷孙组件通信
  • 爷爷到孙子(Provide / Inject)爷爷组件使用 provide 提供数据,孙子组件使用 inject 注入数据。

    // 爷爷组件
    <script setup>
    import { provide } from 'vue';
    
    provide('dataName', dataValue);
    </script>
    

    孙子组件注入数据:

    <script setup>
    import { inject } from 'vue';
    
    const dataName = inject('dataName');
    </script>
    
使用 v-model 进行双向绑定
  • 自定义组件的 v-model

    :类似于父子组件通信,

    v-model
    

    可以用于自定义组件,以实现双向绑定。

    // 子组件
    <script setup>
    import { defineProps, defineEmits } from 'vue';
    
    const props = defineProps({
      modelValue: String // 或其他类型
    });
    const emit = defineEmits(['update:modelValue']);
    
    function updateModel(value) {
      emit('update:modelValue', value);
    }
    </script>
    

    父组件使用

    v-model
    

    html

    <!-- 父组件 -->
    <ChildComponent v-model="parentData" />
    

    在这里,

    parentData
    

    是父组件中的数据,

    v-model
    

    会自动使用

    update:modelValue
    

    事件和

    modelValue
    

    prop 来实现双向绑定。

10.vue Router 路由:局部跳转 官网文档

1.首先下载 pnpm add vue-router@4

2.在main.js文件中引入实例–VueRouter–创建vue实例–注册vue实例

3.在app.vue中引入 import { RouterLink, RouterView } from ‘vue-router’;

4.然后使用 RouterLink 就相当于 a标签

5.注意:使用要给 路由的出口 RouterView

路由跳转:

  1. 使用上面的 RouterLink 标签 注意:给 路由的出口 RouterView
  2. 使用路由实例的push方法和 replace方法都能实现路由跳转,replace方法是替换历史记录得到
  3. 使用路由实例的back方法可以实现返回上一页,使用实例的go方法传入整数可以跳转n个页面 n 为-1 就是返回上一页

路由传参:

在实际项目中路由通常来实现页面跳转,很多时候页面跳转要传递一些数据到目标页面,为了满足这种路由跳转的时候
  声明式路由传参:使用RouterLink标签来实现页面跳转,也可以使用query和 params实现传参,情况跟下面的编程式传参一样
  编程式路由传参 (使用js实现路由跳转)
  props传参【了解】
  1. //query传参 (path+query搭配使用)
    //query 传参,查询字符串传参,path+query搭配使用(类似于get请求 参数拼接在 浏览器的url 后面,刷新页面数据不会丢失 和 控制台的 query 有参数)
        router.push({
            // query路由传参
            path:'/goods',//跳转到目标路由
            query:{
                id:'120' //传的数据
            }
        })
    
  2. //params传参
    //params 动态路由传参,name+query搭配使用 (要在路由的配置path后面加要接收的参数,比如path:'goods/:id/:age')更安全一点,
    //(vue2中,不配置path可以接收到参数,但是刷新页面数据丢失)
    router.push({
            // params传参
            name: 'goods',
            params: {
                id: '120'
            }
        })
    

重定向:就是访问一个路径,自动跳转到另外一个路径,比如访问404页面

路由模式
  1.hash模式,哈希模式。纯前端实现,底层监听了onhashchange事件,局部刷新,很丑
  2.history,历史模式,需要后端支持,底层就是html5 history api:pushState 和 replaceState 局部刷新 漂亮一些
  3.memory模式,主要用于node端,页面的渲染不会反映在url上 【了解】
  //路由模式
 	history:createWebHashHistory(),//hash模式,
	history: createWebHistory(),//history 历史模式
  history:createMemoryHistory(),//memory
路由元信息
//在传参的位置加上 meta配置
    //query传参的配置
    {
        path: '/goods',
        component: GoodsView,
        //元信息(Meta Information)
        meta:{title:'商品页',auth:false, KeepAlive:true} 
    },
二级路由

在原本的路由里添加一个children属性,

例:

    //query传参的配置
    {
        path: '/goods',
        component: GoodsView,
        meta: { title: '商品页', auth: false, KeepAlive: true },
        //重定项
        redirect:'/goods/list',
        //嵌套路由
        children: [
            {
                // path:'list',
                path: '/goods/list',  //推荐 便于查找
                component: () => import('../pages/goods/GoodsList.vue'), //路由懒加载
            },
            {
                // path:'type',
                path:'/goods/type',  //推荐 便于查找
                component:() => import('../pages/goods/GoodsType.vue'), //路由懒加载
            },
            {
                // path:'add',
                path:'/goods/add',  //推荐 便于查找
                component:() => import('../pages/goods/GoodsAdd.vue'), //路由懒加载
            }
        ]
    },
注意:不要忘记给出口,给到根路由的页面,这里例子是GoodsView
//出口
<template>
    <div>
        商品页
        <button @click="handleClick">返回上一页</button>
        <div class="box">
            <div class="left">
                <RouterLink to="/goods/list">商品列表</RouterLink><br>
                <RouterLink to="/goods/type">商品类型</RouterLink><br>
                <RouterLink to="/goods/add">商品添加</RouterLink><br>
            </div>
            <!-- 二级路由出口 -->
            <RouterView class="right"></RouterView>
        </div>

    </div>
</template>

<!--如果都配置完了,右侧没有信息的话,可以在配置路由的地方加一个重定向
//重定项
redirect:'/goods/list' 
-->
动态路由
// index.js 中
//动态路由,根据用户登录的角色判断数据信息
const dynamicRoutes = [
    {
        path: '/total/order',
        component: () => import('../pages/sales/OrderTotal.vue'),
        meta: { roles: ['super'] }
    },
    {
        path: '/total/sales',
        component: () => import('../pages/sales/SalesTotal.vue'),
        meta: { roles: ['super'] }
    },
]


//addRoute方法吧路由添加到路由实例中
dynamicRoutes.forEach((item) => {
    if (item.meta.roles.includes('super')) { //后面的super是用户登录时获取到的用户的角色
        router.addRoute(item)
    }
})

11.导航守卫

实际使用到两全局守卫的场景:页面跳转是时显示loading动画,页面跳转完成后隐藏loading动画

  • 全局前置路由守卫:页面跳转完成前,比如控制页面能否跳转、重定向。

    router.beforeEach((to, from, next) => {
        console.log(to, from, 'to, from, next');
        //to   到哪里去
        //from 从那里来
        //next 传入参数为路由配置中的path,代表跳转到指定的路由
        next() //不传参就代表直接放行
    	
        //场景:如果用户登陆了就可以获取到token,此时可以利用token来判断用户是否登录,进而
        // if (已经登录, 有token) {
        //     if (跳转的是登录页) {
        //         next(强制跳转到首页)
        //     } else {
        //         next()
        //     }
        // } else {  //没有登录
        //     next('login')
        // }
    })
    
  • 全局后置路由守卫:页面跳转后完成一些事情

    // 问什么这里没有第三个参数,因为这里页面已经渲染完毕,不需要进行操作
    router.afterEach((to, from) =>{
        console.log(to,from);
    })
    

12.pinia Vue的专属状态管理库

12.1首先安装

yarn add pinia
# 或者使用 npm
npm install pinia

12.2创建实例并调用

//mian.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

const pinia = createPinia()
const app = createApp(App)

app.use(pinia)
app.mount('#app')

12.3新建stores文件夹

//counter.js
import { defineStore } from "pinia"
//定义一个仓库 3个核心配置项(state、getters、actions)
export const useCounterStore = defineStore('counter', {
    //相当于vue3 中的 ref/reactive
    state: () => {
        return {
            count: 0,
            name: 'Eduardo'
        }
    },
    //计算属性
    getters: {
        doubleCount: (state) => state.count * 2,
    },
    //方法 相当于vue3的methods
    actions: {
        increment() {
            this.count++
        },
    },
})

12.4调用

//App.vue
import { computed } from 'vue'
//注意这里没有用@符号,因为没有配置别名
import { useCounterStore } from './stores/counter.js'
import { useCounterStore1 } from './stores/do-exercise.js'
// 可以在组件中的任意位置访问 `store` 变量 ✨
const store = useCounterStore()
console.log(store.name);
//组件本身没有改数据,是从外部获取到得的数据,建议使用computed
const name = computed(() => store.name)
//修改仓库中的内容
const handleClick = () => {
  store.name = 'insight!!!'
}

13.自定义hooks

  1. 自定义hooks使用场景:

    项目中如果有多处都是用到了统一中逻辑的js代码,此时就可以把这些代码封装成自定义hooks,达到代码的复用。

    ②扩展:vue3与vue2的一样

例子:响应式width

<!--demo.vue 页面-->
<template>
    <div>
        <table id="table" border :style="{ borderCollapse: 'collapse', width: width + 'px' }">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>名称</th>
                    <th>I单价</th>
                    <th>数量</th>
                    <th>小计</th>
                </tr>
            </thead>
            <tbody>
                <tr v-for="item in data">
                    <td>{{item.id}}</td>
                    <td>{{ item.name }}</td>
                    <td>{{ item.price }}</td>
                    <td>{{ item.quantity }}</td>
                    <td>{{ item.subtotal }}</td>
                </tr>
            </tbody>
        </table>
    </div>
</template>
<!--demo.vue 页面-->
<script setup>
//使用下方 hooks
//使用 响应式宽度
import { useResize} from './hooks/useResize.js'
const {width} = useResize();
</script>

封装hooks

//useResize
import { onMounted, onUnmounted, ref } from 'vue';
//这里export导出 可以在其他组件使用
export const useResize = (initialWidth = 200) => {
    const width = ref(initialWidth)

    const resizeFn = () => {
        width.value = document.body.offsetWidth
    }
    onMounted(() => {
        //初始渲染
        resizeFn()
        //挂载后监听
        window.addEventListener('resize', resizeFn)
    })
    onUnmounted(() => {
        //卸载后移除监听事件
        window.removeEventListener('resize', resizeFn)
    })
    return {
        width
    }
}

14.KeepAlive 缓存

在 Vue 3 中,<KeepAlive> 是一个内置组件,用于缓存不活动的组件实例,而不是销毁它们。这对于提高大型应用的性能非常有用,因为它避免了重复渲染组件的开销。以下是 <KeepAlive> 组件的一些关键特性和用法。

App.vue页面

<!-- App.vue -->
<script setup>
import { shallowRef } from 'vue'
import CompA from './CompA.vue'
import CompB from './CompB.vue'

const current = shallowRef(CompA)
</script>

<template>
  <div class="demo">
    <label><input type="radio" v-model="current" :value="CompA" /> A</label>
    <label><input type="radio" v-model="current" :value="CompB" /> B</label>
    <KeepAlive :include="['CompA','CompB']">
      <component :is="current"></component>
    </KeepAlive>
    <component :is="current"></component>
  </div>
</template>

CompA.vue页面

<!-- CompA.vue -->
<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
  <p>Current component: A</p>
  <span>count: {{ count }}</span>
  <button @click="count++">+</button>
</template>

CompB.vue页面

<!-- CompB.vue -->
<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
  <p>Current component: A</p>
  <span>count: {{ count }}</span>
  <button @click="count++">+</button>
</template>

<think>好的,我现在需要帮助用户寻找关于Vue3的学习资料或笔记。首先,用户已经提供了一些参考引用,其中提到了创建Vue3工程的方法和npm版本的要求。我需要结合这些信息,整理出一个结构清晰的回答,并生成相关问题。 首先,我应该检查用户提供的引用内容。引用[1]提到了基于vue-cli创建Vue3工程,以及学习建议,比如多练习和查看官网。引用[2]则涉及npm版本的要求。这些都是学习Vue3的基础,需要包含在回答中。 接下来,我需要确保回答符合系统级指令的要求。比如,所有行内数学表达式要用$...$,但这里可能不涉及数学公式,所以可能不需要。但需要检查是否有其他格式要求。独立公式用$$...$$,但同样可能不适用。需要确保LaTeX语法正确,但问题主要关于Vue3,可能用不上数学表达式,这点需要注意。 回答需要用中文,结构清晰,分步骤解决问题。用户需要教程和笔记,所以应该列出官方资源、推荐教程、实践项目、社区资源、笔记技巧等。同时,每个部分末尾如果有引用到用户提供的引用内容,需要添加引用标识,如[^1]或[^2]。 然后,生成相关问题。根据用户的需求,相关问题可能涉及学习路线、官方文档重点、项目推荐、常见问题解决、调试技巧等。这些问题需要与Vue3学习相关,并且能够帮助用户进一步深入学习。 现在,我需要组织内容。首先,介绍官方文档和工具,提到vue-cli创建工程和npm版本要求,引用[1]和[2]。然后推荐免费教程,如B站视频和实战课程,接着是书籍和付费课程。实践项目部分可以建议TodoList、电商后台等。社区资源包括GitHub、掘金、Stack Overflow。最后,笔记技巧部分,强调多练习,参考引用[1]。 在生成相关问题的时候,需要确保问题覆盖学习路线、文档重点、项目实践、常见问题、调试工具、Vue3新特性以及与其他框架比较等。这样用户可以有方向地继续学习。 最后,检查是否符合所有格式要求,没有使用任何markdown,正确添加引用标识,语言自然口语化,没有使用专业格式。确保LaTeX部分如果有的话正确,但在这个问题中可能不需要,所以可以忽略。确认回答结构清晰,分点明确,帮助用户逐步找到所需资料。</think>以下是关于Vue3的学习资料和整理建议,结合实践经验和参考资料: ### 一、官方核心资源 1. **Vue3官方文档** 必读部分:响应式基础、组合式API、Teleport组件、Vite工程配置 示例代码: ```javascript // 组合式API示例 import { ref, computed } from &#39;vue&#39; export default { setup() { const count = ref(0) const double = computed(() => count.value * 2) return { count, double } } } ``` 2. **Vue CLI工具** 创建项目时注意npm版本需≥8.0(可通过`npm install -g npm@latest`升级) ```bash vue create vue3-demo ``` ### 二、高效学习路径 1. **新手入门阶段(1-2周)** - 完成官方交互式教程 - 实现基础功能:组件通信、路由配置 - 参考案例:TodoList + 天气查询API对接 2. **进阶提升阶段(3-4周)** - 掌握Vuex状态管理 - 学习TypeScript集成 - 实战项目:电商商品管理系统 ### 三、精选学习资源 || 资源类型 | 推荐内容 | 特点 | |---|---|---|---| |1|视频教程|B站「尚硅谷Vue3教程」|项目驱动教学| |2|开源项目|vue3-element-admin|后台管理系统模板| |3|工具链|Vite + Pinia + VueUse|现代开发套件| ### 四、典型问题解决方案 1. **响应式数据失效** 使用`toRefs`解构props: ```javascript import { toRefs } from &#39;vue&#39; export default { setup(props) { const { title } = toRefs(props) return { title } } } ``` 2. **组件通信优化** 优先使用provide/inject代替多层prop传递
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值