我是靠谱客的博主 爱笑西牛,最近开发中收集的这篇文章主要介绍Vue学习笔记Vue学习笔记,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Vue学习笔记

Vue CLI脚手架文件结构

关于不同版本的Vue

  • vue.js和vue.runtime.xxx.js的区别:
    • vue.js是完整版的Vue,包含:核心功能+模板解析器
    • vue.runtime.xxx.js是运行版的Vue,只包含核心功能,没有模板解析器
  • 因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用render函数接收到createElement函数去指定具体内容

vue.config.js配置文件

  • 使用vue inspect > output.js 可以查看vue脚手架的默认配置

  • 使用vue.config.js可以对脚手架进行个性化定制,具体见:https://cli.vuejs.org/zh

ref属性

  • 被用来给元素或子组件注册引用信息(id的替代者)

  • 应用在html标签上获取的是真实的DOM元素,应用在组件标签上是组件实例对象(VC)

  • 使用方法:

    • 打标识:<h1 ref="xxx"></h1><School ref="xxx"></School>
      获取:this.refs.xxx
      

配置项props

功能:让组件接收外部传过来的数据

1.传递数据:<Demo name="xxx"/>
2.接收数据:
	方式一(只接收):
		props:['name']
	方式二(限制类型):
		props:{
			name:String
		}
	方式三(限制类型、限制必要性、指定默认值):
		props:{
			name:{
				type:String,//类型
				required:true,//必要性
				default:'xxx',//默认值
			}
		}

props是只读的,Vue底层会监听对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那就复制props的内容到data中,然后去修改data中的内容

mixin(混入)

功能:可以把多个组件共用的配置提取成一个混入对象

使用方法:

1.定义混入
{
    data(){...},
    methods:{...},
    ...
}
2.使用混合
	(1)全局混入:Vue.mixin(xxx)2)局部混入:mixins:['xxx']

插件

功能:用于增强Vue

本质:包含install方法的一个对象,install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据

定义插件:

对象.install=function(Vue,options){
    //1.添加全局过滤器
    Vue.filter(...)
    //2.添加全局指令
    Vue.directive(...)
    //3.配置全局混入
    Vue.mixin(...)
    //4.添加实例方法
    Vue.prototype.$myMethod=function(){...}
    Vue.prototype.$myProperty=xxx
}

使用插件:

import xxx from './plugins'

Vue.use(xxx)

scoped样式

功能:让样式局部生效,防止冲突

写法:

<style scoped>
.
</style>

ToDo List-1.0案例

  • 组件化编码流程:
    • 拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突。
    • 实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:
      • 一个组件在用:放在组件自身即可
      • 一些组件在用:放在他们共同的父组件上
    • 实现交互:从绑定事件开始
  • props适用于:
    • 父组件==》子组件 通信
    • 子组件==》父组件 通信(要求父组件事先给子组件传函数)
  • 使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是不可以修改的。
  • props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做。

webStorage

  • 存储内容大小一般支持5MB左右(不同浏览器可能不一样)
  • 浏览器端通过Window.sessionStorage和Window.localStorage属性来实现本地存储机制
  • 相关API:
    • xxxStorage.setItem(‘key’,‘value’):该方法接收一个键值对,会把键值对添加到存储中,如果键存在,则更新其值
    • xxxStorage.getItem(‘key’):该方法接收一个键名作为参数,返回对应的值
    • xxxStorage.removeItem(‘key’):该方法接收一个键名作为参数,并把该键值对从存储中删除
    • xxxStorage.clear():该方法会清空存储中的所有数据
  • 说明:
    • SessionStorage存储的内容会随着浏览器窗口关闭而消失
    • LocalStorage存储的内容,需要手动清除才会消失
    • xxxStorage.getItem(‘key’)如果xxx对应的value获取不到,会返回null
    • JSON.parse(str)/JSON.stringfy(obj)可以处理存储的json样式的字符串

