• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
在赶路的我
博客园    首页    新随笔    联系   管理    订阅  订阅

Vue2脚手架

脚手架学习笔记

脚手架文件结构:

|-node_modules
|-public
  |-favicon.ico:页签图标
  |-index.html:主页面
|-src
  |-assets:这里存放静态资源的
  
  |-component:这里是放组件的
  
  |-App.vue:这里是统一管理所有组件的总组件

  |-main.js:这里是vue实例,也是整个项目的入口
|-.gitignore:git版本管制忽略的配置
|-babel.config.js:babel的配置文件,就是es6转es5
|-package.json:应用包配置文件
|-README.md:应用描述文件
|-package-lock.json:包版本控制文件

关于不同版本的Vue

1.关于不同版本的vue
vue.js是完整版的vue,包含:核心功能和模板解析器
vue.runtime.XXX.js是运行版本的vue,只包含:核心功能,但没有模板解析器
2.因为引入的是runtime.xxx.js没有模板解析器,所以不能使用template配置项(在vue实例中),需要使用render函数接收到的createElement函数去指定具体类容(在这儿createElement函数是以参数的形式出现的)

vue.config.js配置文件

> 使用vue inspect > output.js可以查看到Vue脚手架的默认配置
> 使用vue.config.js可以对脚手架进行个性化的定制(vue.config.js要放在与package.json同级的目录下),详情见:https://cli/vuejs.org/zh
> 使用他你可以定义入口和其他的默认路径,如果不设置就使用默认的,如果写了,则覆盖默认的

ref属性

1.被用来给元素或者子组件注册引用信息(id的代替者)
2.应用在html标签上获取真实的dom,应用在组件上是组件的实例对象(vc)
3.使用方式:
      打标识:<h1 ref="XXX"><h1/>  或者 <HelloWorld ref="xxx"><HelloWorld/>
      获取标识的dom:this.$refs.XXX

props配置

功能:让组件接收外面传过来的数据
  1.传递数据:<School name="张三" :age="23"/> 通过标签属性来传值
  2.接收数据:
        (1):props:['name','age']  只负责接收不做任何限制
        (2):props:{
                name:String,
                age:Number
              } 负责接收且指定接收的类型
        (3):props:{
                name:{
                  type:String,
                  required:true
                },
                age:{
                  type:Number,
                  default:21
                }
              }  负责接收且可以指定接收类型,是否强制需要,设置默认值
  
  备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,
        如果业务中必须要修改,可以将props中的数据赋值给data中,进而对data中的数据修改
        就不会发出警告,在这儿要注意的是,props中的数据要比data中先加载,所以props中的值keyi
        给data

mixin混合配置

功能:可以把多个组件公用的配置提取成一个混入对象
使用方式:
      1.第一步定义混合:  新建一个js  export const mixin = {
        data(){
          return{

          }
        },
        methods:{
          a(){

          }
        }
      }

    2.第二步:使用混入
              引入混合: import {XXX} from 'xxx'
             (1):全局混入:Vue.mixin(XXX)
             (2):局部混入:mixins:[xxx,xxx]

插件(plugins)

功能:用于增加Vue
本质:plugins是一个包含install方法的对象,install方法的第一个参数是Vue,第二个以后的参数是外部传进来的参数
定义一个插件:
    新建一个名为plugins的js文件,并且定义一个包含install方法的对象,并要求暴露出来
    方法名必须为install,这样才有效
    如:
    对象名.install = function(Vue,options){
      Vue.filter(),
      Vue.directive(),
      Vue.mixin(),
      Vue.prototype.(方法或者属性)=...
    }
  使用插件:1.在main.js引入插件的js文件 import plugines from 'xxx'
           2.Vue.use(plugines)
            3.使用插件中的方法,直接用this来引用,因为插件上的定义的方法都放在Vue的原型上,而vc的显示原型对象的隐式原型对象指向的是Vue的原型对象

scoped样式

