Vue 3.0 Beta 尝鲜体验

2020年4月vue3.0发布beta版本,这就意味着正式版本3.0即将到来。发布的内容包括下面的内容:

vue: Beta

vue-router: Alpha

vuex: Alpha

vue-class-component: Alpha

vue-cli: Experimental support via vue-cli-plugin-vue-next

eslint-plugin-vue: Alpha

vue-test-utils: Alpha

vue-devtools: WIP

jsx: WIP

 

接下来我们就不多说其他的废话直接进入主题来初体验一下vue3.0。

1、新建一个项目,还是使用原理的vue-cli脚手架进行新建 vue create demo (这里demo是项目名称),输入命令后,会出现命令行交互窗口选择你需要安装的就行(不明白的可以直接网上搜索一下,我就不一一介绍咯)

2、如果项目新建成功咯之后,cd demo进入项目目录,直接运行npm run serve

3、目前创建 Vue 3.0 项目需要通过插件升级的方式来实现,vue-cli 还没有直接支持,我们进入项目目录,并输入以下指令:vue add vue-next

4、行上述指令后,会自动安装 vue-cli-plugin-vue-next 插件,该插件会完成以下操作:

  • 安装 Vue 3.0 依赖
  • 更新 Vue 3.0 webpack loader 配置,使其能够支持 .vue 文件构建(这点非常重要)
  • 创建 Vue 3.0 的模板代码
  • 自动将代码中的 Vue Router 和 Vuex 升级到 4.0 版本,如果未安装则不会升级
  • 自动生成 Vue Router 和 Vuex 模板代码

 

接下来我们执行一下npm run serve命令,项目也是正常显示,

vue3.0版本的main.js代码如下

// 旧版
import App from './App'
import store from './store'
import router from './router'

new Vue({
  // 这个就是路由
  router,
  // 这个是vuex
  store,
  // render渲染,$mount是代表index.html的id
  // 即我把App.vue渲染到id为app的div里
  render: h => h(App)
}).$mount('#app')

// 新版
import { createApp } from 'vue';
import App from './App.vue'
import router from './router'
import store from './store'

createApp(App).use(router).use(store).mount('#app')

接下来我们看一下src目录下router里面的index.js文件

代码如下:

import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '../views/Home.vue'

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router

初始化 Vue Router 的过程与 3.0 版本变化不大,只是之前采用构造函数的方式,这里改为使用 createRouter 来创建 Vue Router 实例,配置的方法基本一致,接下来我们直接就在About.vue里面修改代码吧,把里面的内容全部删除,添加如下代码(你也可以重新新建一个文件然后配置一下路由)。

状态和事件绑定

<template>
	<div class="test">
		<h1>count: {{count}}</h1>
        <h1>statet.size:{statet.size}</h1>
        <h2>reactive:::{{size}}----------color:{{color}}</h2>
	</div>
</template>

<script>
import { ref, reactive, toRefs } from 'vue'
export default {
	setup () {
		// 定义一个ref响应式对象
        const count = ref(0);

        // 如果要定义多个可以使用reactive,返回的时候再return使用...toRefs(statet ),页面就可以直接调用statet里面的属性咯,例如下面的{{size}} {{color}}
        const statet = reactive({
          size: 36,
          color: "red"
        });
		return {
			count,
            ...toRefs(state)
		}
	}
}
</script>

Vue 3.0 中初始化状态通过 setup 方法,定义状态需要调用 ref 和reactive方法。2种方法的区别如下

1、是为了适应不同的写法的人群

有的人可能喜欢这种写法
const a = 1
const b = 2

也有的人可能喜欢这种写法
const field = {
  a : 1,
  b : 1    
}
在这里不评价哪种合适,也没有什么准确的答案,两者的主要区别在于:一,我们使用了2个变量来存储值;而风格二则当作对象的属性存储。这两种风格的代码工作的都没问题,关键在于个人或团队的偏好:使用单独的变量还是使用对象封装,我觉得ref更偏向于第一类人,而reactive更偏向于第二类吧

2、ref只可以监听简单数据,reactive可以监听所有数据
ref这种写法简单,但也有弊端,经过尝试,我发现他只能监听一些如数字、字符串、布尔之类的简单数据而如果需要监听如上面代码一样的jsonArray我们在vue2种都会使用$set来进行变更,到了vue3我们终于可以愉快的使用reactive来实现了。