组件的自定义事件

  • 一种组件间通信的方式,适用于:子组件===》父组件

  • 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)

  • 绑定自定义事件:

    • 第一种方式:在父组件中

      • <Demo @自定义事件名="函数"/>或者<Demo v-on:自定义事件名="函数"/>
        
    • 第二种方式,在父组件中:

      • <Demo ref="demo"/>
        ...
        mounted(){
        	this.$refs.demo.$on('自定义事件名',函数)
        }
        
    • 若想让自定义事件只能触发一次,可以用once修饰符或$once方法

  • 触发自定义事件:this.$emit(‘自定义事件名’,参数)

  • 解绑自定义事件:this.$off(‘自定义事件名’)

  • 组件上也可以绑定原生DOM事件,需要使用native修饰符

  • 注意:通过this. r e f s . x x x . refs.xxx. refs.xxx.on()绑定自定义事件时,回调要么配置在methods中,要么使用箭头函数,不然this的指向会出问题。

全局事件总线(GlobalEventBus)

  • 一种组件间通信的方式,适用于任意组件间通信

  • 添加全局事件总线:

    • new Vue({
        ...
        beforeCreate() {
      		Vue.prototype.$bus=this //添加全局事件总线,$bus就是当前应用的vm	
      	},
      })
      
  • 使用事件总线

    • 接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身

      • methods(){
        	demo(data){...}
        }
          ...
        mounted(){
            this.$bus.$on('xxx',this.demo)
          }
        
    • 提供数据:

      • this.$bus.$emit('xxx',数据)
        
  • 最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件

消息订阅与发布(pubsub)

了解即可,全局事件总线更推荐

  • 一种组件间通信的方式,适用于任意组件间通信

  • 使用步骤:

    • 安装pubsub:npm i pubsub-js

    • 引入:import pubsub from pubsub-js

    • 接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身

      • methods(){
        	demo(data){...}
        }
        ...
        mounted(){
          this.psbId=pubsub.subscribe('xxx',this.demo)//订阅xxx消息
        }
        
    • 提供数据:B组件发布xxx消息,订阅xxx消息的组件会响应

      • pubsub.publish('xxx',数据)
        
    • 最好在beforeDestroy钩子中,用pubsub.unsubscribe(psbId)取消订阅

nextTick

1.语法:this.$nextTick(回调函数)

2.作用:在下一次DOM更新结束后执行指定的回调

3.什么时候用:当数据改变后,要基于更新后的DOM进行某些操作时,要在nextTick所指定的回调函数中执行

Vue封装的过渡与动画

1.作用:在插入、更新或移除DOM元素时,在合适的时候给元素添加样式类名

2.[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t8YWx8VR-1645255867030)(C:UsersluffyDesktopluffynoteVue.assetsimage-20210922164542119.png)]

3.写法:

  • 准备好样式:
    • 元素进入的样式:
      • v-enter:进入的起点
      • v-enter-active:进入过程中
      • v-enter-to:进入的终点
    • 元素离开的样式
      • v-leave:离开的起点
      • v-leave-active:离开过程中
      • v-leave-to:离开的终点
  • 使用transition包裹要过渡的元素,并配置name属性
<transition name="hello">
	<h1 v-show="isSHow">
    你好
  </h1>
</transition>

3.若有多个元素需要过渡,则需要使用 transition-group 标签,且每个元素要指定key

Vue脚手架配置代理

方法一

在vue.config.js中添加如下配置:

devServer:{
	proxy:"http://localhost:5000"
}

说明:

  • 优点:配置简单,请求资源时直接发送给前端(8080)即可
  • 缺点:不能配置多个代理,不能灵活的控制请求是否走代理
  • 工作方式:若按照上述配置代理,当请求了前端不存在的资源时,那么该请求会转发给服务器(优先配置前端资源)

方法二

编写vue.config.js配置具体代理规则:

module.exports = {
  devServer: {
    proxy: {
      'api1': {//匹配所有以'/api1'开头的请求路径
        target:'http://localhost:5000',//代理目标的基础路径
        changeOrigin:true,
        pathRewrite:{'^/api1':''}
      },
       'api2': {//匹配所有以'/api2'开头的请求路径
          target:'http://localhost:5000',//代理目标的基础路径
          changeOrigin:true,
          pathRewrite:{'^/api2':''}
      },
    }
  }
}

