昨日回顾
1.vue项目目录----》 vue项目编译 ----》html,css,js
- public:index.html 单页面应用
- src:以后写代码,都在这里
- assets
- component
- router
- store:vuex----》状态管理器
- views:页面组件
- App.vue:根组件
- main.js
- vue.config.js----》vue的配置
- package.json----》项目依赖
- node_model 删掉 ----》npm install
- yarn
2.vue项目开发流程
-
新建xx.vue里面有三部分
-
templage:html内容,div-----》html
-
script:js
import xx from 'xx' export default { data(){ return{ name:'xz' } } }
-
style scoped
3.导入导出语法
- 模板化开发
- 匿名导出的导入:
import xx ffrom '位置'
- 命名导出的导入:
import {a,yy} from '位置'
- 匿名导出:
export default {}
- 命名导出:
export const a={}
4.项目中使用axios,打通前后端
- npm install axios
- import axios from 'axios'
- axios.get('地址').then(res = >{})
- axios.post('地址',{}).then(res =>{})
5.mixin:混入,抽取公用代码
- 全局使用:main.js vue,mixin(对象)
- 局部使用:组件 mixins:[ ,]
6.插件:对象内部有个insatll函数
export default {
install(){
1.放到vue实例中一些变量,以后在任意组件this.$xxx
2.Vue.mixin()
3.自定义的全局组件
4.自定义指令 v-xxx
}
}
main.js Vue.use(插件)
7.localStorage,sessionStroage,cookie
8.elemetui
-
iview
-
vant
-
使用:先下载再main.js
今日内容
一、Vuex的使用
1.vue插件,增强了vue的功能
在Vue中实现集中式状态(数据)管理的一个Vue插件,对Vue应用中多个组件的共享状态进行集中式的管理(读、写),也是一种组件间通信的方式,且适用于任意组件间通信
2.Vue的使用流程
-
state:存数据的地址
-
actions:服务员,中转站
-
mutations:厨师,真正该state数据的地方
使用步骤:
1.在state中定义变量 2.在组件中通过this.$store.dispatch('actions中定义的函数'),触发actions中的函数执行 3.在action中的函数中,调用context.commit('mutations中定义的函数') 4.在mutations中定义的函数实现真正修改state中的数据 5.页面中只要使用$store.state.变量,变量变化则页面变化,实现组件间的通信 6.注意: * 在组件中可以直接调用commit触发【mutations中定义的函数】 * 在组件中可以直接修改state中定义的变量
3.Vue的执行流程图
二、Vue-router的使用
官方提供的用来实现SPA 的vue 插件:有了它以后,我们可以写很多页面组件,通过地址不同的路径显示不同的页面组件
https://router.vuejs.org/zh/index.html
-
vue-router:3版本对应vue2,4版本对应vue3
-
单页面应用:index.html,以后都是页面组件间的切换,借助于vue-router
1.基本使用
使用步骤1
1.新建router/index.js
const routes = [配置路由1,配置路由2]
2.main.js中使用:之前已经写好了
import router from './router'
new Vue({
...
router,
...
}).$mount('#app')
3.只需要写页面组件,配置路由即可
4.在App.vue中加入
<router-view>
</router-view>
5.在浏览器访问在router/index.js的const routes中配置的路径,就能看到对应的页面组件
使用步骤2
在任意组件中
1.this.$router:路由对象,控制路由的跳转(push,go,back......)
2.this.$router:当前路由,当前路径对象(query,params......)
2.路由跳转
使用步骤:
1. 在html中使用
<router-link :to='path'>去登录
</router-link>
2.在js中使用
this.$router.push('goods')
3.路由跳转携带参数
两种情况
- 带在请求地址中以 ?name=xz&age=19
- 在地址中类似于django的分组 /goods/1/
情况一:
<router-link to="/login/?name=lqz&age=19">去登录</router-link>
从组件中取:
this.$route.query.name 或this.$route.query.age
情况二:
<router-link to="/login/1">去登录</router-link>
从组件中取:
this.$route.params.id
4.路由嵌套
使用步骤:
1.router、index.js 相应中
{
path:'/goods',
name:'goods',
component:Goods,
children:[
{
path:'list',
component:GoodList
},
{
path:'detail',
component:GoodDetail
}
]
},
2.必须要在Goods组件中,写<router-view></router-view>
3.使用router-link标签跳转
4.只会变更Goods下router-view包裹的位置
5.路由守卫
-
对路由进行权限控制
-
前置路由守卫
router.beforeEach((to, from ,next) = >{ console.log('前置路由守卫', to, from) if (to.name == 'shoppingcart') { let name = localStorage.getItem('name') if (name) { next() } else { alert('不好意思没有权限') } } else { next() } })
-
后置路由守卫
router.afterEach((to,from)=>{ console.log('后置路由守卫',to,from) document.title = to.name })
三、vue3介绍
-
性能的提升
-
打包大少减少41%
-
初次渲染快55%,更新渲染快133%
-
-
源码的升级
- 使用Proxy代替defineProerty实现响应式
- 重写虚拟DOM的实现和Tree-Shaking
-
拥抱TypeScript
- vue3可以更好的支持TypeScript
-
新的特性
- Composition API(组合API)
- setup配置
- ref与reactive
- watch与watchEffect
- provide与inject
- 新的内置组件
- Fragment
- Teleport
- Suspense
- 其他改变
- 新的生命周期钩子
- data 选项应始终被声明为一个函数
- 移除keyCode支持作为v-on 的修饰符
- Composition API(组合API)
-
组合式API和配置项API
-
使用组合式API
-
配置项API
{ name:'xx', data:function(){}, methods:{} }
-
四、创建vue3项目 两种方式
-
vue-cli:创建vue2和vue3跟之前一样
-
vite:创建vue3,创建最新
npm init vue@latest
Pinai
-
vite创建另一种方式:创建vue3.0.4版本
npm init vite-app <project-name>
进入工程目录
cd <project-name>
安装依赖
npm install
运行
npm run dev
-
启动的两种方式
-
以后在页面中this已经不是vue2中的对象,而是一个代理 Proxcy
五、setup函数
vue 新增的setup配置项函数
- 定义变量
- 定义函数
- 必须要有个返回return 变量和函数,在模板中才能使用
代码:
export default {
name: 'App',
setup() { // setup中没有this了
// 以后所有的变量定义函数编写,都写在这个函数中
// 定义变量 如果这么写,变量渲染没问题,但是没有响应式,页面变了,变量不会变
let age = 19
let name = 'lqz'
// 定义函数
function handleClick() {
alert('美女~~~')
}
// 箭头函数的写法
let handleAdd = () => {
console.log('我要开始加了')
age=age+1
console.log(age)
}
// 函数必须有返回值
return {
age, name, handleClick, handleAdd
}
}
}
</script>
六、ref和reactive
- 导入使用:
imoport {ref, reactive} from 'vue'
- 基本数据类型(数字,字符串,布尔),如果要加响应式:使用
ref
包裹,在模板中之间使用,js中通过对象,.value
取值 - 对象,数组引用使用
reactive
,ref可以保对象类型,当是用的时候必须.value
代码ref
// ref
<template>
<h2>{{ name }}</h2>
<h3>{{ age }}</h3>
<br>
<button @click="handleAdd">点我,age+1</button>
<br>
<button @click="handleChangeName">点我name变化</button>
</template>
<script>
import {ref, reactive} from 'vue'
export default {
name: 'App',
setup() {
let age = ref(19) // age 已经不是数字了,是RefImpl的对象
let name = ref('lqz')
let handleAdd = () => {
console.log('我要开始加了,age是', age)
age.value = age.value + 1
console.log('我要开始加了,age是', age.value)
}
function handleChangeName(){
name.value=name.value+'?'
console.log(name)
}
return {
age, name, handleClick, handleAdd,handleChangeName
}
}
}
</script>
代码reactive
// reactive
<template>
<h1>reactive的使用</h1>
<h2>人名:{{ name }},年龄:{{ age }}</h2>
<br>
<button @click="handleAdd">点我,age+1</button>
<br>
<button @click="handleChangeName">点我name变化</button>
</template>
<script>
import {ref, reactive} from 'vue'
// 基本数据类型如果要加响应式:使用ref包裹
// 对象,数组引用
export default {
name: 'App',
setup() {
let person = reactive({name:'xz', age:19})
// 如果用ref({name:'xz', age:19}), 则就有代理Proxy,多套一层
// 以下表示 person.value.age 来取出age
let handleAdd = () => {
person.age = person.age + 1
console.log('我要开始加了,age是', person.age)
}
function handleChangeName(){
name.value=name.value+'?'
console.log(name)
}
return {
age, name, handleAdd,handleChangeName
}
}
}
</script>
注意
vue2必须要在一个div中,而vue3不需要套在一个div中
七、计算和监听属性
1.计算属性
export default {
name: 'App',
// computed:{
// fullName:function (){}
// },
setup() {
// 1 计算属性案例1
// let firstName = ref('刘')
// let lastName = ref('清政')
// // 定义计算属性
// let fullName = computed(() => {
// return firstName.value + lastName.value
// })
// 2 计算属性案例2
let person = reactive({
firstName: '刘',
lastName: '清政',
})
// 定义计算属性
person.fullName = computed({
get() {
return person.firstName + '-' + person.lastName
},
set(value) {
console.log(value)
const nameArr = value.split('-')
person.firstName = nameArr[0]
person.lastName = nameArr[1]
}
})
return {
person
}
}
}
2.监听属性
import {computed, watch, ref, reactive, watchEffect} from 'vue'
export default {
name: 'App',
setup() {
// 1 计算属性案例1
let name = ref('lqz')
// 定义监听属性
watch(name, (newValue, old) => {
console.log('name变了')
// console.log(old)
// console.log(newValue)
})
// vue3 多的watchEffect,只要函数中使用的变量发生变化,它就会触发
watchEffect(() => {
// 只要该函数中使用的变量发生变化,它就会触发
// let a = name.value + '?'
console.log('watchEffect配置的回调执行了')
})
return {
name
}
}
}
八、生命周期
vue3.0中可以继续使用vue.2x中是生命周期钩子,当有两个被更名:
beforeDestroy 改名为 beforeUnmount
destroyed 改名为 unmounted
vue.3.0也提供 Compositioon API形式的生命周期钩子,与vue2.x中钩子对应关系如下:
beforeCreate===>setup()
created=======>setup()
beforeMount ===>onBeforeMount
mounted=======>onMounted
beforeUpdate===>onBeforeUpdate
updated =======>onUpdated
beforeUnmount ==>onBeforeUnmount
unmounted =====>onUnmounted
九、hooks
1.hook/usePoint.js
import {onMounted, onUnmounted, reactive} from "vue";
export default function () {
let p = reactive({
x: 0,
y: 0
})
function getPoint(event) {
console.log(event)
p.x = event.pageX
p.y = event.pageY
}
// 声明周期钩子的onMounted,当页面挂载就会执行
onMounted(() => {
// 给数鼠标点击增加监听,当点击鼠标,就会执行这个函数
window.addEventListener('click', getPoint)
})
// 组件被销毁时,把功能去掉
onUnmounted(() => {
window.removeEventListener('click', getPoint)
})
return p
}
2.在想使用的组件中引入使用即可
<template>
<h2>x坐标是:{{ p.x }},y坐标是:{{ p.y }}</h2>
</template>
<script>
import {reactive, onMounted, onUnmounted} from 'vue'
import usePoint from '../hook/uesPoint.js'
export default {
name: "Point",
setup() {
let p = usePoint()
return {p}
}
}
</script>
<style scoped>
</style>
十、toRefs
setup函数,return{...toRefs(data)} 可以解压赋值
代码
export default {
name: 'App',
setup() {
let data = reactive({
name: 'lqz',
age: 19,
isShow: true
})
function handleShow() {
console.log('ssdaf')
data.isShow = !data.isShow
data.age++
}
return {
...toRefs(data),
handleShow
// data
}
}
}
App.vue
<template>
<HelloWorld msg='xxxx'></HelloWorld>
</template>
components/HelloWorld.vue
export default {
name:'HelloWorld',
props:['msg'],
// 可以接受参数,context, 内部函数props接受的自定义属性
setup(context){
// context.msg
console.log('----', context)
}
}
十一、后台管理模板
vue-admin-template-master
- 运行起来
package.json
第7行加入"dev":"set NODE_OPTIONS=--openssl-legacy-provider & vue-cli-service serve",
- java半的若依,带权限控制后台管理模块
python:django-vue-admin
python flask-vue-admin
go:gin-vue-admin