Vue笔记

vue 基础

常用指令:

v-model 数据双向绑定

v-bind 修改属性值 :

v-on 事件绑定 @

v-text 渲染纯文本

v-html 渲染超文本

v-show 控制显示隐藏 display

v-if 控制显示隐藏 移除元素

v-for 列表循环

v-bind:key 独立索引值

MVVM 模型


M 模型 ========》VM vue 对象 《=========V 视图


数据代理:利用 Object.defineProperty 实现 方便操作 data 数据


事件修饰符

prevent: 阻止默认事件
stop: 阻止事件冒泡

once:事件触发一次

获取元素

可以用来操作Dom

标签内设置名称
ref='title'
获取
this.$refs.title

✨传值操作

props

让组件接受外部传进来的数据

父传子

写在子组件,并对接受类型限制
 props: {
    name: String,
    age: Number,
  },
完整写法
props: {
    name: {
      tpye: String,
      required: true, //是否为必须
    },
    age: {
      type: Number,
      default: 99, //默认
    },
:age='18'
利用动态绑定v-bind传值可参与计算

子传父

在父中定义一个函数,在子中去调用父的函数

父亲
receive(x) {
   console.log('@@@app',x);
},
儿子
props: ["receive"],
methods: {
  add(e) {
    const obj = { id: nanoid(), title:e.target.value, done: false };
    this.receive(obj);
  },
},
消息订阅与发布

收参数一方订阅消息,发参数一方发送消息

安装第三方库 npm i pubsub-js

引入:import pubsub from "pubsub-js";

订阅消息:

    this.pubId = pubsub.subscribe("hello", (msgName, data) => {
      console.log(data);
    });

发送消息:

    sentName() {
      pubsub.publish("hello", "@@@");
    },
组件自定义事件

通过 v-on:name 绑定自定义事件 通过 this.$emit('name') 调用

解绑:this.$off('name')

解绑多个: this.$off(['name1','name2'])

通过父组件向子组件绑定自定义事件实现 子组件向父组件传值

✨优势:不用在子组件添加props

父组件
<Student v-on:customEvents="demo"></Student>
  methods: {
    demo(val) {
      console.log("触发了自定义事件customEvents", val);
    },
  }

✨子组件通过this.$emit('name')调用

子组件
<button @click="sendStudentName">点我触发自定义事件customEvents</button>
  methods: {
    sendStudentName() {
      this.$emit("customEvents",this.name);    
    },
  },

✨全局事件总线(常用)

可以任意组件通信,传值操作

main.js 里,设置全局事件总线

new Vue({
  render: (h) => h(App),
  beforeCreate() {
    Vue.prototype.$bus = this;},
}).$mount("#app");

收参数一方:绑定事件总线

  mounted() {
    this.$bus.$on("hello", (val) => {
      console.log("school收到了" + val);
    });
  },

发送参数一方

    sendStudentNameToSchool() {
      this.$bus.$emit("hello", this.name);
    },

mixin 混入

两个组件共享一个配置

单独写一个js文件,存组件公用的代码块

属性以原本为主,mounted等钩子都实现

引入
import { mixin } from "../mixin";
配置
mixins: [mixin],
使用
 <div @click="showName">学生姓名:{{ name }}</div>

plugins 插件

本质为一个含有install的对象,第一个参数为Vue

使用方法
Vue.use(name)

给Vue动态添加数据:this.$set('target','key','value')

✨this.$nextTick(()=>{})

下一次DOM更新结束后执行回调

数据改变后进行操作,例如获取焦点

Vue动画

<transition name='' appear></transition> 包裹一个标签

appear: 开始时页面有动画

.vue(name)-enter-active {
}
.vue-leave-active {
}
@keyframes identifier {
  from {
  }
  to {
  }
}

过渡写法:

.vue-enter{
	//进入的起点
}
.vue-enter-to{
	//进入的终点
}
.vue-leave{
	//离开的起点
}
.vue-leave-to{
	//离开的终点
}
.vue-enter-active,.vue-leave-active{
	//整个过度的时间
}

第三方动画库:

引入:

import 'animate.css'

使用:

<transition
      name="animate__animated animate__bounce"
      enter-active-class="animate__backInLeft"
      leave-active-class="animate__backOutLeft"
>
      <div v-show="isShow">
       
      </div>
</transition>

✨Vue中的ajax请求

引入axios库 npm i axios

解决跨域问题:开启代理服务器
方式一:devServer.proxy

vue.config.js

module.exports = {
  devServer: {
  	//目标地址
    proxy: "http://localhost:5000",
  },
};

请求:public目录中已有的不会转发给5000端口

axios.get("http://localhost:8080/students") 填写目前网页的端口

方式二

module.exports = {
  devServer: {
    proxy: {
      '/api': {     //前缀
        target: '<url>',   //目标基础路径
        pathRewite:{'^/url前缀': ''}  //传到后将前缀替换为空字符串
        ws: true,  //支持websocket
        changeOrigin: true  //控制请求头的host值
      },
      '/foo': {
        target: '<other_url>'
      }
    }
  }
}

请求:

axios.get("http://localhost:8080/api/students")


vue插槽

默认

<slot>默认值,没有传东西时出现</slot>

具名插槽

<slot name = '123'>

使用

<h3 slot = '123'>

<template v-slot:footer>

作用域插槽

数据在组件自身,结构需要使用者决定

将games传给使用者

<slot :games = 'games'></slot>

使用者:

<div>
    <tempalte scope = '{games}'>	解构赋值
   
    </tempalte>
</div>

Vue-x

专门在Vue中实现集中式状态数据管理的一个Vue插件

多个组件的共享状态进行集中式的管理(读/写)

适用于任意组件间通信

什么时候使用:

不同组件的我行为需要改变同一状态

多个组件依赖于同意状态(数据)

原理:

image-20230329111041081

1.安装:

npm i vuex@3

vue2使用vuex3版本 ,vue3使用vuex4版本

2.使用:

main.js中

import Vuex from 'vuex'
Vue.use(Vuex)

3.创建store目录下的index文件

image-20230418154803472

//创建vuex中store
//引入Vuex
import Vuex from "vuex";
import Vue from "vue";
Vue.use(Vuex);
//actions响应组件中的动作
const actions = {};
//mutations操作数据
const mutations = {};
//state存储数据
const state = {};

//创建并且暴露store
export default new Vuex.Store({
  actions,
  mutations,
  state,
});

4.main.js中使用

import store from "./store/index";
new Vue({
 render: (h) => h(App),
 store,
}).$mount("#app");

actions中写业务逻辑

const actions = {
  incrementOdd(context, value) {
    setTimeout(() => {
      context.commit("INCTEMENT", value);
    }, 500);
  },
};

actions中没有操作逻辑,则直接对话commit

this.$store.commit("INCTEMENT", this.n);

组件中读取vuex数据:$store.state.sum

修改vuex中的数据:$store.dispatch('sum',value) / $store.cinnut(mutations,value)

vue.getters

加工state中的数据

//加工state中的数据
const getters = {
  bigSum() {
    return state.sum * 10;
  },
};
export default new Vuex.Store({
  ......
  getters,
});
mapState & mapGetter

帮助我怕们映射state中的数据为计算属性,从state中读取数据

1.引入

import { mapState } from "vuex";

2.使用

  computed: {
    ...mapState(["school", "subject"]),
    // ...mapState({ school: "school", subject: "subject" }),
  },
mapMutations & mapActions

生成对应的方法,方法中调用commit去联系mutations

1.引入

import { mapMutations } from "vuex";

2.使用

  methods: {
	key对应组件中方法,value对应mutations中方法
    ...mapMutations({ increment: "INCTEMENT", decrement: "DECREMENT" }),
  },
   传参需要在调用中传递
   <button @click="increment(n)">+</button>
Vuex模块化

1.index中配置模块化store

const countOption = {
    //开启mapState命名
  namespaced: true,
  actions: {},
  mutations: {},
  state: {},
  getters: {},
};

2.暴露

export default new Vuex.Store({
  modules: {
    countAbout: countOption,
    personAbout: personOption,
  },
});

3.组件中使用

简写:

使用…mapState

 methods: {
    ...mapMutations("countAbout", {
      increment: "INCTEMENT",
      decrement: "DECREMENT",
    }),
    ...mapActions("countAbout", { incrementOdd: "incrementOdd" }),
  },
  computed: {
    ...mapState("countAbout", ["sum", "school", "subject"]),
    ...mapGetters("countAbout", ["bigSum"]),
    // ...mapState({ school: "school", subject: "subject" }),
  },

纯生手写:

image-20230419171208920

Vue-router

安装 npm vue-router

vue2中安装router3

vue3中安装router4

1.main.js中引入并使用插件:

import Vue from "vue";
import App from "./App.vue";
//引入vue-router
import VueRouter from "vue-router";
//引入router配置文件
import router from "./router";

Vue.config.productionTip = false;
//应用插件
Vue.use(VueRouter);

new Vue({
  render: (h) => h(App),
  router,
}).$mount("#app");

2.配置路由:

在router文件夹中创建index.js

//引入Vuerouter
import VueRouter from "vue-router";
//引入组件
import About from "../components/About.vue";
import Home from "../components/Home.vue";
//暴露
export default new VueRouter({
  routes: [
    {
      path: "/about",
      component: About,
    },
    {
      path: "/home",
      component: Home,
    },
  ],
});

3.使用

    <router-link to="/about">about</router-link>
    <router-link to="/home">home</router-link>
    <router-view></router-view>
嵌套路由

配置子路由

  routes: [
    {
      path: "/about",
      component: About,
    },
    {
      path: "/home",
      component: Home,
      children: [
        {
          path: "news",
          component: News,
        },
      ],
    },
  ],

使用:

 <router-link to="/home/news">跳转News</router-link>
    <router-view></router-view>
路由传参
query方式;

发送方:

<router-link
          :to="{
            path: '/home/news/detail',
            query: {
              id: item.id,
              title: item.title,
            },
          }"
          >信息{{ item.id }}</router-link
        >

接收方:

    <ol>
      <li>{{ $route.query.id }}</li>
      <li>{{ $route.query.title }}</li>
    </ol>
params方式;

image-20230518203740570

路由的props

image-20230518204954676

路由replace

image-20230518205800825

编程式路由导航

image-20230520141424203

路由缓存

image-20230520141959124

路由生命周期:

路由组件独有的生命周期钩子

activated路由组件被激活时触发

deavtivated路由组件失活时触发

路由守卫:

前置守卫,初始化时被调用

router.beforeEach((to,from,next)=>{})

后置守卫,路由切换后调用

router.afterEach((to,from)=>{})

独享路由守卫

beforeEnter:

组件内路由守卫
history模式和hash模式

image-20230520154709085

Vue3
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值