3、使用方式不一样
a、ref修改数据需要使用这样count.value=xxx的形式,而reactive只需要state.reactiveField=值这样来使用
b、第二点体现在template中引用时候为reactiveField,不需要state,也就是说我reactive对象里面字段是应该直接使用的
c、体现在reactive在return时候需要toRefs来转换成响应式对象
目前刚刚接触,我总结出的不同大概就这么些吧,我上面也提到了使用reactive需要用toRefs来包裹,那这个函数干嘛用的呢?
toRefs函数我是这么理解的 他能将reactive创建的响应式对象,转化成为普通的对象,并且这个对象上的每个节点,都是ref()类型的响应式数据。

 

接下来我们定义一个事件,用来更新 count 状态:

<template>
	<div class="test">
		<h1>count: {{count}}</h1>
		<button @click="add">add</button>
	</div>
</template>

<script>
import { ref } from 'vue'
export default {
	setup () {
		const count = ref(0)
		const add = () => {
			count.value++
		}
		return {
			count,
			add
		}
	}
}
</script>

这里的 add 方法不再需要定义在 methods 中,但注意更新 count 值的时候不能直接使用 count++,而应使用 count.value++,更新代码后,点击按钮,count 的值就会更新了

计算属性和监听器

Vue 3.0 中计算属性和监听器的实现依赖 computed 和 watch 方法

<template>
	<div class="test">
		<h1>count: {{count}}</h1>
		<div>count * 5 = {{newCount}}</div>
		<button @click="add">add</button>
	</div>
</template>

<script>
import { ref, computed, watch } from 'vue'
export default {
	setup () {
		const count = ref(0)
		const add = () => {
			count.value++
		}

        // watch
		watch(() => count.value, val => {
			console.log(`count is ${val}`)
		})

        // computed
		const newCount= computed(() => count.value * 5)
		return {
			count,
			newCount,
			add
		}
	}
}
</script>

计算属性 computed 是一个方法,里面需要包含一个回调函数,当我们访问计算属性返回结果时,会自动获取回调函数的值

const newCount= computed(() => count.value * 5)

监听器 watch 同样是一个方法,它包含 2 个参数,2 个参数都是 function

watch(

    () => count.value, 

    val => {     //  val代表更新后的新值,如果需要显示旧值,可以这样写(newVal, oldVal) = >{..............}

        console.log(`count is ${val}`)

    }

)

第一个参数是监听的值,count.value 表示当 count.value 发生变化就会触发监听器的回调函数,即第二个参数可以执行监听时候的回调

获取路由信息

Vue 3.0 中通过 getCurrentInstance 方法获取当前组件的实例,然后通过 ctx 属性获得当前上下文,ctx.$router 是 Vue Router 实例,里面包含了 currentRoute 可以获取到当前的路由信息

方法一:import { getCurrentInstance } from 'vue'

方法二:import { useRouter } from "vue-router";

setup () {
            // 方法一
			/*const { ctx } = getCurrentInstance()
			console.log(ctx.$router.currentRoute.value)*/
            // 方法二
            const router = useRouter();
            // console.log(router.currentRoute.value)
            
		}

vueX集成

1、引用 Vuex 状态

首先找到项目目录store文件夹下的index.js(vue3.0版本的store和原来的Api几乎没有啥变化),我们在state里面新添加一个testA状态

import Vuex from 'vuex'

export default Vuex.createStore({
	state: {
		testA: 125
	},
	actions: {

	},
	modules: {

	}
});

然后再about.vue页面里使用computed引用store里面的状态。

/* store使用*/

 方法一:const testA = computed(() => ctx.$store.state.testA)

 方法二:先引入vuex里面的useStore

               import { useStore } from 'vuex'

               然后再step里面定义变量接受

               const store = useStore();

               const testA = store.state.testA;

然后再return返回,页面里面就可以使用{{testA}}

<template>
    <div class="test">
        <h1>count: {{count}}</h1>
        <h3>newCount:{{newCount}}</h3>
        <button @click="add">Add</button>
        <h2>vuex testA:{{testA}}</h2>
        <button @click="update">Add-Store</button>
    </div>
</template>