lang是规定样式语言,默认为css,可以为less
但是解析less要用到less-loader,如果安装失败,就降一个版本
npm view less-loader versions 可以查看less-loader的所有版本
scoped的作用就是让组件之间的各个样式不冲突

自定义事件

1.自定义事件是一种组件之间通信的方式:子组件===》父组件
2.使用场景:A是父组件,B是子组件,B想给A传递数据,那么就要在A中给B绑定自定义事件(事件的回调在父组件中)
3.绑定自定义事件:
          (1):在子组件的标签上用v-on获者@来绑定自定义事件
          (2):第二种方式,在父组件中:使用this.$refs.xx.$on('自定义事件名',回调函数)
          (3):若想要自定义事件只触发一次,用once或者$once修饰
4.触发自定义事件:在子组件中this.$emit('自定义事件名',传递的参数)
5.解绑自定义事件:在子组件中this.$off('')
6.子组件标签上也可以使用原生的dom事件,但是要用native修饰(如果不修饰的话vue会当成自定义事件名),该事件会自动绑定在子组件的根div上,这也是组件只有一个根元素的原因之一
7.注意:在父组件中如果使用this.$refs.xx.$on()来绑定的自定义事件,回调函数如果直接写在后面,不写在methods中的话,要用箭头函数,原因是:箭头函数没有this,就会向上找this,也就是父组件的this

全局事件总线

全局事件总线可以实现任意组件之间的通信:
安装全局事件总线:在Vue实例里面的beforeCreate钩子函数中安装全局事件总线:
beforeCreate(){
  this.$bus=Vue.prototype
} 
这里在vue原型对象上加上一个$bus属性用来指定Vue实例,这样就可以在任意组件上可以使用$bus来使用Vue的实例对象以此来使用$on,$off,$emit来给vue实例绑定事件和触发事件,
又因为所有组件都指向Vue原型,所以可以通过每个组件的this对象来使用$bus使用$on,$off,$emit,所以组件之间就可以通过$bus来绑定事件,触发事件来通信
注意:在这里也可以通过组件的实例对象来代替vue实例
但是这样相对麻烦:const VC = Vue.extend({})
                  const demo = new VC()
                  此时demo就是组件的实例对象
                  Vue.prototype.$bus=demo

总结:1.全局事件总线是一种适用于任意组件之间的通信
  *      2.安装全局事件总线:new Vue({
  *      beforeCreate(){
  *      Vue.prototype.$bus=this
  * }
  * })
  * 在这里用$bus的原因是bus有总线的意思
  * 
  * 3.使用事件总线:1.接收数据:A组件想接收数据,在A组件中给$bus绑定自定义事件,事件的回调留在A组件中
  *                2.发送数据:B组件要给A组件发送数据,就在B组件中触发这个事件,把数据传给A组件
  * 4.最好在beforeDestory钩子函数中,用$off去解绑这个事件

vue动画和过渡效果

  1.作用:在插入,更新或者移除dom元素时候,在合适的时候给元素添加样式类名
  2.写法:
          1.css3动画和vue配合:
                定义css3动画,在要使用动画的元素上添加transition来包裹,如果有多个元素使用transition-group来包裹,
                然后使用v-enter-action和v-leave-action中的animation来定义动画的持续时间和其他属性,在使用transition-group时候需要给
                每个元素指定key
          2.vue自带的过渡
                定义元素进入起点和终点,定义元素离开的起点和终点
                v-enter{} v-enter-to{} v-leave{} v-leave-to{}
                然后在v-enter-active{} v-leave-active{}中使用transform指定过渡时间可是否匀速,或者在需要动画的css样式中添加transform来指定过渡时间和其他属性
            元素进入的样式:
              v-enter:进入的起点
              v-enter-active:进入的过程
              v-enter-to:进入的终点
            元素离开的样式:
              v-leave:离开的起点
              v-leave-active:离开的过程
              v-leave-to;离开的终点  
  3.使用<transition>包裹过渡的元素,并配置name属性
  4.备注:如果有多个元素需要过渡,则需要使用:<transtition-group>,且每个元素都要指定key值

