vue3笔记

目录

一、使用vite创建项目

二、常用的Composition Api(组合式api)

1. setup

2. ref函数

2.1 ref将普通数据变成响应式数据

2.2 用来获取dom(vue2的$ref)

3. reactive函数

4. props

5. emit(书写自定义事件)

6. computed计算属性

7. watch 监听器

7.1 使用vue2写法

7.2 vue3写法(5种情况)

8. watchEffect

9. 生命周期

10. 自定义hook

11. toRef 和 toRefs

三、其他Composition Api

1. customRef

2. provide 与 inject

3. 响应式数据的判断

四、异步引入组件

五、其他

1. 全局api


一、使用vite创建项目

npm init vite -y
// package.json
"scripts": {
  "dev": "vite", // 项目启动
  "build": "vue-tsc && vite build", // 项目打包
  "preview": "vite preview" // 项目预览(打包后的,需要先执行 npm run build 才行)
},
// 项目依赖
"dependencies": {
  "vue": "^3.2.47"
},
// 开发依赖
"devDependencies": {
  "@vitejs/plugin-vue": "^4.1.0",
  "typescript": "^5.0.2",
  "vite": "^4.3.9",
  "vue-tsc": "^1.4.2"
}

在npm run dev的时候,不会显示局域网地址

  VITE v4.3.9  ready in 1006 ms

  ➜  Local:   http://127.0.0.1:5173/
  ➜  Network: use --host to expose
  ➜  press h to show help

需要在scripts的dev中加入--host

"scripts": {
  "dev": "vite --host", // 这里添加
  "build": "vue-tsc && vite build",
  "preview": "vite preview"
},

二、常用的Composition Api(组合式api)

1. setup

1. 组件中所用到的数据、方法等,均要配置在setup中。
2. setup函数的两种返回值:
	1. 若返回一个对象,则对象中的属性、方法,在模版中均可以直接使用。
	2. 若返回一个渲染函数;则可以自定义渲染内容。(了解)
3. setup执行时机在beforeCreate之前执行,this为undefined
4. setup可以接受两个参数,参数1:props(响应式数据) 参数2:context(上下文对象)

setup(props, context)

// 具体看第4、5点
props:需要通过props接受(和vue2相同)才能获取props
context: 	attrs: Proxy(Object) // props未接收的数据,会出现在attrs中
		    emit: (event, ...args) => instance.emit(event, ...args)
			expose: (exposed) => {…}
			slots: Proxy(Object)
<script>
export default {
  setup(props, context) {
    // 透传 Attributes(非响应式的对象,等价于 $attrs)
    console.log(context.attrs)

    // 插槽(非响应式的对象,等价于 $slots)
    console.log(context.slots)

    // 触发事件(函数,等价于 $emit)
    console.log(context.emit)

    // 暴露公共属性(函数)
    console.log(context.expose)
  }
}
</script>

2. ref函数

2.1 ref将普通数据变成响应式数据

通过 .value 来获取值

基本数据类型

<template>
  <div>
    <p>{{ name }}{{ age }}</p>
    <button @click="changeInfo">按钮</button>
  </div>
</template>

<script>
import { ref } from "vue";
export default {
  setup() {
    // 数据
    let name = ref('xiaotian');
    let age = ref(19);

    // 方法
    function changeInfo() {
      name.value = 'wifi';
      age.value = 20
    }

    return {
      name, age, changeInfo
    }
  }
}
</script>

引用数据类型

<template>
  <div>
    <p>name:{{ obj.name }}</p>
    <p>age:{{ obj.age }}</p>
    <button @click="changeInfo">按钮</button>
  </div>
</template>

<script>
import { ref } from "vue";
export default {
  setup() {
    const obj = ref({
      name: 'xiaotian',
      age: 19
    })

    const changeInfo = () => {
      obj.value.name = 'wifi'
      obj.value.age = 20
    }

    return {
      obj, changeInfo
    }
  }
}
</script>

2.2 用来获取dom(vue2的$ref)

<template>
  <div>
    <p ref="pDom">这是一个p标签</p>
  </div>
</template>