<script>
import { useStore } from 'vuex'
import { ref, computed, watch, getCurrentInstance  } from 'vue'
export default {
    setup () {
        /* 
            定义变量 data
        */
        const count = ref(0);

        /* 
            watch  监听器 watch 同样是一个方法,它包含 2 个参数,2 个参数都是 function:
        */
        watch( 
            () => count.value, 
            val => {
            console.log(`count is ${val}`)
            }
        )

        /* 
            computed
        */

        const newCount = computed(() => count.value * 2)

        /* 
            获取当前路由信息  Vue 3.0 中通过 getCurrentInstance 方法获取当前组件的实例,然后通过 ctx 属性获得当前上下文,ctx.$router 是 Vue Router 实例,里面包含了 currentRoute 可以获取到当前的路由信息
        */
        const { ctx } = getCurrentInstance()
		/* console.log(ctx.$router)
		console.log('store:', ctx.$store)
		console.log('state:', ctx.$store.state) */
		/* 
			store使用
		*/

		// const testA = computed(() => ctx.$store.state.testA); // 同下面2行
        const store = useStore(); // 使用useStore必须要inport { useStore} from 'vuex'
        const testA = store.state.testA;
        /* 
            定义方法 methods
        */
        const add = () => {
            count.value++ 
        }

        return {
            count,
            testA,
            newCount,
            // methods
            add,
        }
    }
}
</script>

<style lang="scss" scoped>
.test {
    color: red;
}
</style>

2、更新 Vuex 状态

更新 Vuex 状态仍然使用 commit 方法,这点和 Vuex 3.0 版本一样

import Vuex from 'vuex'

export default Vuex.createStore({
	state: {
		testA: 125
	},
	mutations: {
		setTestA(state, value) {
			state.testA += value;
		}
	},
	actions: {

	},
	modules: {

	}
});

页面使用commit方法调用

<template>
    <div class="test">
        <h1>count: {{count}}</h1>
        <h3>newCount:{{newCount}}</h3>
        <button @click="add">Add</button>
        <h2>vuex testA:{{testA}}</h2>
        <button @click="updateStore">updata-store</button>
    </div>
</template>

<script>
import {useStore} from 'vuex'
import { ref, computed, watch, getCurrentInstance  } from 'vue'
export default {
    setup () {
        /* 
            定义变量 data
        */
        const count = ref(0);
        const store = useStore();
        /* 
            watch  监听器 watch 同样是一个方法,它包含 2 个参数,2 个参数都是 function:
        */
        watch( 
            () => count.value, 
            val => {
            console.log(`count is ${val}`)
            }
        )

        /* 
            computed
        */

        const newCount = computed(() => count.value * 2)

        /* 
            获取当前路由信息  Vue 3.0 中通过 getCurrentInstance 方法获取当前组件的实例,然后通过 ctx 属性获得当前上下文,ctx.$router 是 Vue Router 实例,里面包含了 currentRoute 可以获取到当前的路由信息
        */
        const { ctx } = getCurrentInstance()
		/* console.log(ctx.$router)
		console.log('store:', ctx.$store)
		console.log('state:', ctx.$store.state) */
        
		/* 
			store使用
		*/
		const testA = computed(() => ctx.$store.state.testA)
        /* 
            定义方法 methods
        */
        const add = () => {
            count.value++ 
        }

        //
        const updateStore = () => {
            // mutations
            // ctx.$store.commit('setTestA', 100)
            store.commit("increment");
        }
        return {
            count,
            testA,
            newCount,
            // methods
            
            add,
            updateStore
        }
    }
}
</script>

<style lang="scss" scoped>
.test {
    color: red;
}
</style>

页面点击updata-store按钮后,会触发 update 方法,此时会通过 ctx.$store.commit 调用 setTestA 方法,将 state里面的testA 值覆盖 ,另外一种方法是引入useStore   然后通过store.commit("setTestA")调用

vue3.0版本生命周期

// beforeCreate -> 使用 setup()
// created -> 使用 setup()
// beforeMount -> onBeforeMount
// mounted -> onMounted
// beforeUpdate -> onBeforeUpdate
// updated -> onUpdated
// beforeDestroy -> onBeforeUnmount
// destroyed -> onUnmounted
// errorCaptured -> onErrorCaptured

// 生命周期同样需要引入,写在setup里面,但不需要return
import { onMounted, onUnmounted } from "vue";
export default {
  name: "Home",
  setup() {
    onMounted(() => {
      console.log("onMounted");
    });
  }
};

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值