说明:

  • 优点:可以配置多个代理,且可以灵活的控制请求是否走代理
  • 缺点:配置略微繁琐,请求资源时必须加前缀

Vuex

1.概念

专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对Vue应用中多个组件的共享状态进行集中式管理(读、写),也是一种组件间通信的方式,且适用于任意组件间通信。

2.什么时候使用Vuex

  1. 多个组件依赖于同一状态
  2. 来自不同组件的行为需要变更同一状态

3.原理图

vuex

4.搭建Vuex环境

  1. 创建文件:src/store/index.js

    import Vuex from 'vuex'
    import Vue from 'vue'
    
    Vue.use(Vuex)
    
    //准备actions——用于响应组件中的动作
    const actions={}
    //准备mutations——用于操作数据(state)
    const mutations={}
    //准备state——用于存储数据
    const state={}
    
    //创建并暴露store
    export default new Vuex.Store({
      actions,
      mutations,
      state
    })
    
    
  2. 在main.js中创建vm时传入store配置项

    import Vue from "vue";
    import App from "./App.vue";
    import ElementUI from "element-ui";
    import 'element-ui/lib/theme-chalk/index.css'
    import store from './store'
    
    Vue.config.productionTip = false;
    Vue.use(ElementUI);
    
    
    new Vue({
      render: (h) => h(App),
      store,
      beforeCreate(){
        Vue.prototype.$bus=this//添加全局事件总线
      }
    }).$mount("#app");
    

5.基本使用

  1. 初始化数据、配置actions、配置mutations

    import Vuex from 'vuex'
    import Vue from 'vue'
    
    Vue.use(Vuex)
    
    //准备actions——用于响应组件中的动作
    const actions={
      jia(context,value){
        context.commit('JIA',value)
      },
      jiaOdd(context,value){
        if(context.state.sum % 2){
          context.commit('JIA',value)
        }
      },
      jiaWait(context,value){
        setTimeout(()=>{
          context.commit('JIA',value)
        },500)
      },
      jian(context,value){
        context.commit('JIAN',value)
      }
    }
    //准备mutations——用于操作数据(state)
    const mutations={
      JIA(state,value){
        state.sum+=value
      },
      JIAN(state,value){
        state.sum-=value
      }
    }
    //准备state——用于存储数据
    const state={
      sum:0
    }
    
    //创建并暴露store
    export default new Vuex.Store({
      actions,
      mutations,
      state
    })
    
  2. 组件中使用

    <template>
      <div>
        
        <el-select v-model="selectValue">
          <el-option :value="1">1</el-option>
          <el-option :value="2">2</el-option>
          <el-option :value="3">3</el-option>
        </el-select>
        <el-group>
          <el-button @click="increment">+</el-button>
          <el-button @click="decrement">-</el-button>
          <el-button @click="incrementOdd">当前求和为奇数再加</el-button>
          <el-button @click="incrementWait">等一等再加</el-button>
        </el-group>
      </div>
    </template>
    
    <script>
    export default {
      name: "Counter",
      data() {
        return {
          selectValue: 0,
        };
      },
    
      methods: {
        increment() {
          this.$store.commit("JIA", this.selectValue);
        },
        decrement() {
          this.$store.commit("JIAN", this.selectValue);
        },
        incrementOdd() {
          this.$store.dispatch("jiaOdd", this.selectValue);
        },
        incrementWait() {
          this.$store.dispatch("jiaWait", this.selectValue);
        },
      },
    };
    </script>
    
    <style></style>
    
  3. 组件中读取vuex中的数据:$store.state.sum

  4. 组件中修改vuex中的数据: s t o r e . d i s p a t c h ( ′ a c t i o n 中 的 方 法 名 ′ , 数 据 ) 或 store.dispatch('action中的方法名',数据)或 store.dispatch(action,)store.commit(‘mutations中的方法名’,数据)

  5. 备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写dispatch,直接编写commit

