Vue2入门学习笔记
Vue2入门必备!
⭐关注我查看更多配套笔记
学习视频:https://www.bilibili.com/video/BV1Zy4y1K7SH/
【尚硅谷Vue全家桶】
本博客是对该视频内容的整理以及加入自己的理解 想全面学习的推荐大家去看原视频
1.Vue动画
自己使用 Css 也能实现
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
| // apper属性可以让动画加载时出现 简写 apper 属性直接添加 <transition name="hello" :apper="true" apper> <div> <button @click="isShow = !isShow"> 显示/隐藏 </button> <h1 v-show="isShow"> 我是动画元素 </h1> </div> </transition>
<style> .hello-enter-active { animation: 动画名 持续时间; } .hello-leave-active { animation: 动画名 持续时间 everse; } .v-enter-active { animation: 动画名 持续时间; } .v-leave-active { animation: 动画名 持续时间 everse; } @keyfarm 动画名{ ... } </style>
|
2.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
| // apper属性可以让动画加载时出现 简写 apper 属性直接添加 <transition name="hello" :apper="true" apper> <div> <button @click="isShow = !isShow"> 显示/隐藏 </button> <h1 v-show="isShow"> 我是动画元素 </h1> </div> </transition>
<style> h1 { transition: all 0.5s linear; }
.v-enter,.v-leave-to { animation: 动画名 持续时间; } .v-enter-active,.v-leave-active { transition: all 0.5s linear; } .v-leave-enter-to,.v-leave { animation: 动画名 持续时间 everse; } @keyfarm 动画名{ ... } </style>
|
3.多个元素过渡
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
| // apper属性可以让动画加载时出现 简写 apper 属性直接添加 <button @click="isShow = !isShow"> 显示/隐藏 </button>
<transition-group group name="hello" apper> <div> <h1 v-show="isShow"> 我是动画元素 </h1> <h1 v-show="isShow"> 我是动画元素 </h1> </div> </transition-group>
<style> h1 { transition: all 0.5s linear; }
.v-enter,.v-leave-to { animation: 动画名 持续时间; } .v-enter-active,.v-leave-active { transition: all 0.5s linear; } .v-leave-enter-to,.v-leave { animation: 动画名 持续时间 everse; } @keyfarm 动画名{ ... } </style>
|
4.超级好用的动画库
animate.css
1 2 3 4 5 6
| <transition enter-active-class="animate__fadeIn" leave-active-class="animate__fadeOut" > <h1 v-show="visible" class="animate__animated">Animate.css</h1> </transition>
|
1 2 3 4 5 6 7 8 9 10 11 12
|
import animate from 'animate.css' Vue.use(animate)
|
官网:Animate.css | A cross-browser library of CSS animations.
5.Http请求 代理
Vue 项目中 推荐使用 axios
解决跨域问题
1.CORS
2.Jsonp script src 只能使用 get
3.代理服务器 代理服务器默认端口号 8080
1.– nginx
2.– vue-cli
5.1简易代理
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
| const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ transpileDependencies: true, devServer: { proxy:'http://后端服务器地址', } })
axios.get('http://localhost:8080/后端路由地址').then( response =>{ }, errror =>{ }, )
|
5.2完美代理
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
| const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ transpileDependencies: true, devServer: { proxy:{ '/api':{ target:'http://后端服务器地址', pathRewrite:{ '^/api':'' }, ws:true, changeOrigin:true, }, '/cas':{ target:'http://后端服务器地址', pathRewrite:{ '^/cas':'' }, ws:true, changeOrigin:true, } } } })
axios.get('http://localhost:8080/配置的前缀/后端路由地址')
|
6.静态组件
ES6 合并对象语法 Obj = {…对象1名称,…对象2名称}
7.vue-resource vue的插件库
对 xhr 进行封装
Vue.use(vueResource) 在main.js中进行全局配置
在 vm 中会出现 $http
使用 this.$http 代替 axios api完全一致 vue1.0广泛使用
8.slot 插槽
8.1默认插槽
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <Student/> <Student></Student>
<Student> <img src=""> </Student>
<div> <slot>使用者没有传入插槽 会将我展示</slot> </div>
|
8.2(具名插槽)多个插槽
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
<Student> <img src="" slot="slot名称1"> <vido src="" slot="slot名称2"> <template slot="slot名称1" slot:slot名称1> <h1>我是h1</h1> <div>我是div</viv> </template> </Student>
<div> <slot name="slot名称1">使用者没有传入插槽 会将我展示</slot> <slot name="slot名称2">使用者没有传入插槽 会将我展示</slot> </div>
|
8.3作用域插槽
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
<Student> <template scop="Obj"> <h1>{{Obj.games}}</h1> <h1>{{Obj.msg}}</h1> </template> </Student>
<div> <slot :games="games" msg="这里是msg信息">使用者没有传入插槽 会将我展示</slot> </div>
|
9.Vuex
多组件共享数据 状态 = 数据
- 多个组件依赖于同一个状态
- 来自不同组件的行为需要修改同一状态
1 2 3 4 5 6 7 8 9 10 11 12
| 1.npm i vuex
2.import Vuex from 'vuex'
3.Vue.use(Vuex)
Vue({ store:"hello", })
|
在components同级文件夹下添加 store 文件夹
添加 index.js
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
|
import Vue from 'vue' import Vuex from 'vuex'
Vue.use(Vuex)
const actions = { "函数名"(context,value){ console.log('actions 中的函数被调用了',context,value); context.dispatch("函数2",value); context.commit("函数名(使用大写与actions进行区分)",value); } }
const mutations = { "大写函数名"(state,value){ state.value += value; } }
const state = { "value":0, }
const getters = { bigSum(state){ return state.sum*10; } }
export default new Vuex.Store({ actions, mutations, state, getters, })
|
main.js
1 2 3 4 5
| import store from './store/index.js'
new Vue({ store })
|
js 执行 import 全部 import 会被提升到最高层
vue 规定必须 先 ues(vuex) 再 创建 store 实例
使用2.import Vuex from ‘vuex’
// vue2 -> vuex3
// vue3 -> vuex4
3.Vue.use(Vuex)
1 2 3 4 5 6 7
| methds:{ this.$store.dispatch("事件名",传入的数据); this.$store.commit("事件名",传入的数据); this.$store.getters.bigSum; }
|
可直接夸过 Actions 进行 Commit 调用 mutation 的函数
vuex 开发者工具 历史记录符号
回到该次数据 历史记录符号
可以删除历史记录 禁用符号
合并记录 下载符号
底部分 可以 导入导出 / 粘贴复制
ES6 语法
1 2 3 4 5 6
| let Obj1 = {x:1,y:2} let Obj2 ={ z:3, ...Obj1, m:7, }
|
9.1 **mapState **mapGetters
1 2 3 4 5 6 7 8 9 10 11 12 13
| import {mapState} from 'vue'
computed:{ ...mapState({sum:'sum',adress:'adress'}) ...mapState(['sum','subject']) ...mapGeters(['bigSum']) }
|
9.2 mapAction mapMutations
1 2 3 4 5 6 7 8 9 10 11 12
| import {mapState} from 'vue'
methods:{
...mapActions(['add']), ...mapMutations(['add']) }
|
9.3Vuex模块化
index.js
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
| import Vuex from 'vuex'
const countOptions = { namespaced:true, action:{}, mutation:{}, state:{}, getter:{}, }
const personOptions = { action:{}, mutation:{}, state:{}, getter:{}, }
export default new Vuex.Store({ modules:{ countAbout:countOptions, personAbout:personOptions } })
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| computed:{ ...mapState(['countAbout','personAbout']), ...mapState('countAbout',['data']), ...mapState('personAbout',['data']), }
|
10.路由
10.1 路由基础
单页面应用 路由改变 页面局部刷新 (没有全部刷新)
使用 vue 的插件库 vue-router
npm install -g vue-router
在 components 同级文件夹下创建 router 文件夹
index.js
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
| import VueRouter from 'vue-router'
import TheList from '../components/TheList.vue'; import AboutSnowman from '../components/AboutSnowman.vue';
export default new VueRouter({ routes: [ { path:"/TodoList", component:TheList, }, { path:"/about", component:AboutSnowman, }, { path:"*", component:AboutSnowman, },
] })
|
main.js
1 2 3 4 5 6 7 8
| import router from './router'
new Vue({ render: h => h(App), router:router, }).$mount('#app')
|
1 2 3 4 5 6 7 8
|
<router-link to="/TodoList" active-class="active">每日清单</router-link> <router-link to="/about" active-class="active">关于我的主页</router-link>
<router-view></router-view>
|
在 components 同级文件夹下创建 pages 文件夹
便于分类 pages存放 路由组件 components文件夹存放 一般组件
原理 : {不断销毁与挂在组件}
- 每个组件都有自己的$route属性,里面存储着自己的路由信息
- 整个应用只有一个router, 可以通过组件的$router属性获取到
10.2 多级路由 (嵌套路由)
index.js
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
| import VueRouter from 'vue-router'
import Vue from 'vue' Vue.use(VueRouter)
import TheList from '../components/TheList.vue'; import AboutSnowman from '../components/AboutSnowman.vue';
export default new VueRouter({ routes: [ { path:"/TodoList", component:TheList, children:[{ path:"new", component:TheList, }] }, { path:"/about", component:AboutSnowman, },
] })
|
1 2 3 4 5 6 7 8 9 10
|
<router-link to="/TodoList/new" active-class="active">每日清单</router-link> <router-link to="/about/new" active-class="active">关于我的主页</router-link>
<router-view></router-view>
|
10.3 路由传参
query参数 get传参
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <router-link to="/TodoList/new?name=雪人&age=18" active-class="active">每日清单</router-link>
<router-link :to="`/TodoList/new?name=${name}&age=${age}`" active-class="active">每日清单</router-link>
<router-link :to="`{ path="/TodoList/new", query:{ name:name, age:age, } } `" active-class="active">每日清单</router-link>
<router-link to="/about/new" active-class="active">关于我的主页</router-link>
|
1 2 3
| this.$route.query.name this.$route.query.age
|
10.4 命名路由
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| export default new VueRouter({ routes: [ { name:'ListName', path:"/TodoList", component:TheList, children:[{ name:'new', path:"new", component:TheList, }] }, ] })
|
1 2 3 4 5 6 7 8 9 10 11
|
<router-link :to="`{ // 此处直接传入 路由器 定义的名字 name:"ListName", query:{ name:name, age:age, } } `" active-class="active">每日清单</router-link>
|
10.5 params参数
1 2 3 4 5 6 7 8 9 10 11 12
| <router-link :to="`/TodoList/new/11/王二`" active-class="active">每日清单</router-link>
<router-link :to="`{ // params 只能使用name path会报错!!! name:"ListName", params:{ id:11, name:"王二", } } `" active-class="active">每日清单</router-link>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| export default new VueRouter({ routes: [ { name:'ListName', path:"/TodoList/:id/:name", component:TheList, children:[{ name:'new/:id/:name', path:"new", component:TheList, }] }, ] })
|
1 2 3
| this.$route.params.name this.$route.params.age
|
10.6 props的配置
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
| export default new VueRouter({ routes: [ { name:'ListName', path:"/TodoList/:id/:name", component:TheList, children:[{ name:'new/:id/:name', path:"new", component:TheList, props:{id:1,name:'hello'}, props:true, props($route){ return {id:$route.query.id,name:'hello'} } props({query}){ return {id:query.id,name:query.name} } }] }, ] })
|
10.7 replace 记录
默认为push记录 栈的不断添加
replace 替换当前记录 不能返回
1 2 3 4
| <router-link to="/TodoList/new" active-class="active" :replace="true">每日清单</router-link>
<router-link to="/about/new" active-class="active" replace>关于我的主页</router-link>
|
10.8 编程式路由导航
在 $router 中 直接操作 不借助 router-link
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 52 53 54 55 56
| <template> <button @click="showPush"> push查看 </button> <button @click="showReplace"> replace查看 </button> <button @click="back"> 后退 </button> <button @click="forward"> 前进 </button> <button @click="go"> 前进 </button> </template>
<script> export default { name:'Message', methods:{ showPush(){ // 调用 $router 上的API this.$router.push({ name:"xiangqing", query:{ id:'11', name:'王二', } }) }, showReplace(){ // 调用 $router 上的API this.$router.replace({ name:"xiangqing", query:{ id:'11', name:'王二', } }) }, back(){ this.$router.back }, forward(){ this.$router.forward }, go(){ // 正数 前进 n 次 // 复数 后退 n 次 this.$router.go(n) }, } } </script>
|
10.8 缓存路由组件
组件切走时会被销毁 内容消失 如何保存?
需要保存数据的去缓存
1 2 3 4 5 6 7 8 9 10
|
<keep-alive inlude="组件名"> <router-view></router-view> </keep-alive>
<keep-alive :inlude="['组件名1','组件名2','组件名3']"> <router-view></router-view> </keep-alive>
|
10.9激活与失活声明周期
用于路由组件的 开启定时器 比 mounted更高效
1 2 3 4 5 6 7 8
| methods:{ activated(){ }, deactivated(){ } }
|
10.10路由守卫
1.前 / 后 置路由守卫
保护路由的安全 验证数据库再展示
全局前置路由守卫
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
| export default new VueRouter({ routes: [ { path:"/TodoList", component:TheList, meta:{isAuth:true,title:"每日清单"}, } ] })
router.beforeEach((to,from,next)=>{ if(to.path === '/home'){ if(from.meta.isAuth){ next() } next() } next() }) export default router
|
1 2 3 4 5 6
|
router.afterEach((to,from)=>{ doucment.title = to.meta.title || '网页标题' })
|
2.独享路由守卫
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| export default new VueRouter({ routes: [ { path:"/TodoList", component:TheList, meta:{isAuth:true,title:"每日清单"}, beforeEnter:(to,from,next)=>{ if(...){ next() } } } ] })
|
3.组件内路由守卫
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <script> mounted(){ // 通过路由器规则 进该组件时被调用 // 在beforeEnter 之前 // to 一定是该组件路由 beforeRouteEnter(to,from,next){ }, // 通过路由器规则 离开该组件时被调用 // from 一定是该组件路由 beforeRouteLeave(to,from,next){ } } </script>
|
11.浏览器路由模式
main.js
1 2 3 4 5 6 7
|
new VueRouter({ mode:history, })
|
12.打包 上传服务器
如何部署服务器
node.js express 框架
->npm init
->text_serve 包名
->npm i express
中间件解决 history 模式 404问题
->npm i connect-history-api-fallback
// 在 server.js 同级目录下 新建 js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const express = require('express') const history = require('connect-history-api-fallback')
const app = express()
app.use(history)
app.use(express.static(__dirname+"./static"))
app.get('/person',(req,res)=>{ res.send({ name:'tom', age:18 }) })
app.listen(5005,(err)=>{ if(!err) console.log('服务器启动成功了!') })
|
13.Vue UI 组件库
7.1 移动端常用组件库
7.2PC端常用UI组件库
直接用就行
此处介绍Element UI
->npm i element-ui
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import Vue from 'vue'; import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css'; import App from './App.vue';
Vue.use(ElementUI);
new Vue({ el: '#app', render: h => h(App) });
|
按需引入
-> npm install babel-plugin-component -D 按需引入的库 -D为开发依赖(开发环境)
->npm install babel-preset-es2015 –save
->npm install –save-dev @babel/cli
需要修改 babel.config.js 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| module.exports = { presets: [ '@vue/cli-plugin-babel/preset', ['es2015', { modules: false }], ], plugins: [ [ 'component', { libraryName: 'element-ui', styleLibraryName: 'theme-chalk', }, ], ], }
|
main.js
1 2 3 4 5 6 7 8
| import {Button,Row,...} from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css';
VUe.component(Button.name,Button)
|