VUE 3.0 初体验之路
在2020年9月中旬,vue.js发布了3.0正式版,在不久的将来,VUE3.0 也终将成为大前端的必然趋势,
环境搭建
node
版本要求:Node.js8.9
或更高版本 ,输入node -v
查看node版本vue-cli
版本:达到vue-cli4.5.0
以上,可创建vue3.0的项目,支持体验vue3.0的新特性,(3.x Preview)
,vue -V
查看脚手架版本终端输入:
vue create project_name
核心知识
一 、组件的定义和使用
组件:是维护单一功能,可复用的单个个体,相同的样式及逻辑即可抽离成组件,方便维护,复用性增强。也是vue3.0项目中,最核心的概念
defineComponent
:vue3.0中提供了一个函数返回传递给它的对象,最重要的是:在TypeScript下,给予了组件 正确的参数类型推断 。此处先不展开介绍,后续会总结 vue3.0 + ts。
setup
:组件的启动函数,两个参数: props(父组件传递的数据)
,content ( 上下文对象)
,最后return 定义的数据,方法,钩子函数等,且setup中 没有this,不能访问this
<script>
import { defineComponent } from 'vue'
export default defineComponent ({
setup (props, content) {
// TODO 数据,方法,钩子函数等
return { }
}
})
</script>
二、数据的定义和使用
ref
:定义单个数据
,接受一个参数值并返回一个响应式且可改变的ref 对象
。ref 对象拥有一个指向内部值的单一属性.value
。
import { ref } from 'vue'
export default {
setup () {
let num1 = ref(10) // Number
let name1 = ref('Echoyya') // String
let arr1 = ref(['a','d','c','d']) // Array
let obj1 = ref({age:20}) // Object
// 获取及改变 ref对象的值,获取内部值的单一属性 value
console.log(num1.value) // 10
num1.value++
console.log(num1.value) // 11
return {
//使用 ref 定义的数据,需要直接 return
num1,name1,arr1,obj1
}
}
}
reactive
: 用于创建响应式数据,接收一个普通对象然后返回该普通对象的响应式代理
,即双向数据绑定,使用 reactive 定义的数据,不需要逐一 return,可以使用 ES6 的扩展运算符。
解构会破坏双向数据绑定的特性, 变更为单向数据绑定
解决:vue3.0中添加了新特性,可对当前的数据进行转换。将其转换为响应式数据,
toRefs
将数据包裹即可转换为响应式数据
import { reactive, toRefs } from 'vue'
export default {
setup () {
let data = reactive ({
num:33,
arr:['a','d','c','d'],
obj:{age:20},
})
// 获取及改变:reactive 定义的数据,调用时直接 reactive变量名.数据名,
console.log(data.num) // 33
data.num++
console.log(data.num) // 34
return {
...toRefs(data)
}
}
}
三、方式的定义和使用
创建的方法仍然需要 return
<template>
<div>
<p><button @click="clickNum">{{num}}</button></p>
<p><button @click="clickNum1">{{num1}}</button></p>
<p><button @click="singleMethod">{{name}}</button></p>
</div>
</template>
<script>
import { reactive, ref, toRefs } from 'vue'
export default {
setup () {
let num1 = ref(10)
let name = ref('Echoyya')
let data = reactive({
num:33,
})
// 定义多个方法,不需要逐一 return
let methods = {
clickNum1: () => {
num1.value++
console.log(num1.value);
},
clickNum : () => {
data.num ++
console.log(data.num);
}
}
// 定义单个方法,需要return
let singleMethod = () => {
console.log(name.value)
}
return {
num1,
name,
singleMethod,
...toRefs(data)
...methods,
}
}
}
</script>
四、路由的定义、使用和传参
- /src/router/index.js:在路由文件中使用了
createRouter
方法
import { createRouter } from 'vue-router'
const routes = [
{
path: '/',
name: 'Home',
component: () => import('../views/Home.vue')
},
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue')
}
]
const router = createRouter({
routes
})
export default router
- home组件中使用,路由跳转及传递参数
<template>
<div>
<p><button @click="gotoQuery">query跳转</button></p>
<p><button @click="gotoParams">params跳转</button></p>
</div>
</template>
<script>
import { useRouter } from 'vue-router'
export default {
setup (){
// router对象是全局路由的实例。
let router = useRouter()
// 跳转路由用push: 跳转时可使用name 和 path,传递参数可使用query 和 params
let gotoQuery = () => {
// query: 可以使用name和path,参数显示在地址栏中, 且页面刷新参数仍在
router.push({
// name:'About',
path:'/about',
query:{
name:'Echoyya',
age: 25,
obj:JSON.stringify({gender:"f"})
},
})
}
let gotoParams = () => {
// params:只能使用name ,不显示在地址栏中,且页面刷新,参数清空 console.log(route.params); 打印空对象
router.push({
name:'Home',
params:{
name:'Echoyya',
age: 25,
obj:JSON.stringify({gender:"f"})
}
})
}
return {
gotoQuery,
gotoParams
}
}
}
- about组件中使用,接收路由参数
import { useRoute } from 'vue-router'
export default {
setup (){
// route对象表示当前的路由信息,包含了当前 URL 解析得到的信息。包含当前的路径,参数,query对象等。
let route = useRoute()
console.log(typeof route.query.age) //string, query传递的参数都是string类型
console.log(route.query); //获取query传参
console.log(route.params); //获取params传参
return {}
}
}
五、父子组件传值
父 to 子
:通过动态绑定属性
的方式,子组件在props
中去接收,子 to 父
:通过ctx.emit('事件名称', 传递的参数)事件分发
的方式, 父组件当中,调用子组件标签上绑定自定义事件,其中包含一个参数,即子组件传递过来的数据ctx.emit('事件名称', 传递的参数)事件分发
, ctx是 setup 函数的第二个参数,上下文对象emit 只能接受两个参数,其余不生效,第一个参数:事件名称,第二个: 传递的数据
事件分发,不一定要通过点击事件,也可使用钩子函数等
需要传递多个参数时,emit第二个参数可选择数组或是对象
father.vue
<template>
<div class="wrapper">
<p>this is father components</p>
<p> 子组件传递的值:{{childMsg}}</p>
<!-- msg 自定义属性,send 自定义监听事件-->
<p><child :msg="msg" @send="getChildData"></child></p>
</div>
</template>
<script>
import { ref } from 'vue'
import child from '../components/child'
export default {
components:{
child
},
setup() {
let msg = ref('father组件数据')
let childMsg = ref('')
let getChildData = (data)=>{
childMsg.value = data
}
return {
msg,
childMsg,
getChildData
}
},
}
</script>
child.vue
<template>
<div>
this is child components
<p>父组件传递过来的值:{{msg}}</p>
<p><button @click="send">传值给父组件</button></p>
</div>
</template>
<script>
import {ref,onMounted, reactive} from 'vue'
export default {
name:'child',
// props 接收的数据,不能直接修改,如props.xxx = yy
props:{
msg:{
type:String , // 数据类型校验
require:true , // 是否必传 默认false
default:'默认值' // require和default 有些冲突,即必填时,可不设置默认值
}
},
setup(props,ctx){
console.log(props.msg); // 父组件传递的数据:father组件数据
let childMsg = ref('child组件数据')
let data = reactive({
childNum:10
})
let send = ()=>{
ctx.emit('send',childMsg.value)
// ctx.emit('send',[childMsg.value,data.childNum]) // 数组
// ctx.emit('send',{ // 对象
// msg:childMsg.value,
// num:data.childNum
})
}
return {
childMsg,
send,
...data
}
}
})
</script>
六、状态管理的定义和使用
状态管理即 VUEX
,为达到数据共享的目的
- /src/store/index.js:在状态管理文件中使用了
createStore
方法
import { createStore } from 'vuex'
export default createStore({
// 定义所需要的状态
state: {
name: 'Echoyya',
},
// 同步修改state ,是方法,不能操作异步操作(包括发送请求及定时器等)
mutations: {
// 可接收两个参数:一:state,二:需修改的值,payload(可选)
setName(state, payload) {
state.name = payload
},
},
// 提交 mutations
actions: {
// 可接收两个参数 一:store, 二 要修改的值
asyncSetName(store, params) {
setTimeout(() => {
// commit 是提交mutation, 提交异步的mutations方法
store.commit('setName', params)
console.log(store.state.name)
}, 2000)
}
},
// 模块化
modules: {}
})
- 组件中调用,VUEX操作数据
<template>
<div>
{{name}}===={{name1}}===={{name2}}
<p><button @click="setName">设置 name</button></p>
<p><button @click="asyncSetName">异步设置 name</button></p>
</div>
</template>
<script>
import { reactive, ref, toRefs, computed } from 'vue'
import { useStore } from 'vuex'
export default {
setup (){
//通过 ref 方式
let name = ref(store.state.name)
// 计算属性 方式
let name1 = computed(()=>{
return store.state.name + 'computed'
})
//reactive 方式
let data = reactive({
name2:store.state.name + '_reactive'
})
// 触发 mutations
let setName = ()=>{
console.log(store.state.name) // Echoyya
store.commit('setName','nhyya')
console.log(store.state.name) // nhyya
}
// 触发 action
let asyncSetName = ()=>{
store.dispatch('asyncSetName','nhyya1212')
}
return {
name,
name1,
...toRefs(data),
setName,
asyncSetName
}
}
})
</script>
七、常用的生命周期
setup:不需要引入的生命周期 ,表示组件创建的过程,且没有this
onMounted:比
setup
稍微晚一些执行,表示组件挂载的过程,包括数据, dom元素等,是一个函数,需要传入一个回调函数执行,无参数。- 常用于:发送请求、数据初始化的操作、接受路由传递的参数
onUnmounted:与
onMounted
相对应,组件卸载或销毁(路由跳转),常用于清除定时器等操作
较 VUE2.0 另有哪些改变?
3.0去掉了filter, 没有beforeCreate created,用setup取代
setup里没有this
3.0兼容IE12以上
可直接监听数组类型的数据变化
监听的目标为对象本身,不需要像Object.defineProperty一样遍历每个属性,有一定的性能提升
直接实现对象属性的新增/删除
重构 Virtual DOM:模板编译时的优化,将一些静态节点编译成常量
另附上vue3.0 文档地址: https://v3.cn.vuejs.org/
上述内容并非全部 VUE3 内容,只是我通过一段时间的学习,做的自我总结,以便学习和复习,写的不准确之处还望大神们能留言指正
VUE 3.0 初体验之路的更多相关文章
- vue组件化初体验 全局组件和局部组件
vue组件化初体验 全局组件和局部组件 vue组件化 全局组件 局部组件 关于vue入门案例请参阅 https://www.cnblogs.com/singledogpro/p/11938222.h ...
- MySQL8.0初体验
MySQL8.0的官方社区开源版出来有段时间了,而percona的8.0版本还没有正式对外发布(已发布测试版),一直以来也没安装体验下这个号称质的飞跃的版本,今天正好有些时间就下了安装体验体验. 一. ...
- Vue3.0初体验
最近看了Vue3.0的相关信息,相比Vue2.0有以下优点: Performance:性能更比Vue 2.0强. Tree shaking support:可以将无用模块"剪辑", ...
- vue-cli3.0 初体验
vue-cli3.0 自我记录 其实在2018年8月10号,vue-cli3.0就已经面世了,由于项目中应用的全是2.x版本,所以并不了解3.0的vue-cli发生了什么变化,那今天尝试了下遇见的问题 ...
- 手动搭建webpack + vue项目之初体验
在使用vue做开发时,大部分人只会使用官方提供的脚手架搭建项目,脚手架虽然很好用,但想要成为一名优秀的前端开发者,webpack这一道坎是绕不开的,所以我们要学会脱离脚手架,利用webpack手动搭建 ...
- (一) .net core 2.0 初体验
1..net core 2.0环境 .net core 下载地址:https://www.microsoft.com/net/core#windowscmd 问题一:提示[Failed to load ...
- 【swoole2.0】 PHP + swoole2.0 初体验
背景: centos7 PHP7.1 swoole2.0 准备工作: 一. swoole 扩展安装 1 下载swoole cd /usr/local wget -c https://git ...
- TensorFlow2.0初体验
TF2.0默认为动态图,即eager模式.意味着TF能像Pytorch一样不用在session中才能输出中间参数值了,那么动态图和静态图毕竟是有区别的,tf2.0也会有写法上的变化.不过值得吐槽的是, ...
- Vue Cli 3 初体验(全面详解)
vue新出了 vue cli 3,并直接改名为 @vue/cli,今天就来盘他. 首先介绍等啰里啰嗦的就不写了,贴个link吧. Vue CLi3 github Vue CLi web 要是想先了解下 ...
随机推荐
- 【Oracle】11g direct path read介绍:10949 event、_small_table_threshold与_serial_direct_read
转自刘相兵老师的博文: http://www.askmaclean.com/archives/11g-direct-path-read-10949-_small_table_threshold-_se ...
- CTFshow萌新赛-web签到
打开靶机 查看页面信息 可以看到有一个system函数 在Linux中可以使用":"隔离不同的语句 payload如下 https://5105c8b6-83aa-4993-91b ...
- .NET Core使用Source Link提高源代码调试体验和生产效率
前言: 在我们日常开发过程中常常会使用到很多其他封装好的第三方中间件(NuGet依赖项).类库或者是.NET框架中自带的库.但是当你想要对这些类库的方法设置断点调试,然后发现无法F11(逐语句)调试进 ...
- file转化为binary对象发送给后台
具体代码如下: function filechange(e) { var file = $('#filed').get(0).files[0]; var fileSize = file.size, f ...
- 解决JavaScript中构造函数浪费内存的问题!
解决JavaScript中构造函数浪费内存的问题! 把构造函数中的公共的方法放到构造函数的原型对象上! // 构造函数的问题! function Gouzaohanshu(name, age, gen ...
- Linux系统中的Page cache和Buffer cache
Linux系统中的Page cache和Buffer cache Linux中有两个很容易混淆的概念,pagecache和buffercache,首先简单将一些Linux系统下内存的分布,使用free ...
- MySQL调优用户监控之show processlist
简介 show processlist显示这台MySQL正在连接的用户: mysql> show processlist; +----+------+-----------+-------+-- ...
- .NET, NETCORE 怎么写 "超时"代码,解析"超时"代码原理!
干货:本人不会长篇大论.能贴上去的,就是干货,能用一两句话讲明白的,不会大讲概念,不会浪费大家宝贵的时间. 前言:我们发现,超时是个非常重要的概念,如果在通讯架构中,没有超时的设计,那么这个通讯架构就 ...
- node集群(cluster)
使用例子 为了让node应用能够在多核服务器中提高性能,node提供cluster API,用于创建多个工作进程,然后由这些工作进程并行处理请求. // master.js const cluster ...
- 一个支付宝小程序在一段时间内只能保留一个 WebSocket 连接
一个支付宝小程序在一段时间内只能保留一个 WebSocket 连接 my.connectSocket - 支付宝开放平台 https://opendocs.alipay.com/mini/api/vx ...