6.getters的使用

  1. 概念:当state中的数据需要经过加工后再使用时,可以使用getters加工

  2. 在store.js中追加getters配置

    const getters = {
      bigSum(state){
        return state.sum*10
      }
    }
    //创建并暴露store
    export default new Vuex.Store({
      ...
      getters
    })
    
  3. 组件中读取数据:$store.getters.bigSum

7.四个map方法的使用

  1. mapState方法:用于帮助我们映射state中的数据为计算属性

    import {mapState} from 'vuex'
    
    computed: {
      //借助mapState生成计算属性:sum、school、subject(对象写法)
      ...mapState({sum:'sum',school:'school',subject:'subject'})
      //借助mapState生成计算属性:sum、school、subject(数组写法)
      ...mapState(['sum','school','subject'])
    }
    
  2. matGetters方法:用于帮助我们映射getters中的数据为计算属性

    import {mapGetters} from 'vuex'
    
    computed: {
      //借助mapGetters生成计算属性:bigSum(对象写法)
      ...mapGetters({bigSum:'bigSum'})
      //借助mapGetters生成计算属性:bigSum(数组写法)
      ...mapGetters(['bigSum'])
    }
    
  3. mapActions方法:用于帮助我们生成与actions对话的方法,即包含$store.dispatch(xxx)的函数

    import {mapActions} from 'vuex'
    
    methods:{
      //借助mapActions生成函数(对象写法)
      ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
      //借助mapActions生成函数(数组写法)
    }
    
  4. mapMutations方法:用于帮助我们生成与mutations对话的方法,即包含$store.commit(xxx)的函数

      //借助mapMutations生成函数(对象写法)
      ...mapMutations({increment:'JIA',decrement:'JIAN'})
      //借助mapMutations生成函数(数组写法)
    

路由

  1. 理解:一个路由(route)就是一组映射关系(key-value),多个路由需要路由器(router)进行管理
  2. 前端路由:key是路径,value是组件

1.基本使用

  1. 安装vue-router,命令:npm i vue vue-router

  2. 编写router配置项,src/router/index.js

    import Vue from 'vue'
    //引入VueRouter
    import VueRouter from 'vue-router'
    //引入自己的路由组件
    import About from '../components/About'
    import Home from '../components/Home'
    
    //创建路由实例对象,去管理一组一组的路由规则
    Vue.use(VueRouter)
    const router = new VueRouter({
      routes:[
        {path:'/about',component:About},
        {path:'/home',component:Home}
      ]
    })
    
    export default router
    
  3. App.vue中添加router

  4. 简单实现切换

    <router-link to="/about">About</router-link>
    <router-link to="/home">Home</router-link>
    
  5. 指定路由内容展示区域

    <router-view></router-view>
    

2.多级路由

  1. 配置路由规则,使用children配置项

    routes:[
      {
        path:'/about',
      	component:About
      },
      {
        path:'/home',
        component:Home,
        children:[
          {
            path:'news',
            component:News
          },
          {
            path:'message',
            component:Message
          }
        ]
      }
    ]
    
  2. 跳转(要写完整路径):

    <router-link to="/home/news"></router-link>
    

3.路由的query参数

  1. 传递参数
<!--跳转并携带query参数,to的字符串写法-->
<router-link :to="/home/message/detail?id=666&title=xxx">跳转</router-link>

<!--跳转并携带query参数,to的对象写法-->
<router-link
	:to="{
       path:'/home/message/detail',
       query:{
       	id:666,
       	title:'xxx'
       }
       }"
             >跳转</router-link>
  1. 接收参数
$route.query.id
$router.query.title

4.命名路由

  1. 作用:可以简化路由的跳转
  2. 使用:略

5.路由的params参数(RESTful)

  1. 配置路由,声明接收params参数
{
  path:'home',
  component:Home,
  children:[
    {
      path:'news',
      component:News
    },
    {
      component:Message,
      children:[
        name:'xiangqing',
        path:'detail/:id/:title',//使用占位符声明接收params参数
        component:Detail
      ]
    }
  ]
}
  1. 传递参数