vue axios请求跨域解决问题

  * 前端和后端通信的技术:xhr(xmlhttprequest)(js中自带的对象) fetch(window自带的对新,和xhr平级)
  * ajax:技术实现了网页的局部数据刷新,axios实现了对ajax的封装
  * axios:封装了ajax,axios是通过promise实现对ajax技术的一种封装,就像jQuery实现ajax封装一样
  * jauery:封装了ajax和操作dom的方法
  * vue-resource:vue中的通信方式,是vue的一个插件,npm install vue-resource 且要在main.js中Vue.use()来使用,这样vc和vm都可以使用
  *
  *在这里vue-resource和axios的使用的api是一样的,只不过vue-resource是通过this.$http来调用的 

  *使用这些通信技术,在请求后端接口时候,会存在跨域问题:有以下解决方案:
  * 1.后端允许跨域请求(如果是spring,就在接口上添加@CrossOr...,但是这样不安全)
  * 2.jsoup(不太了解)
  * 3.vue的配置代理
  *      方式一:在vue.config.js中添加以下配置:
  *               devServer: {
                      proxy: 'http://localhost:8001'
                  }
                  注意点: 1.优点:配置简单 
                          2.缺点:不能配置多个代理,不能灵活的控制是否直接请求远程服务,而不是优先本地的vue资源 
                          3.工作方式:如果请求的资源前端vue项目也有,请求直接不会给远程服务,直接走本地的vue中的public资源
          方式二:在vue.config.js中添加以下完整配置
                    devServer: {
                        proxy: {
                          //'/api'是用于提示vue这个请求是远程的,不要请求本地的vue
                          '/api': {
                            target: 'http://localhost:8001',//请求的远程的服务器
                            pathRewrite:{'^/api':''},//将带有前缀的请求中的前缀去掉,以免带到服务器出现404(这里是用正则表达式来去掉的)
                            ws: true,//用于支持websocket的
                            changeOrigin: true//如果为true(默认为true)在远程服务端收到的请求地址就是target中的远程服务器的地址,反之则为本地vue的端口号
                        }
                      }
                    }
                    注意点:1.优点:可以匹配多个代理,且可以灵活的控制请求是走远程服务器还是走本地的vue
                            2.缺点:配置略微繁琐,请求资源时候必须加前缀

Vue插槽

  * 插槽总结:
          *      1.作用:让父组件可以向子组件指定位置插入html结构,也是一种组件之间通信的方式,,适用于父组件===》子组件
          *      2.分类:默认插槽,具名插槽,作用域插槽
          *      3.使用方式:
          *        1.默认插槽:
          *                    子组件  <template>
                                          <div>
                                            <ul>
                                              <h1>默认插槽</h1>
                                              <!-- 插槽位置 -->
                                              <!-- 这是默认的组件插槽,没有指定任何属性 -->
                                              <slot></slot>
                                            </ul>
                                          </div>
                                        </template>

                                父组件      <HelloWorld>
                                              <!-- 被组件标签包裹的结构都会先在组件使用者解析完之后被塞到组价定义的插槽位置 -->
                                              <li v-for="(k,index) in kuangjia" :key="index">{{k}}</li>
                                            </HelloWorld>
                                
                    2.具名插槽:
                                  子组件  <template>
                                              <div>
                                                <ul>
                                                  <h1>具名插槽</h1>
                                                  <!-- 插槽位置 -->
                                                  <!-- 这是具名插槽,指定了name属性 -->
                                                  <slot name="demo1"></slot>
                                                  <slot name="demo2"></slot>
                                                </ul>
                                              </div>
                                          </template>
父组件      <HelloWorld1>
    <!-- 具名插槽需要指定插槽的名字才能有效 -->
    <!-- 写法一 -->
    <li slot="demo1" v-for="(k,index) in kuangjia" :key="index">{{k}}</li>

    <!-- 写法二 :     v-slot:插槽名  注意这里插槽名不能加双引号,且需要template来包裹 当然这里也可以写成slot=''-->
    <!-- 如果这里插入的结构很多,不需要在外面添加一个div包裹在插入,直接使用template即可 -->
    <template v-slot:demo2>
        <hr>
        <li v-for="(k,index) in kuangjia" :key="index+4">{{k}}</li>
    </template>