<script>
import { ref, onMounted } from "vue";
export default {
  setup() {
    const pDom = ref()
    onMounted(() => {
      // pDom是一个ref对象
      console.log(pDom.value);
    })

    return {
      pDom // 返回的pDom要和模版中ref绑定的名字要相同
    }
  }
}
</script>

3. reactive函数

用来定义引用数据类型的响应式,获取数据不用 .value

<template>
  <div>
    <p>name:{{ obj.name }}</p>
    <p>age:{{ obj.age }}</p>
    <button @click="changeInfo">按钮</button>
  </div>
</template>

<script>
import { reactive } from "vue";
export default {
  setup() {
    const obj = reactive({
      name: 'xiaotian',
      age: 19
    })

    const changeInfo = () => {
      obj.name = 'wifi'
      obj.age = 20
    }

    return {
      obj, changeInfo
    }
  }
}
</script>

4. props

<!-- 父组件 -->
<template>
	<Son msg="hello"/>
</template>

<!-- 子组件 -->
<template>
	<div></div>
</template>

<script>
export default {
  props: ['msg'],
	setup(props, context) {
    	console.log(props) // Proxy(Object) {msg: 'hello'}
  }
}
</script>

5. emit(书写自定义事件)

<!-- 子组件 -->
<template>
  <div>
    <button @click="handleClick">点击触发自定义事件</button>
  </div>
</template>

<script>
export default {
  // 要将自定义事件名声明一下
  emits: ['hello'],
  setup(props, context) {
    const handleClick = () => {
      context.emit('hello', '我是子组件')
    }
    return { handleClick }
  }
}
</script>

<!-- 父组件 -->
<template>
  <div>
  <Son @hello="handleHello" msg="Vite + Vue" />
</template>

<script>
import Son from './components/Son.vue'
export default {
  components: {
    Son
  },
  setup() {
    const handleHello = (data) => {
      console.log(data);
    }

    return { handleHello }
  }
}
</script>

6. computed计算属性

<script>
import { reactive, computed } from 'vue';
export default {
  setup() {
    let person = reactive({
      firstName: 'xiao',
      lastName: 'tian'
    })
    // 计算属性 简写形式(没有考虑计算属性被修改的情况)
    person.fullName = computed(() => {
      return person.firstName + '-' + person.lastName
    })
     // 计算属性 完整写法
    person.fullName = computed({
      get() {
        return person.firstName + '-' + person.lastName
      },
      set(val) {
        const newArr = val.split('-')
        person.firstName = newArr[0]
        person.lastName = newArr[1]
      }
    })

    return { person }
  }
}
</script>

7. watch 监听器

7.1 使用vue2写法

<script>
import { ref } from 'vue';
export default {
  setup() {
    let num = ref(0)
    return { num }
  },
  watch: {
    // 简单写法
    num(newVal, oldVal) {
      console.log(newVal, oldVal);
    }
    // 完整写法
    num: {
      handler(newVal, oldVal) {
        console.log(newVal, oldVal);
      }
    }
  }
}
</script>

7.2 vue3写法(5种情况)

1. ref定义的响应式数据,如果是基本数据类型,则watch不需要.value, 如果是引用数据类型就可以开启deep深度监听
2. 当数据嵌套比较深的时候,需要开启deep

8. watchEffect

<script>
import { reactive, ref, watchEffect } from 'vue';
export default {
  setup() {
    let num = ref(0)
    let person = reactive({
      name: 'xiaotian',
      age: 19,
      a: {
        b: {
          c: 1
        }
      }
    })
    watchEffect(() => {
      // 一加载完就会执行一次,监视回调中用到的响应式数据,深层数据也能监听到
      console.log('watchEffect', num.value);
      console.log('watchEffect', person.a.b.c);
    })
    // watchEffect返回的是一个停止侦听函数,可以调用它来停止副作用代码的执行。
    const stop = watchEffect(() => {
      // ...
    })
    stop()

    return { num, person }
  }
}
</script>

9. 生命周期

配置项写法