<!--跳转并携带params参数,to的字符串写法-->
<router-link :to="/home/message/detail/666/xxx">跳转</router-link>

<!--跳转并携带params参数,to的对象写法-->
<router-link
	:to="{
       name:'xiangqing',//对象写法一定要用name,不能用path
       params:{
       	id:666,
       	title:'xxx'
       }
       }"
             >跳转</router-link>
  1. 接收参数
$route.params.id
$route.params.title

6.路由的props配置

让路由组件更方便的接收参数

{
  name:'xiangqing',
  path:'detail/:id',
  component:Detail,
  //第一种写法:props值为对象,该对象中所有的key-value的组合最终都会通过props传给Detail组件
  //props:{a:900,b:800}
    
  //第二种写法:props值为布尔值,布尔值为true,则把路由收到的所有params参数通过props传给Detail组件
  //props:true
    
  //第三种写法:props值为函数,该函数返回的对象中每一组key-value都会通过props传给Detail组件
  props(route){
    return{
      id:route.query.id,
      title:route.query.title
    }
  }
}

7.<router-link>的replace属性

  1. 作用:控制路由跳转时操作浏览器历史记录的模式
  2. 浏览器的历史记录有两种写入方式:分别为push和replace,push是追加历史记录,replace是替换当前记录,路由跳转默认为push。
  3. 如何开启replace模式:<router-link replace …></router-link>

8.编程式路由导航

  1. 作用:不借助<router-link>实现路由跳转,让路由跳转更加灵活
  2. 具体代码
//$router的两个API
this.$router.push({
  name:'xiangqing',
  params:{
    id:xxx,
    title:xxx
  }
})

this.$router.replace({
  name:'xiangqing',
  params:{
    id:xxx,
    title:xxx
  }
})

9.缓存路由组件

  1. 作用:让不展示的路由保持挂载,不被销毁
  2. 具体编码:
<keep-alive include="News">
  <!--News为对象-->
	<router-view></router-view>
</keep-alive>

10.两个新的生命周期钩子

  1. 作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态
  2. 具体名字:
    1. activated:路由组件被激活时触发
    2. deactivated:路由组件失活时触发

11.路由守卫

  1. 作用:对路由进行权限控制
  2. 分类:全局守卫、独享守卫、组件内守卫
  3. 全局守卫:
//全局前置守卫,初始化时执行、每次路由切换前执行,写在index.js中
router.beforeEach((to,from,next)=>{
	if(to.meta.xxx){}//判断当前路由是否需要进行权限控制
	else{
		next()//放行
}
})

//全局后置守卫,初始化时执行、每次路由切换后执行,写在index.js中
router.afterEach((to,from,next)=>{
	if(to.meta.xxx){}//控制操作
	else{}
}
})
  1. 独享守卫:
//路由属性内添加
routes:[
  {
    path:'/about',
  	component:About,
    //没有afterEnter
		beforeEnter(to,from,next){
			console.log('beforeEnter',to,from)
		}
  },
  {
    path:'/home',
    component:Home,
    children:[
      {
        path:'news',
        component:News
      },
      {
        path:'message',
        component:Message
      }
    ]
  }
]
  1. 组件内守卫
//进入守卫,通过路由规则,进入该组件时被调用
beforeRouteEnter(to,from,next){
  
},
//离开守卫,通过路由规则,离开该组件时被调用
beforeRouterLeave(to,from,next){
  
}

12.路由器的两种工作模式

  1. 对于一个url来说,上什么是hash值?——#以及其后面的内容就是hash值
  2. hash值不会包含在HTTP请求中,即:hash值不会带给服务器
  3. hash模式:
    1. 地址中永远带着#,不美观
    2. 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法
    3. 兼容性好
  4. history模式:
    1. 地址干净,美观
    2. 兼容性和hash模式相比略差
    3. 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题

最后

以上就是爱笑西牛为你收集整理的Vue学习笔记Vue学习笔记的全部内容,希望文章能够帮你解决Vue学习笔记Vue学习笔记所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部