第一章,入门 1. 创建工程 使用脚手架 vue-cli创建 安装脚手架 vue-cli
Node 版本要求 Vue CLI 4.x 需要 Node.js v8.9 或更高版本 (推荐 v10 以上)。你可以使用 n ,nvm 或 nvm-windows 在同一台电脑中管理多个 Node 版本。
1 2 3 npm install -g @vue/cli yarn global add @vue/cli
如需升级全局的 Vue CLI 包,请运行:
1 2 3 npm update -g @vue /cli # 或者 yarn global upgrade --latest @vue /cli
查看本地脚手架版本vue -V/vue --version 版本应大于5.1.0 可以创建vue3项目–具体没试过
坑:
1 2 3 4 5 6 7 vue : 无法加载文件 xxxxx \nodejs\vue.ps1。未对文件 xxxxx\nodejs\vue.ps1 进行数字签名。无法在当前系统上运行该脚本。有关运行脚本和设置执行策略的详细信息,请参阅 https:/go.microsoft.com/fwlin k/?LinkID=135170 中的 about_Execution_Policies。 所在位置 行:1 字符: 1 + vue + ~~~ + CategoryInfo : SecurityError : (:) [],PSSecurityException + FullyQualifiedErrorId : UnauthorizedAccess
原因:由于使用的是powershell,存在powershell不能或禁止执行脚本 powershell无疑是对安全充分考虑,把脚本的执行分成几种策略4种常见的策略:
Restricted: (默认策略)禁止运行任何脚本和配置文件。
AllSigned :可以运行脚本,但要求所有脚本和配置文件由可信发布者签名,包括在本地计算机上编写的脚本。
RemoteSigned :可以运行脚本,但要求从网络上下载的脚本和配置文件由可信发布者签名; 不要求对已经运行和已在本地计算机编写的脚本进行数字签名。
Unrestricted :可以运行未签名脚本。(危险!)解决办法: 获取当前的执行策略 Get-ExecutionPolicy命令不区分大小写 在命令框输入 set-ExecutionPolicy RemoteSigned 在 PowerShell中输入会出现如下图,选择 y或者 a即可
创建工程
使用 Vite创建 Vite新一代前端构建工具-老的是 webpak 优势:
开发环境中,无需打包,快速冷启动
轻量,快速的热重载(HMR)
按需编译,不再等待整个应用编译完成
创建工程
1 npm init vite-app project-name
1 2 3 4 5 6 7 8 9 10 11 12 PS C:\Users\admin> npm init vite-app vue3_study_vite Need to install the following packages: create-vite-app Ok to proceed? (y) y npm WARN deprecated create-vite-app@1.21.0: create-vite-app has been deprecated. run `npm init @vitejs/app` or `yarn create @vitejs/app` instead. Scaffolding project in C:\Users\admin\vue3_study_vite... Done. Now run: cd vue3_study_vite npm install (or `yarn`) npm run dev (or `yarn dev`)
1 2 cd <project-name>npm install
2. vue-cil创建的工程分析
主文件 main.js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import { createApp } from 'vue' import App from './App.vue' const app = createApp (App ) app.mount ('#app' ) setTimeout (()=> { app.unmount ('#app' ) },1000 )
脚手架配置文件 vue.config.js 1 2 3 4 module .exports = { lintOnSave : false , };
App.vue模板 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <template> <!-- vue3组件中的模板结构可以没有根标签 --> <img alt="Vue logo" src="./assets/logo.png"> <HelloWorld msg="Welcome to Your Vue.js App" /> </template> <script> import HelloWorld from './components/HelloWorld.vue'//引入 HellWorld组件 export default { name: 'App',//给组件命名, components: {//注册组件 HelloWorld } } </script> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
第二章、常用CompositionAPI(组合式API) 1. 拉开序幕的 setup()
vue3中的一个新的配置项,值为一个函数
setup是所有组合式 API表演的舞台
组件中所有用到的数据、方法等待,均要配置在 setup中
两种返回值:
一个对象,,对象中的属性,方法,在模板中可以直接使用!!
渲染函数,可以自定义渲染内容(了解)
<font color='red'>注意点</font>:
不建议 vue2,vue3混用
Vue2.x配置的(data,methods,computed…)中可以访问到setup中的属性,方法
但是在 setup中不能访问 vue2的配置(data,methods,computed…)
如果有混合定义,那么 vue3的优先级高
setup不是一个 async函数,因为返回值不再是 return的对象,而是 promise,模板看不到 return对象中的属性
setup()的两个注意点
执行时机
在 beforeCreate之前执行一次,this是 undefinedDemo.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <template> <div > <h1 > 一个人的信息</h1 > <h2 > 姓名:{{ person.name }}</h2 > <h2 > 年龄:{{ person.age }}</h2 > </div > </template> <script> import { reactive } from 'vue' export default { name : 'components-demo' , beforeCreate ( ) { console .log ('-beforeCreate-' ) }, setup ( ) { console .log ('--setup--' ,this ) let person = reactive ({ name : 'Susan' , age : 16 }) return { person } } }
setup()的参数
props:值为对象,包含:组件外部传递过来,且内部声明接受了的属性context:上下文对象
attrs:值为对象,包含组件外部传递过来,但是没有在props配置中声明的属性,相当于 this.$attrs.
slots:收到的插槽内容,相当于 this.$slots.
emit:分发自定义事件的函数,相当于 this.$emit.
内容代码App.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <template> <Demo @hello ="showHelloMsg" msg ="你好" school ="依旧归七学院" > <template v-slot:qwe > <span > 测试卡槽 </span > </template > </Demo > <h1 > 以上是demo组件</h1 > </template> <script > import Demo from './components/Demo' export default { name : 'app' , components : { Demo }, setup ( ) { function showHelloMsg (value ) { alert (`出发了hello时间,收到的参数是:${value} ` ) } return { showHelloMsg } } } </script >
Demo.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 <template> <h1 > 一个人的信息</h1 > <h2 > 姓名:{{ person.name }}</h2 > <h2 > 年龄:{{ person.age }}</h2 > <button @click ="test" > 测试demo组件的触发事件</button > </template> <script > import { reactive } from 'vue' export default { name : 'components-Demo' , props : ['msg' , 'school' ], emits : ['hello' ], beforeCreate ( ) { console .log ('-beforeCreate-' ) }, setup (props, context ) { console .log ('--setup--\n[props]' , props) console .log ('--setup--\n[context]' , context) console .log ('--setup--\n[context.slots]:' , context.slots ) let person = reactive ({ name : 'Susan' , age : 16 }) function test ( ) { context.emit ('hello' , 666 ) } return { person, test } } } </script > <style > #app { font-family : 'Avenir' , Helvetica, Arial, sans-serif; -webkit-font-smoothing : antialiased; -moz-osx-font-smoothing : grayscale; text-align : center; color : #2c3e50 ; margin-top : 60px ; } </style >
2. ref函数
接受一个参数值并返回一个响应式且可改变的 ref 对象。ref 对象拥有一个指向内部值的单一属性 .value。
1 2 3 4 const count = ref (0 )console .log (count.value ) count.value ++ console .log (count.value )
3. reactive函数
作用,定义一个对象类型 的响应式数据(基本类型用 ref)
语法,const 代理对象 = reactive(源对象)接收一个对象,或数组,返回一个代理对象,(proxy对象)
reactive定义的响应式数据是”深层次的”
内部基于ES6的porxy实现,通过代理对象操作源对象内部数据进行操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <script> import HelloWorld from './components/HelloWorld.vue' import { ref, reactive } from 'vue' export default { name : 'App' , setup ( ) { const refvalue = ref (666 ) const person = reactive ({ name : '姓名' , age : 18 , job : '会计' , salary : '10k' , hobby : ['study' , 'lol' , 'csgo' ] }) function changeInfo ( ) { person.name = 'Jack' person.age = 23 person.job = '睡觉' person.salary = '1元' person.hobby [1 ] = 'pubg' console .log (person) setTimeout (()=> { person.salary = refvalue.value },2000 ) } return { person, changeInfo } } } </script>
4. Vue3中的响应式原理 Vue2.x的响应式
实现原理:
对象类型:通过 Object.defineProperty()对属性读取修改拦截(数据劫持,响应式根基)
数组类型:通过重写更新数组的一系列方法,来实现的拦截。(对数组的变更方法进行了包裹)
1 2 3 4 Object .defineProperty (data, 'count' ,{ get ( ){}, set ( ){} })
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <script> export default { name: 'App',//给组件命名, data() { return{ person { name: '姓名', age: 18, job: '会计', salary: '10k', hobby: ['study', 'lol', 'csgo'] } } }, methods:{ addSex(){ } } </script>
直接通过数组下标修改数组里的元素,界面不会自动更新
Vue3.0的响应式