<script>
export default {
  // 配置项写法
  beforeCreate() {
  },
  created() {
  },
  beforeMount() {
  },
  mounted() {
  },
  beforeUpdate() {
  },
  updated() {
  },
  beforeUnmount() {
    // vue3已经不是beforeDestroy,改为beforeUnmount
  },
  unmounted() {
    // vue3已经不是destroyed,改为unmounted
  }
}
</script>

组合式api(在setup中写)

beforeCreate => setup()
created => setup()
beforeMount => onBeforeMount()
mounted => onMounted()
beforeUpdate => onBeforeUpdate()
updated => onUpdated()
beforeUnmount => onBeforeUnmount()
unmounted => onUnmounted()

10. 自定义hook

将需要复用的逻辑抽离出来

// hooks/usePoint.js
import { reactive, onMounted, onBeforeUnmount } from 'vue';

export default () => {
    let point = reactive({
        x: 0,
        y: 0
    })
    
    const savePoint = (e) => {
        point.x = e.pageX
        point.y = e.pageY
    }
    
    onMounted(() => {
        window.addEventListener('click', savePoint)
    })
    
    onBeforeUnmount(() => {
        window.removeEventListener('click', savePoint)
    })

    return point
}
<template>
  <div>
   <p>x: {{ point.x }}</p>
   <p>y: {{ point.y }}</p>
  </div>
</template>

<script>
import savePoint from '../hooks/usePoint'
export default {
  setup() {
    const point = savePoint()

    return { point }
  }
}
</script>

11. toRef 和 toRefs

<template>
  <div>
    num: {{ num }}
    <button @click="num++">num++</button>
  </div>
</template>

<script>
import { reactive } from 'vue';
export default {
  setup() {
    const obj = reactive({
      num: 10
    })
    return {
      num: obj.num // 这样会导致数据丢失响应式,所以需要对象数据的某个响应式,就需要用到toRef
    }
  }
}
</script>

toRef:创建一个 ref 对象,其value值指向另一个对象中的某个属性。语法:const name = toRef(person, 'name')。就是将不是ref的数据变成ref数据

<template>
  <div>
    num: {{ num }}
    <button @click="num++">num++</button>
  </div>
</template>

<script>
import { reactive, toRef } from 'vue';
export default {
  setup() {
    const obj = reactive({
      num: 10
    })

    let num = toRef(obj, 'num')

    return {
      num
    }
  }
}
</script>

toRefs

<template>
  <div>
    num: {{ num }}
    <button @click="num++">num++</button>
  </div>
</template>

<script>
import { reactive, toRefs } from 'vue';
export default {
  setup() {
    const obj = reactive({
      num: 10,
      str: 'hello'
    })

    return {
      ...toRefs(obj)
    }
  }
}
</script>

三、其他Composition Api

1. customRef

  • 作用:创建一个自定义的ref,并对其依赖项跟踪和更新出啊发进行显示控制。

  • 写法:

<template>
  <input type="text" v-model="keyword">
  <h3>{{ keyword }}</h3>
</template>

<script>
import { customRef } from 'vue';
export default {
  setup() {
    // let keyword = ref('hello'); // 使用vue提供的ref
    // 自定义的ref:myRef
    function myRef(val) {
      return customRef((track, trigger) => {
        // customRef的回调函数必须返回一个对象
        return {
          get() {
            track(val) // 第三步:通知vue,追踪val数据的变化
            return val
          },
          set(newVal) {
            val = newVal  // 第一步
            trigger() // 第二步通知vue去重新解析模板
          }
        }
      })
    }
    let keyword = myRef('hello'); // 使用自定义的ref
    return { keyword }
  }
}
</script>
  • 实现防抖效果:

<script>
import { customRef } from 'vue';
export default {
  setup() {
    function myRef(val) {
      let timer = null;
      return customRef((track, trigger) => {
        return {
          get() {
            track(val)
            return val
          },
          set(newVal) {
            clearInterval(timer);
            timer = setTimeout(() => {
              val = newVal
              trigger()
            }, 1000)
          }
        }
      })
    }
    let keyword = myRef('hello');
    return { keyword }
  }
}
</script>