</HelloWorld1>

3.作用域插槽   
理解:数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。
子组件
<template>
    <div>
        <ul>
            <h1>作用域插槽</h1>
            <!-- 插槽位置 -->
            <!-- 作用域插槽就是数据不在使用改组件的组件中,而是在当前组件中 ,父组件只需要管结构,数据在子组件中,此时就需要子组件的插槽传给父组件
父组件利用scope来拿到数据,这就是所谓的作用域插槽
-->
            <!-- 例如:这里要在父组件中展示food -->
            <!-- :food='food'将数据传给父组件 -->
            <slot name="demo1" :food="food" ></slot>
            <slot name="demo2" :food="food" ></slot>

        </ul>
    </div>
</template>

父组件
<HelloWorld2>
    <!-- 这里要用template包裹结构,利用scope来收到子组件传递过来的food数据并渲染 -->
    <!-- 写法一 -->
    <template scope="data" slot="demo1">
        <!-- 这里data是一个包含子组件传过来的数据对象 ,原因是有可能传递多个数据-->
        {{data}}
        <li v-for="(k,index) in data.food" :key="index+8">{{k}}</li>
    </template>

    <!-- 写法二 -->
    <template slot-scope="data" slot="demo2">
        <!-- 这里data是一个包含子组件传过来的数据对象 -->
        {{data}}
        <li v-for="(k,index) in data.food" :key="index+12">{{k}}</li>
    </template>
</HelloWorld2>
* 

vuex

/**
* vuex简介:
*      1.专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中的多个组件的共享状态进行集中式管理(读写),也是一种组价间通信的一种方式
*        且适合用于任意组件之间的通信
*      2.什么时候用vuex:在多个组件需要对摸个数据进行操作的时候(读写)
*      3.案例:求和案例
*      4.工作原理:
*              vuex插件中有一个store对象,他管理着三个对象:actions,mutations,state对象
*              actions的作用:当调用者不知道操作要携带的数据时候可以将所要进行的操作告诉actions对象,
*                            然后可以在actions对象中进行axios请求后台得到操作的数据,如果所要携带的数据已经明确,可以直接跳过actions
*                            直接提交到mutations对象进行操作
*              mutations的作用:他是操作的执行者,他里面有携带的数据和state中的共享数据
*              state的作用:他是所有组价所使用的共享数据,且在操作之后,如果共享的数据与变化,可以自动更新到页面
*              如何将操作和数据提交到actions对象中:通过他们的管理对象store来调用api来操作
*                    提交到actions:this.$store.$dispatch('操作',携带的数据)
*                    然后提交到mutations:this.$store.$commit('操作',携带的数据)
*      5.搭建vuex的环境:
*             (1):引入vuex插件:vue2对应vuex3    vue3对应vuex4   npm install vuex@3
*             (2):在src目录下新建sotre文件jia,在下面新建index.js
*              (3): 在index.js中定义actions,mutations,state三大对象,引入vue和vuex,并使用vuex 然后创建store实例  vuex.store({actions,mutations,state})
*              (4):在main.js中用import引入store下面的index.js 让后在vm实例中配置store
*              (5):注意的是:在创建store实例的时候,vue必须提前使用vuex
*
*      6.vuex中的store的配置项:
*              (1)actions:如果有业务逻辑的话,可以用提交到actions中进行处理,如果没有业务逻辑就直接提交到commit中
*                         actions中的方法可以收到context和value,其中如果需要处理的事情很复杂,可以用context中的dispatch来继续交给其他方法来处理,然后在提交
*              (2)mutations:mutations中可以收到state和value,通过state可以获得将要进行处理的共享数据,和value进行处理,获得新的state                    
*              (3)state:保存多个组件之间共享的数据
*              (4)getters:如果要对state中共享的数据进行加工,可以在getters配置项中处理,getters中的方法可以获得state拿到共享数据,方法通过return来返回加工后的数据
*                           也可以供多个组件使用,state和getters的关系就相当于vue中的data和computed的关系
*      
*      7.自己对于state和dispatch和commit要重复调用$store.state.xxx和$store.dispatch()和$store.commit()的优化
*              对于模板读取state中的数据的优化:用计算属性来优化,以this.$store.state.xxx作为数据源,来进行数据计算返回,这样就可以在模板中通过计算属性名来调用state中的数据了
*      8.vuex对于state和dispatch和commit要重复调用$store.state.xxx和$store.dispatch()和$store.commit()的优化
*              从vuex中引用mapState,mapGetters,mapActions,mapMutations方法来自动生成对应computed和methods
*              例如:优化state: 在computed中写 ...mapState({sum1,'sum'}),就会自动生成对应的计算属性方法,sum1是计算属性方法名,sum是state中对应的属性
*                                如果设置的计算属性方法名和state中的属性名一样,可以使用数组写法 ...mapState(['sum']),计算属性名和state中的属性名都为sum
*                    注意点:引用的state中的属性名要用''括起来,如果计算属性方法名和state中的属性名都一样,不能用对象写法的简写形式,因为对象形式的简写形式
*                            最终是...mapState({sum1,sum}),没有''包裹state中引用的sum,报错
*                    getters优化一样,但是用 ...mapGetters()
*              例如:优化dispatch: 在methods中写...mapActions({add:'add1'}),会自动生成对应的方法,add是方法名,add1是actions中的方法名,当然也有数组写法,道理和state中的一样
*                    注意点:value引入是通过方法参数传进来的如:add(countnumber)
*                    commit优化也一样,但是要用 ...mapMutations()
*      9.vuex的模块化开发步骤:
*              1.将每个业务的state,mutations,actions,getters封装到一个模块中(对象),在这里每一个业务的state,...都可以新建一个文件来保存,在index中导入再引用
*              2.在vuex中引用模块:models:{
*                                    业务1模块,
*                                    业务2模块
*                                 }
*              3.注意点:各个模块中要开启命名空间为true   namespaced:true
*/   

