东营+网站建设,新能源汽车价格趋势,深深圳的网站建设公司,网站内容体系一、为什么要学Vue3 Vue3官网#xff1a;简介 | Vue.js
1. Vue3的优势 2. Vue2选项式API vs Vue3组合式API 示例#xff1a; 二、create-vue搭建Vue3项目
1. 认识create-vue
create-vue是Vue官方新的脚手架工具#xff0c;底层切换到了vite(下一代构建工具)#xff0c;为…一、为什么要学Vue3 Vue3官网简介 | Vue.js
1. Vue3的优势 2. Vue2选项式API vs Vue3组合式API 示例 二、create-vue搭建Vue3项目
1. 认识create-vue
create-vue是Vue官方新的脚手架工具底层切换到了vite(下一代构建工具)为开发提供极速响应。 2. 使用create-vue创建项目
1. 前提环境条件
已安装16.0或更高版本的Node.js
node -v
2. 创建一个Vue应用
npm init vuelatest
这一指令将会安装并执行create-vue
①创建项目 ②安装依赖 ③启动项目 三、熟悉项目目录和关键文件 ①禁用Vue2的插件“Vetur” ②安装Vue3的插件“Vue - Official” 四、组合式API - setup选项
1. setup选项的写法和执行时机 示例
App.vue
script
// setup
// 1. 执行时机比beforeCreate还要早
// 2. setup函数中获取不到this(this是undefined)
export default {setup () {console.log(setup函数, this)},beforeCreate () {console.log(beforeCreate函数)}
}
/scripttemplatediv学习Vue3/div
/template 2. setup选项中写代码的特点 示例
App.vue
script
// setup
// 1. 执行时机比beforeCreate还要早
// 2. setup函数中获取不到this(this是undefined)
// 3. 数据和函数需要在setup最后return才能在模板中应用
// 问题每次都要return好麻烦
// 4. 通过setup语法糖简化代码
export default {setup () {// 数据const message hello Vue3// 函数const logMessage () {console.log(message)}return {message,logMessage}},beforeCreate () {console.log(beforeCreate函数)}
}
/scripttemplate{{ message }}brbutton clicklogMessagelog message/button
/template 3. script setup语法糖 示例
App.vue
script setup
const message this is a message
const logMessage () {console.log(message)
}
/scripttemplate{{ message }}brbutton clicklogMessagelog message/button
/template script setup 语法糖原理 4. 总结
1. setup选项的执行时机
答beforeCreate钩子之前 自动执行。
2. setup写代码的特点是什么
答定义数据 函数然后以对象方式return。
3. script setup解决了什么问题
答经过语法糖的封装更简单的使用组合式API。
4. setup中的this还指向组件实例吗
答指向undefined。 五、组合式API - reactive和ref函数
1. reactive()
作用接受对象类型数据的参数传入并返回一个响应式的对象
核心步骤
1. 从vue包中导入reactive函数
2. 在script setup中执行reactive函数并传入类型为对象的初始值并使用变量接收返回值 示例
App.vue
script setup
// reactive: 接收一个对象类型的数据返回一个响应式的对象
// 问题如果是简单类型怎么办呢
import { reactive } from vue
const state reactive({count: 100
})const setCount () {state.count
}
/scripttemplatedivdiv{{ state.count }}/divbutton clicksetCount1/button/div
/template 2. ref()
作用接收简单类型或者对象类型的数据传入并返回一个响应式的对象
核心步骤
1. 从vue包中导入ref函数
2. 在script setup中执行ref函数并传入初始值使用变量接收ref函数的返回值 示例
App.vue
script setup
// ref: 接收简单类型或复杂类型返回一个响应式的对象
// 本质在原有传入数据的基础上外层包了一层对象包含了复杂类型
// 底层包成复杂类型之后再借助reactive实现的响应式
// 注意点
// 1. 脚本中访问数据需要通过.value
// 2. 在template中value不需要加帮我们拔了一层// 推荐以后声明数据统一用ref 统一了编码规范
import { ref } from vue
const count ref(1)const setCount () {count.value
}
/scripttemplatedivdiv{{ count }}/divbutton clicksetCount1/button/div
/template 3. 总结
1. reactive和ref函数的共同作用是什么
答用函数调用的方式生成响应式数据。
2. reactive vs ref ?
答①reactive不能处理简单类型的数据 ②ref参数类型支持更好但是通过.value访问修改 ③ref函数的内部实现依赖于reactive函数。
3. 在实际工作中推荐使用哪个
答推荐使用ref函数更加灵活统一。 六、组合式API - computed
1. computed计算属性函数
计算属性基本思想和Vue2的完全一致组合式API下的计算属性只是修改了写法。
核心步骤
1. 导入computed函数
2. 执行函数在回调参数中return基于响应式数据做计算的值用变量接收 示例计算属性小案例 App.vue
script setup
// 计算属性
// const 计算属性 computed(() {
// return 计算返回的结果
// })import { ref, computed } from vue// 声明数据
const list ref([1, 2, 3, 4, 5, 6, 7, 8])// 基于list派生一个计算属性从list中过滤出 2
// computedList是一个只读的计算属性
const computedList computed(() {return list.value.filter(item item 2)
})// 创建一个可读的计算属性
const count ref(1)
const plusOne computed({get: () count.value 1,set: (val) {count.value val - 1}
})
plusOne.value 1 // set
console.log(count.value) // 0// 定义一个修改数组的方法
const addFn () {list.value.push(666)
}/scripttemplatedivdiv原始数据{{ list }}/divdiv计算后的数据{{ computedList }}/divbutton clickaddFn typebutton修改/button/div
/template 2. 总结
1. 计算属性中不应有“副作用”
比如异步请求/修改dom
2. 避免直接修改计算属性的值
计算属性应该是只读的特殊情况可以配置get set 七、组合式API - watch
1. watch函数
作用侦听一个或者多个数据的变化数据变化时执行回调函数
两个额外参数①immediate立即执行②deep深度侦听 2. 基础使用 - 侦听单个数据
①导入watch函数
②执行watch函数传入要侦听的响应式数据ref对象和回调函数 3. 基础使用 - 侦听多个数据
说明同时侦听多个响应式数据的变化不管哪个数据变化都需要执行回调函数 示例
App.vue
script setup
import { ref, watch } from vue
const count ref(0)
const nickname ref(张三)const changeCount () {count.value
}const changeNickname () {nickname.value 李四
}// 1. 监视单个数据的变化
// watch(ref对象, (newValue, oldValue) { ... })
// watch(count, (newValue, oldValue) {
// console.log(newValue, oldValue)
// })// 2. 监视多个数据的变化
// watch([ref对象1, ref对象2], (newArr, oldArr) { ... })
watch([count, nickname], (newArr, oldArr) {console.log(newArr, oldArr)
})
/scripttemplatediv{{ count }}/divbutton clickchangeCount改数字/buttondiv{{ nickname }}/divbutton clickchangeNickname改昵称/button
/template 4. immediate
说明在侦听器创建时立即触发回调响应式数据变化之后继续执行回调 示例
App.vue
script setup
import { ref, watch } from vue
const count ref(0)
const nickname ref(张三)const changeCount () {count.value
}const changeNickname () {nickname.value 李四
}// 3. immediate立即执行
watch([count, nickname], (newArr, oldArr) {console.log(newArr, oldArr)
}, {immediate: true
}
)
/scripttemplatediv{{ count }}/divbutton clickchangeCount改数字/buttondiv{{ nickname }}/divbutton clickchangeNickname改昵称/button
/template 5. deep
说明deep深度监视默认watch进行的是浅层级的监视。
示例
script setup
import { ref, watch } from vue
const count ref(0)
const nickname ref(张三)const changeCount () {count.value
}const changeNickname () {nickname.value 李四
}// 4. deep 深度监视默认watch进行的是浅层监视
// const ref1 ref(简单类型) 可以直接监视
// const ref2 ref(复杂类型) 监视不到复杂类型内部数据的变化
const userInfo ref({name: zs,age: 18
})
const setUserInfo () {// 如果userInfo一整个对象的地址没有发生任何变化监视不到// 如果想要对象内部数据的变化也能监视到deep: trueuserInfo.value.age// 修改了userInfo.value 修改了对象的地址才能监视到// userInfo.value {name: ls, age: 20}
}watch(userInfo, (newValue) {console.log(newValue)
}, {deep: true
})/scripttemplatediv{{ count }}/divbutton clickchangeCount改数字/buttondiv{{ nickname }}/divbutton clickchangeNickname改昵称/buttondiv--------------------------------------/divdiv{{ userInfo }}/divbutton clicksetUserInfo修改userInfo/button
/template 6. 精确侦听对象的某个属性
需求在不开启deep的前提下侦听age的变化只有age变化时才执行回调 示例
App.vue
script setup
import { ref, watch } from vue
const count ref(0)
const nickname ref(张三)const changeCount () {count.value
}const changeNickname () {nickname.value 李四
}const userInfo ref({name: zs,age: 18
})
const setUserInfo () {userInfo.value.age
}// 5. 对于对象中的属性进行监视
watch( () userInfo.value.age, (newValue, oldValue) {console.log(newValue, oldValue)}
)
/scripttemplatediv{{ count }}/divbutton clickchangeCount改数字/buttondiv{{ nickname }}/divbutton clickchangeNickname改昵称/buttondiv--------------------------------------/divdiv{{ userInfo }}/divbutton clicksetUserInfo修改userInfo/button
/template 7. 总结
1. 作为watch函数的第一个参数 ref对象需要添加.value吗
答不需要第一个参数就是传ref对象
2. watch只能侦听单个数据吗
答单个 或 多个
3. 不开启deep直接监视复杂类型修改属性能触发回调吗
答不能默认是浅层侦听
4. 不开启deep精确侦听对象的某个属性
答可以把第一个参数写成函数的写法返回要监听的具体属性 八、组合式API - 生命周期函数
1. Vue3的生命周期API选项式 VS 组合式
选项式API组合式APIbeforeCreate / createdsetupbeforeMountonBeforeMountmountedonMountedbeforeUpdateonBeforeUpdateupdatedonUpdatedbeforeUnmountonBeforeUnmountunmountedonUnmounted
示例
script setup
import { onMounted } from vue;// beforeCreate和created的相关代码一律放在setup中执行
const getList () {setTimeout(() {console.log(发送请求获取数据)}, 2000)
}
// 一进入页面的请求
getList()// 如果有些代码需要在mounted生命周期中执行
onMounted(() {console.log(mounted生命周期函数 - 逻辑1)
})// 写成函数的调用方式可以调用多次并不会冲突而是按照顺序依次执行
onMounted(() {console.log(mounted生命周期函数 - 逻辑2)
})
/scripttemplatediv/div
/template 九、组合式API - 父子通信
1. 组合式API下的父传子
基本思想
1. 父组件给子组件绑定属性
2. 子组件内部通过props选项接收 defineProps原理就是编译阶段的一个标识实际编译器解析时遇到后会进行编译转换 示例
App.vue
script setup
// 父传子
// 1. 父组件给子组件绑定属性
// 2. 子组件内部通过props选项接收// 局部组件导入进来就能用
import SonCom from /components/son-com.vueimport { ref } from vue
const money ref(10000)const getMoney () {money.value 5000
}
/scripttemplatedivh3父组件 - {{ money }}button clickgetMoney挣钱/button/h3!-- 给子组件添加属性的方式传值 --SonCom car宝马 :moneymoney/SonCom/div
/template
components/son-com.vue
script setup
// 子组件
// 由于写了setup所以无法直接配置props选项
// 所以此处需要借助于“编译器宏”函数接收子组件传递的数据
const props defineProps({car: String,money: Number
})
console.log(props.car)
console.log(props.money)
/scripttemplate!-- 对于props传递过来的数据模板中可以直接使用 --div classson我是子组件 - {{ car }} - {{ money }}/div/templatestyle scoped
.son {border: 1px solid #000;padding: 30px;
}
/style 2. 组合式API下的子传父
基本思想
1. 父组件中给子组件标签通过绑定事件
2. 子组件内部通过emit方法触发事件 示例
App.vue
script setup
// 父传子
// 1. 父组件给子组件绑定属性
// 2. 子组件内部通过props选项接收// 子传父
// 1. 在子组件内部通过emit触发事件编译器宏获得
// 2. 在父组件中通过监听// 局部组件导入进来就能用
import SonCom from /components/son-com.vueimport { ref } from vue
const money ref(10000)const getMoney () {money.value 5000
}const changeFn (newMoney) {money.value newMoney
}
/scripttemplatedivh3父组件 - {{ money }}button clickgetMoney挣钱/button/h3!-- 给子组件添加属性的方式传值 --SonCom changeMoneychangeFncar宝马 :moneymoney/SonCom/div
/template
son-com.vue
script setup
// 子传父
// 由于写了setup所以无法直接配置props选项
// 所以此处需要借助于“编译器宏”函数接收子组件传递的数据
const props defineProps({car: String,money: Number
})
console.log(props.car)
console.log(props.money)const emit defineEmits([changeMoney])
const buy () {// 需要emit触发事件emit(changeMoney, props.money - 500)
}/scripttemplate!-- 对于props传递过来的数据模板中可以直接使用 --div classson我是子组件 - {{ car }} - {{ money }}button clickbuy花钱/button/div/templatestyle scoped
.son {border: 1px solid #000;padding: 30px;
}
/style 3. 总结
父传子
1. 父传子的过程中通过什么方式接收props
答defineProps({属性名: 类型})
2. setup语法糖中如何使用父组件传过来的数据
答const props defineProps({属性名: 类型}) props.xxx
子传父
1. 子传父的过程中通过什么方式得到emit方法
答defineEmits([事件名称])
2. 怎么触发事件
答emit(自定义事件名, 参数) 十、 组合式API - 模板引用
1. 模板引用的概念
通过ref标识获取真实的dom对象或者组件实例对象 2. 如何使用以获取dom为例 组件同理 3. defineExpose()
默认情况下在script setup语法糖下组件内部的属性和方法是不开放给父组件访问的可以通过defineExpose编译宏指定哪些属性和方法允许访问。 示例
App.vue
script setup
import TestCom from ./components/test-com.vue
import { onMounted, ref } from vue// 模板引用可以获取dom也可以获取组件
// 1. 调用ref函数生成一个ref对象
// 2. 通过ref标识进行绑定
// 3. 通过ref对象.value即可访问到绑定的元素必须渲染完成后才能拿到
const inp ref(null)// 生命周期钩子 onMounted
onMounted(() {// console.log(inp.value)// inp.value.focus()
})
const clickFn () {inp.value.focus()
}const testRef ref(null)
const getCom () {console.log(testRef.value.count)testRef.value.sayHi()
}/scripttemplatedivinput refinp typetextbutton clickclickFn点击让输入框聚焦/button/divTestCom reftestRef/TestCombutton clickgetCom获取组件/button
/template
test-com.vue
script setup
const count 999
const sayHi () {console.log(打招呼)
}defineExpose({count,sayHi
})
/scripttemplatediv我是用于测试的组件 - {{ count }}/div
/template 4. 总结
1. 获取模板引用的时机是什么
答组件挂载完毕
2. defineExpose编译宏的作用是什么
答显示暴露组件内部的属性和方法 十一、组合式API - provide和inject
1. 作用和场景
顶层组件向任意的底层组件传递数据和方法实现跨层组件通信 2. 跨层传递普通数据
1. 顶层组件通过provide函数提供数据
2. 底层组件通过inject函数获取数据 3. 跨层级传递响应式数据
在调用provide函数时第二个参数设置为ref对象。 4. 跨层级传递方法
顶层组件可以向底层组件传递方法底层组件调用方法修改顶层组件中的数据 示例
App.vue 父组件
script setup
import CenterCom from ./components/center-com.vue
import { provide, ref } from vue;// 1. 跨层传递普通数据
provide(theme-color, pink)// 2. 跨层传递响应式数据
const count ref(100)
provide(count, count)setTimeout(() {count.value 666
}, 2000)// 3. 跨层级传递函数 给子孙后代传递可以修改数据的方法
provide(changeCount, (newCount) {count.value newCount
})/scripttemplatedivh1我是顶层组件/h1CenterCom/CenterCom/div
/template
center-com.vue 子组件
script setup
import BottomCom from ./bottom-com.vue/scripttemplatedivh2我是中间组件/h2BottomCom/BottomCom/div
/template
bottom-com.vue 孙组件
script setup
import { inject } from vue;const themeColor inject(theme-color)
const count inject(count)
const changeCount inject(changeCount)const clickFn () {changeCount(888)
}
/scripttemplatedivh3我是底层组件 - {{ themeColor }} - {{ count }}/h3button clickclickFn更新count/button/div
/template 十二、Vue3.3新特性 - defineOptions
1. 背景说明 有script setup之前如果要定义propsemits可以轻而易举地添加一个setup平级的属性。但是用了script setup后就没法这么干了setup属性已经没有了自然无法添加与其平级的属性。 为了解决这一问题引入了 defineProps 与 defineEmits这两个宏。但这只解决了props与emits这两个属性。如果我们要定义组件的name或其他自定义的属性还是得回到最原始的用法——再添加一个普通的script标签。这样就会存在两个script标签让人无法接受。 所以在Vue3.3中新引入了defineOptions宏。顾名思义主要是用来定义Options API的选项。可以用defineOptions定义任意的选项propsemitsexposeslots除外因为这些可以使用defineXXX来做到。 示例
src/views/login/index.vue
script setup
defineOptions({name: LoginIndex
})
/scripttemplatediv我是登录页/div
/template 十三、Vue3.3新特性 - defineModel
Vue3中的v-model和defineModel
在Vue3中自定义组件上使用v-model相当于传递一个modelValue属性同时触发update:modelValue事件 之前我们需要先定义props再定义emits。其中有许多重复的代码。如果需要修改此值还需要手动调用emit函数。 示例
App.vue
script setup
import MyInput from ./components/my-input.vue;
import { ref } from vueconst txt ref(123456)/scripttemplatedivMyInput v-modeltxt/MyInput{{ txt }}/div
/template
my-input.vue
script setup
import { defineModel } from vue
const modelValue defineModel()
/scripttemplate
divinput typetext :valuemodelValue inpute modelValue e.target.value
/div
/template