2. provide 与 inject

  • 作用:实现祖孙组件间的通信,数据是响应式的

  • 用法:父组件有一个provide来提供数据,子组件有一个inject来使用数据

3. 响应式数据的判断

  • isRef:检查一个值是否为一个ref对象

  • isReactive:检查一个对象是否是由reactive创建的响应式代理

四、异步引入组件

  • defineAsyncComponent 和 Suspense组件

<template>
  <Suspense>
    <!-- 加载完成展示的内容 -->
    <template v-slot:default>
      <Child/>
    </template>
    <!-- 加载中展示的内容 -->
    <template v-slot:fallback>
      <div>加载中...</div>
    </template>
  </Suspense>
</template>

<script>
import { defineAsyncComponent } from 'vue';
const Child = defineAsyncComponent(() => import('./Child.vue'))
export default {
  components: {
    Child
  }
}
</script>

五、其他

1. 全局api

vue2 ===> vue3
Vue.config.xxx ===> app.config.xxx
Vue.component ===> app.component
Vue.mixin ===> app.mixin
Vue.use ===> app.use
Vue.prototype ===> app.config.globalProperties
### 关于 Vue3 学习笔记和教程 Vue 是一个流行的前端框架,用于构建交互式的用户界面。以下是有关 Vue3 的学习资源以及如何设置开发环境的相关信息。 #### 1. 安装 Vue CLI 并创建 Vue3 项目 为了快速上手 Vue3,可以使用官方推荐的工具 `vue-cli` 来初始化一个新的项目。安装 Vue CLI 需要 Node.js 和 npm 支持。运行以下命令来全局安装 Vue CLI: ```bash npm install -g @vue/cli ``` 接着可以通过以下命令创建新的 Vue3 项目[^1]: ```bash vue create my-vue3-project ``` 在创建过程中可以选择 Vue3 版本作为默认选项。 --- #### 2. 使用 CDN 方式引入 Vue3 进行初步体验 如果不想立即配置本地开发环境,可以直接通过 HTML 文件中的 `<script>` 标签加载 Vue3 的 CDN 资源来进行简单的实验。例如,在 HTML 中加入以下代码即可开始编写第一个 Vue 应用程序[^2]: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue3 Example</title> <!-- 引入 Vue3 --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="app">{{ message }}</div> <script> const app = { data() { return { message: &#39;Hello, Vue3!&#39; } } } Vue.createApp(app).mount(&#39;#app&#39;) </script> </body> </html> ``` 上述代码展示了如何利用 Vue3 实现数据绑定功能。 --- #### 3. 组件间通信:v-model 在 Vue3 中的应用 对于更复杂的场景,比如父子组件之间的双向数据绑定,Vue3 提供了增强版的 `v-model` 功能。下面是一个典型的例子,展示父组件向子组件传递值并接收更新的过程[^3]: **父组件** ```javascript <script setup> import MyInput from &#39;./components/MyInput.vue&#39; import { ref } from &#39;vue&#39; const txt = ref(&#39;初始文本&#39;) </script> <template> <MyInput v-model="txt" /> <p>{{ txt }}</p> </template> ``` **子组件 (MyInput.vue)** ```javascript <script setup> defineProps([&#39;modelValue&#39;]) defineEmits([&#39;update:modelValue&#39;]) </script> <template> <input :value="modelValue" @input="$emit(&#39;update:modelValue&#39;, $event.target.value)" /> </template> ``` 此示例说明了 Vue3 如何支持自定义事件名称前缀(如 `update:`),从而实现更加灵活的数据同步机制。 --- #### 4. 推荐的学习资料 除了以上提到的内容外,还有许多优秀的在线课程可以帮助深入理解 Vue3 技术栈。其中包括但不限于以下几个方面: - **尚硅谷 Vue2.0+Vue3.0 全套教程**: 结合实际案例讲解核心概念和技术要点。 - **黑马程序员 Vue3 学习笔记**: 主要针对初学者设计,适合零基础入门者阅读。 - **官方文档**: https://v3.vuejs.org/guide/introduction.html —— 最权威且详尽的技术指南。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值