vue和vue3区别:
vue--->const app=new vue({
el:"#id",
data:{
message:'这个信息'
}
})
vue3---->const app=Vue.createApp({
data(){
return{
message:'这是信息'
}
}
}).mount('#id');//将上面的实例挂载到id上
数据响应式:---->app.message='我已经改变';
v-for="item in arrays"------>遍历数组
title属性:----->鼠标悬浮显示字符串
:title属性:----->:title="item.array"--->绑定数据
安装脚手架:
安装:npm insatll -g @vue/cli
版本:vue --version
创建项目 vue create 项目名称
vue.config.js----->vue脚手架配置文件---->详细配置到vue官网
{{}}----->插值表达式可以写简单逻辑
指令:v-once------>数据只第一次显示,不是响应式
----<p v-once>{{mes}}</p>
v-pre----->内容原封不动的显示
<p v-pre>{{mes}}</p>
v-text----->响应式显示数据(与插值表达式一样)
<p v-text="hello"></p>
v-html------>可解析标签
<p v-html="<p v-text="hello"></p>"></p>
绑定属性(可以使用数组、对象、方法、字符串):
v-bind:属性名---->就可以实现属性响应式(动态属性)---->简写为(:属性名)语法糖
<p v-bind:class="mes"></p>
<p :class="mes"></p>
使用对象格式绑定:<p :class="{bg:true}"></p>-------->当bg为true时,就使用bg这个样式类
使用数组格式绑定:<p :class="[bg1,bg2]"></p>----->绑定了bg1和bg2样式类
使用方法格式绑定:<p :class="fun()"></p>----->方法返回所需要的json格式或者数组类型
使用字符串格式绑定:<p :class="'bg'"></p>---->不常用(了解)
vue的options(选项):
①data(){return{}}-------->返回值
②name:“”------>名字
③methods:{fun(){}}--------->所有方法
④----------->复杂计算可用(把fun1放到{{fun1}})
computed:{
fun1:{
get(){},
set(){}
}
}
vue事件监听:
v-on:click=""------@click=""(语法糖)----->点击事件
----@click="add"----->不传参数-----在methods中有一个参数,这个参数是默认事件对象
----@ckick="add(a,$event)"-----传参时,如果想获取默认事件对象使用:$event
v-on事件修饰符:
@click.stop---->阻止冒泡事件
@click.self------>
@click.capture----->
@click.prevent------>阻止默认事件(比如阻止a标签的默认事件)
@click.once----->事件只触发一次
v-if="true"/"false"-----显示/隐藏(直接删除dom元素)
v-show="true"/"false"-----显示/隐藏(使用display:none)
v-for="item in arrays"------->遍历数组----加上唯一标识:key=""(提高效率)
v-for="(item,index) in arrays"------->遍历数组----加上唯一标识::key=""(提高效率)
v-model----->数据双向绑定----->修饰符:
.lazy---懒加载----回车之后才变化
.number---数字转换
.trim-----去掉前后空格
数字.toFixed(2)------>保留两个小数
vue自定义组件使用:
①:创建组件模板:创建一个.vue模板,然后写入想要的样式
②:在App.vue或者其他组件中引入自定义组件:import 组件名 from “组件路径”
③:注册组件:使用components:{Hello}
④:使用组件:<{Hello}></{Hello}>
注意:在父组件中加入一个class,在子组件中也可以使用(.box)
<style scoped>
</style>
-----------scoped:只能在父组件中使用
父子组件的通信(传递):
①父组件传到子组件:
父组件通过 属性 传递,子组件通过props接收(在子组件里写props['',''])
传递的值可以是多种类型----只不过要在子组件中说明type
-----props[
str:{
default:"",//默认值
type:String,//类型
required:true,//必填项
},
arrays:{
type:Array
},
propA:[String,number],//说明可能的多种类型
]
②子组件传到父组件:通过 $emit 事件 传递(情景:子组件触发事件,让父组件中的数据改变)
在子组件中定义一个点击事件触发后的方法:@click="fun()"
然后再methods:{
fun(){
this.$emit('事件名称',参数名);
}
}
---在父组件中的标签中,<父组件 @事件名称="fun()"></父组件>
---实现这个fun()就可以改变父组件的数据
父子组件之间的访问:
①子组件调用父组件方法(调用成员变量也行):
$parent:----this.$parent.父组件方法名(父组件调用子组件方法)
$root:----this.$root.根组件方法名(直接调用到根组件方法)
②父组件调用子组件方法(调用成员也可以):
在子组件的标签上加入ref属性:<子组件 ref="别名"></子组件>
通过:this.$refs.别名.子组件的方法名称()------就可以访问到子组件的方法
vue插槽的使用:(占位符/与java的工具类一样)
在子组件需要变化的位置加入:<solt></solt>
在父组件中:
<子组件>写入想要替换的标签</子组件>------->实例:
<子组件><button>提交</button></子组件>
-----这时子组件中的<solt>默认值</solt>----->替换<button>提交</button>
------默认值可以不写
假设:子组件中声明多个插槽---就给插槽起个名字---><solt name="one">默认值</solt>
父组件使用时:
老版本:
<button slot="noe">提交</button>
----->就只会替换相应名字的插槽
(建议使用)新版本:
<template v-slot:one>
<button >提交</button>
</template>
----->就只会替换相应名字的插槽
----引用插槽组件数据(使用情景:子组件数据不变,样式改变):
----> <solt :user="user"></solt>
父组件中引用:<template v-slot:one="user'>------->user可以随便定义
<button >{{user.user.name}}</button>
</template>
vue生命周期:
beforeCreate() {
console.log('实例刚刚被创建');
},
created() {
console.log('实例已经创建完成');
},
beforeMount() {
console.log('模板编译之前');
},
mounted() {
console.log('模板编译完成,经常使用');
},
beforeUpdate() {
console.log('数据更新之前');
},
updated() {
console.log('数据更新完成');
},
activated() {
console.log('keep-alive 缓存的组件激活时调用');
},
deactivated() {
console.log('keep-alive 缓存的组件停用时调用');
},
beforeUnmount() {
console.log('实例销毁之间');
},
unmounted() {
console.log('实例销毁完成');
},
封装网络请求(axios)
创建一个js文件:
import axios from 'axios';
//创建实例
const instance = axios.create({
baseURL:'http://api.eduwork.cn/admin',
timeout:5000
});
//请求拦截
instance.interceptors.request.use(
config=>{
return config;
},
err =>{
return Promise.reject(err);
}
);
//响应拦截
instance.interceptors.response.use(
response =>{
console.log(response);
return response;
},
err =>{
return Promise.reject(err);
}
);
//get请求
export function get(url, params){
return instance.get(url, {
params
})
}
export function post(url, data) {
return instance.post(url, data, {
transformRequest:[
function(data){
let str = '';
for(let key in data){
str += encodeURIComponent(key) +
'='
+ encodeURIComponent(data[key]) + '&'
}
console.log(str);
return str;
}
],
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
});
}
路由(Rounter)
创建项目时可选择安装路由
第一步安装路由
第二步创建路由:在router/index.js中---->
//引入依赖
import { createRouter, createWebHistory } from 'vue-router'
//组件引入
import Home from '../views/Home.vue'
//路由地址
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
//注意:这样写就不需要像上面一样引入组件:这种方式是懒加载,常用
component: () => import('../views/About.vue')
}
]
//创建路由
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
//暴露路由
export default router
第三步:在main.js中引入router.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
createApp(App).use(router).mount('#app')
第四步:在App.vue中使用路由
使用router-link标签进行路由:
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
使用 <router-view/>标签进行组件内容展示
下面两个样式,可以对路由样式进行修改:
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
也可以自定义样式active-class(优先级不够:!important):
<router-link active-class="" to=""></router-link>
自定义router-link标签:使用插槽------>
<router-link active-class="" to="" v-solt="name"><button>插槽</button></router-link>
嵌套子路由:访问时:/home/test
const routes = [
{
path: '/home',
name: 'Home',
component: Home,
children:[
{
path:'test',
component:''
}
]
},
{
path: '/about',
name: 'About',
//注意:这样写就不需要像上面一样引入组件:这种方式是懒加载,常用
component: () => import('../views/About.vue')
}
]
动态路由和传递参数:模板只使用一个(只是数据变化)
传递参数两种方式:
params方式:适用传递一个值
第一步:在path中加入参数:(:id)
{
path: '/test/:id',
//注意:这样写就不需要像上面一样引入组件:这种方式是懒加载,常用
component: () => import('../views/Test.vue')
}
第二步:传参:
<router-link :to="'/test'+id" ></router-link>
第三步:在模板中获取参数id,对参数进行判断显示
{{$route.params.id}}
query方式:适用传递多个值
第一步:不用写参数名
{
path: '/test',
//注意:这样写就不需要像上面一样引入组件:这种方式是懒加载,常用
component: () => import('../views/Test.vue')
}
第二步:传参:
<router-link :to="/test?id=1&name=2" ></router-link>
json传递:
<router-link :to="{path:"/test",query:{id:1,name:'2'}}" ></router-link>
第三步:在模板中获取参数|
{{$route.query.id}}
{{$route.query.name}}
注意:在标签属性中使用$router,在标签内容中使用$route
<button @click="$router.push("/test")">{{$route.query.id}}</button>
路由重定向和别名:
以下是重定向到根目录‘/’
①根据路径跳转:
{
path: '/test',
redirect:'/',
//注意:这样写就不需要像上面一样引入组件:这种方式是懒加载,常用
component: () => import('../views/Test.vue')
}
②根据名字跳转
{
path: '/test',
redirect:{name:'Root'},
//注意:这样写就不需要像上面一样引入组件:这种方式是懒加载,常用
component: () => import('../views/Test.vue')
}
别名:访问时可以使用别名:/test或者/a或者/b,都可以访问组件Test.vue
{
path: '/test',
alias:['a','b'],
//注意:这样写就不需要像上面一样引入组件:这种方式是懒加载,常用
component: () => import('../views/Test.vue')
}
导航守卫(路由的拦截器):在router/index.js中添加(全局使用)-->是回调函数
前置守卫:
router.beforeEach((to,from)=>{
return false;//代表不给跳转
})
后置钩子:
router.afterEach((to,from)=>{
return false;//代表不给跳转
})
局部使用:直接使用到组件中(Test.vue)-->是一个方法
前置守卫:
router.beforeEach(to,from){
return false;//代表不给跳转
}
后置钩子:
router.afterEach(to,from){
return false;//代表不给跳转
}
keep-alive和router的配合使用:
缓存组件,这样路由跳转时就不会被一直创建和销毁了,直接使用缓存就行了,提高效率
使用插槽:使用时直接复制就行
<router-view v-slot="{ Component }">
<transition>
<keep-alive>
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
使用keep-alive时,会触发以下生命周期的方法----->
activated() {
console.log('keep-alive 缓存的组件激活时调用');
},
deactivated() {
console.log('keep-alive 缓存的组件停用时调用');
},
Vuex (状态管理):超全局变量、响应式(一个改变、所有改变、所有组件都可以用这个变量)
相似:cookie、session
使用场景:用户登录的状态、用户名称、头像
安装:npm i vuex
创建项目时就安装:在store/index.js里面--->
import { createStore } from 'vuex'
export default createStore({
state: {
num:0
},
mutations: {//一般使用修改值
add(state,参数){}//自动将上面的state的值传递到方法中
},
getters:{//计算属性
add(state,参数){}//自动将上面的state的值传递到方法中
},
actions: {//异步请求后端时使用,可以使用以上所有属性:getters、mutations等
demo(context){
context.state.num;
}
},
modules: {//可定义多个模块
//用户模块
user:{
state: { },
mutations: {},
}
}
})
方法中就使用'this.$strore.getters.方法名',标签中就使用'$strore.getters.方法名'
①使用state:{}:--->
<h1>{{$store.state.变量}}</h1>
②使用mutations: {}:------->
使用this.$strore.commit('方法名add')进行改变
-----传递一个参数:this.$strore.commit('方法名add',参数)
-----传递多个参数:this.$strore.commit('方法名add',参数对象)
③使用:getters:{}---->
this.$strore.getters.方法名
④使用:actions:{}----->
this.$strore.dispatch('demo',参数)
⑤使用modules: {}---->
this.$strore.state.user.属性名
devtools工具查看状态管理:浏览器中下载插件
组合API(CompositionAPI):
第一步:import {reactive,computed} form 'vue'
第二步:
export default{
setup(){//组合api入口
const data=reactive({
count:0,
double:computed(()=>data.count*2)
})
function add(){
data.count++;
}
return {data,add}//一定要返回出去
}
}
第三步:
<h1>{{data.count}}</h1>
<h1>{{data.double}}</h1>
<button @click="add"></button>
setup(props,context){}----------------->在组件没创建之前就执行了,因此获取不到this
props参数:代表父组件传递的属性值
context参数:上下文
--------------->
setup(props, context) {
//获取属性值
context.attrs
//获取插槽值
context.slots
context.parent
context.root
//向父组件传递:通过事件
context.emit
//向父组件通信
context.refs
}
组合API常用API:
ref()函数用来给定的值创建一个响应式的数据对象,ref()的返回值是一个对象,这个对象上只包含一个.value属性.
reactive是用来创建一个响应式对象
将ref响应式数据挂载到reactive中,当把ref()创建出来值直接挂载到reactive()中时,会自动把响应式数据对象的展开为原始的值,不需要通过.value就可以直接访问到
双向绑定
toRefs()解构响应式对象
readonly将响应式数据变回原使数据
访问路径:@----->代表src目录(绝对路径)
webpack在vue.config.js中配置别名:
module.exports={
// 修改webpack配置
configureWebpack:{
resolve:{
//起别名
alias:{
'assets':'@/assets',
'components':'@/components'
}
}
}
}
调用别名:~别名---->
①<img src="~assets/images/11.png">
②import HelloWorld from 'components/HelloWorld.vue'