vue-router

* vue-router简介:

  • 理解:vue的一个插件库,专门用来实现spa引用

  • 对spa应用的理解:(1)单页web应用

  • (2)整个应用只有一个完整的页面

  • (3)点击页面中的导航链接不会刷新页面,只会做页面的局部更新

  • (4)数据需要通过ajax请求来获取

  • 对于路由的理解:1.什么是路由:一个路由就是一组映射关系(key-value);key为路径,value可能为function或者component

  • 2.路由的分类:(1):后端路由:value是function,用于处理客户端提交的请求

  • (2):前端路由:value是component,用于展示页面内容

  • 使用步骤:(1)npm vuerouter

  • (2)引入vue-router,使用vue-router

  • (3)配置router文件

  • (4)引入router配置文件,在vue中配置router配置项

  • (5)使用vue-router的router-link标签来实现路由

  • (6)使用vue-router的router-view标签来实现路由页面的占位

  • 注意点:1.路由组件通常放在pages文件夹,一般组件放在components文件夹下

  • 2.路由之间的切换,组件会处于挂载和销毁,也就是说切换到那个组件就会挂载那个组件

  • 3.每一个组件都有自己的$route属性,存储着自己的路由信息

  • 4.整个应用只有一个router,可以通过组件的$router获取

  • 嵌套路由配置:通过在router的配置文件中的一级路由下的children属性来配置子路由的相关信息,子路由的path不能带有/使用的时候key要 带 上 父路由的路径

  • 路由传递query参数:

  • 使用场景:当父路由要向子路由传递参数时

  • 使用方法:在路由路径的后面添加key-value传递参数

  • 示例:1.模板字符串写法:向子路由中传递query参数

  • 2.对象写法:向子路由中传递query参数

    路由命名:简化路由的路径使用,在router配置文件中配置name属性,在使用的时候,to写成对象才可以使用name来代替路径
    路由传递params参数:
    示例:1.模板字符串写法:向子路由中传递params参数
    2.对象写法:向子路由中传递query参数
    注意点:1.使用params传递参数,to对象写法不能写path,要使用name属性代替 2.需要在router配置中在路径的后面加上占位符
    路由的props配置项:原因在于使用params和query传递参数时候,在使用时要写this.$route.query...太过于麻烦,所以使用props使用更加简介(让路由组件更加方便接收参数)
    在路由中配置props:
    写法一(对象式):props:{a:1,b:2}
    写法二(布尔值):props:true 说明:为true则表示将所有传递过来的params参数全部转换成组件的props形式来接收
    props:['mesg','a','b']
    写法三(函数式):props($route){
    return{mesg:$route.query.mesg}
    }
    函数式也是将返回值转换成props参数来接收,解决了布尔值写法只支持params参数

    的replace属性(vue默认为push模式):
    1.作用:控制路由跳转时操作浏览器历史记录的模式
    2.浏览器的历史记录有两种写入模式:push和replace,push是追加历史记录,replace是替换当前记录,路由跳转时候默认为push
    3.在router-link标签上replace即可开启replace模式

    编程式路由导航:借助push和replace实现
    实例: methods:{
    pushlink(){
    //编程式路由导航
    this.$router.push({
    //有路由名代替路径
    name:'children2',
    params:{msg:'Hello,push模式编程式路由'}
    })
    },
    replacelink(){
    this.$router.replace({
    name:'children2',
    params:{msg:'Hello,replace模式编程式路由'}
    })
    }
    }

    缓存路由组件:让指定的路由组件在被切掉之后保持挂载(vue默认在切换路由组件时候会销毁),不被销毁,只存在于同一个的切换



    include属性可以指定需要继续挂载的路由组件,可以为数组,如果不指定,默认为同一个的所有路由组件,值为组件的名字

    两个新的生命周期钩子(路由的):actived和deactived
    1.activated:路由被激活触发
    2.deactivated:路由失活触发
    3.都是函数

    路由守卫:
    1.作用:对路由进行权限控制
    2.分类:全局守卫,独享守卫,组件内守卫
    3.全局守卫:
    即是router.beforeEach和router.afterEach这两个函数

  • //全局前置路由守卫
    //函数会接受三个参数to,from,next
    //其中的to,from的控制台输出有meta配置项,这是vue-router给我们的容器
    //初始化时候调用一次,每一次的路由切换前调用一次
    router.beforeEach((to,from,next)=>{
    console.log(to,from)
    //next()方法是放行
    //案例规定只有meta中有token且为true才放行(为children2设置权限控制)
    if(to.meta.token=false&&to.name='children2'){
    alert("权限不足")
    }else{
    console.log("放行")
    next()
    }

    })

    //初始化时候调用一次,每一次的路由切换后调用一次
    //全局后置路由守卫,用于处理一些放行之后的事情,如改变title
    router.afterEach((to,from)=>{
    document.title=to.name || '路由学习'
    })
    4.独享路由守卫:
    在路由规则中配置:beforeEnter(to,from,next){}
    在全局前置路由后执行
    5.组件内路由守卫:
    在组件中配置:beforeRouteEnter(to,from,next){},beforeRouteLeaf(to,from,next){}
    平时使用不多,beforeRouteEnter在独享路由守卫后执行,beforeRouteLeaf在全局后置路由守卫后执行
    路由的hash和history模式:
    1.hash模式:(1):对于前端的一个url来说,什么是hash值----指#及其后面的内容。vue模式路由的工作模式是hash
    2.hash值不会包含在http请求中
    3.hash模式:(1):地址会带有#,不美观。
    (2):若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法
    (3):兼容性较好
    4.history模式:(1):地址干净,美观
    (2):兼容性和hash模式相比较差
    (3):应用部署上线时候需要后端人员支持,解决刷新页面服务器404问题

*/

posted @ 2023-08-03 22:13  在赶路的我  阅读(49)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3