Vue基础

82 阅读7分钟

数据绑定

单向数据绑定

- v-bind:href = "xxx" 可简写为:href = "xxx"
- 数据只能从data流向视图

双向数据绑定

- v-mode:href = "xxx" 

data的两种写法

对象式写法

- data:{name:'name'}

函数式写法

-data:function(){return} 
//如果在组件中,必须使用函数式写法 因为如果写成对象的话,组件上的值可以被改变

计算属性

- data中的属性存在于vm._data中 而computed则是通过计算直接赋值给vm
- computed中的get中的this被vue改成了vm
    - get调用的时机有两次:
        1. 初始化的时候(也就是说如果一个页面中有多处用到计算属性时,在初始化时只会调用一次,之后的值都为缓存)
        2. 依赖的属性更新时
- vm.计算属性会自动调用计算属性中的get方法 而不是计算属性.get
- set没必要写 //当计算属性被修改时才会被使用
- 简写: 如果不需要set方法 可简写成
//计算属性:function(){return xxx}

监视属性

两种写法

- watch:{ obj:{immediate:true, handler(newValue,oldValue){}}}
- vm.$watch('obj',{相同的写法}

各项属性

- immediate 初始化时让handler调用一下
- handler 当obj发生改变时会被调用
- deep:true时,会监视到多级结构中某个属性的变化

简写

- 只需要handler时,可使用简写方式,obj(newValue,oldValue){}

自定义指令

- directives:{
    dir(element,binding){}
    element指的是绑定的dom binding指的是vlue
}
notice: 当设置为函数时,会在以下两个时间点进行调用, 1. 指令与元素成功绑定时 2. 指令所在的模版被重新解析时

- 当设置为对象时
    bind()//指令与元素成功绑定时
    inserted()//指令所在元素被插入页面时
    updated()//所在的模版被重新解析时
    
    这些钩子函数都能收到element 和 binding元素 并且在这些方法中的thiswindow
    
    

组件

什么是组件

- 实现应用中局部功能代码和资源的集合
1. 解决了依赖关系混乱, 不好维护的问题
2. 解决了代码复用率不高的问题

- 局部注入组件
    - Vue.extend({})
    - components:{}
- 全局注入组件
    - Vue.component('component',component)
- name: 可以指定组件在开发者工具中出现的名字

- 组件的嵌套

- 组件中的this指向vueComponent

- 组件是可复用的vue实例,所以接受与new Vue相同的选项,除了el这种根实例所特有的选项

- VueComponent.prototype._proto_ === Vue.prototype 

ref

- 类似于id 可以通过this.$refs.xx 拿到
notice: 当获取组件的ref时得到的是vc

props

- 简单接受 props:{}
- 可以限制接受的数据类型
    - e.g. props:{name:String}
    - 也可以有更多属性限制
        - e.g. props:{name:String required:true,default:10} //default 与 required一般不同时使用
- notice: 不要直接修改props传过来的数值,可以通过在data中定义一个变量来接受并且进行修改

mixins

- 将暴露出的变量先用import导入,然后再用mixins接收,
- 当mixins中的变量与原有变量冲突时,以原有变量为主

- 在main.js中引入 并用Vue.mixin() 即代表全局混入

插件

- Vue.use(plugin,optioanl(参数))
- 在插件中的行参是Vue
- 定义插件 对象.install =function(Vue, options){
        此处可添加全局的东西
}

组件自定义事件

绑定及触发自定义事件

- 之前可通过父组件给自组件传递函数类型的props实现:子给父传递数据
- 父组件在子组件标签内添加 v-on:'自定义事件‘ = 'methods中的func',之后通过在子组件中的this(vc).$emit('自定义事件',optional(参数) )

 1. 自定义事件 不需要子组件用props接受
 2. 可通过给子组件绑定ref 然后通过this.$refs.xxx.$on('自定义事件',callback') 一般在mounted中绑定,而且$on can replace to $once代表只能使用一次 也可在@自定义事件后加上.once
 

解绑自定义事件

- this.$off() 可传数组,如果不传任何参数代表解绑所有的自定义事件 当组件销毁的时候,绑定的所有自定义事件都会被销毁,原生dom上的事件 会被保留
- 在自定义事件中 谁触发的自定义事件 this就为谁 在methods中的方法的this一直都为vm
- 在子组件上添加@click时 会被认为是自定义事件,需变成@click.native 才会被认为是点击事件

全局事件总线

- 能够实现任意组件间的通信
- 前置: $on $emit $off... 都是vc和vm的原型上的方法
-   实现步骤:
    1. const Demo = Vue.extend({}) const d = new Demo() //不推荐
    2. 在main.js中 beforeCreate方法中设置 Vue.prototype.$bus = this
    3. 使用这种方法需要在beforeDestroy中进行解绑,要不就一直存在

pubsub-js

- publish&subscribe github上查看用法

$nextTick

- 里面的callback会在DOM节点更新完毕之后再执行

动画与过渡

-  待做 前置知识: CSS3 动画

配置代理

axios

- 如何解决跨域
    1. cors 需要在后端加上响应头(negative:谁都能访问)
    2. jsonp(script src)需要前后端配合 并且只能进行get请求 post等不能(用得少)
    3. 配置一个代理服务器(常用): 
    - 白话来说就是设置一个同域的服务器接受前端的请求,atst 服务器与服务器之间的请求不受跨域限制
    - 开启的方式
        - nginx 反向代理服务器
        - vue-cli 
            - 开启的配置 devServer.proxy 位于vue.config.js中
                -  在proxy中设置联系的服务器地址
                -  negative: 1. 不能配置多个服务器地址 2. 如果所请求的资源在本地上有会优先寻找本地的资源
        
            - 可以在proxy中声明多个数组解决如上缺点, 使用pathRewrite属性利用正则表达式替换

fetch (TODO)


vue-resource

- npm i vue-resource 再引入 Vue.use() 就可以使用 通过this.$http.methods使用

slot

-  声明在组件的页面结构当中,当在使用组件时在中间插入结构时,就会替代slot的位置(default)
- 具名插槽 name 在标签里是slot="name"  第二种写法是当v-slot = method(只在template里面有用)
- 作用域插槽 作用是将子组件的数据通过slot传递给父元素 父元素通过template 标签中的scope or slot-scope 进行接收 可传递多个元素

v-text diff with 插值语法: v-text会替换掉节点中的内容, 哪怕有html标签

Vuex

- 实现多组件共享数据 
    - 使用场景:1. 多个组件依赖于同一状态 2. 来自不同组件的行为需要依赖同一状态
    
- 步骤
    在Action阶段, 可能会通过backend API获取到值,
    在main.js中声明store
    新建一个文件夹store创建一个index.js(一般都这样)
    其中引入Vue & Vuex 同时Vue.use(Vuex)


- step
    actions(dispatch触发) 中接受两个行参(context,value) context为上下文的意思 value代表接受的变量
    mutations(commit触发) 中接受两个行参(state,value) 这个时候可以操作state
    state中可以设置公共变量
    

getters

- 用于将state中的数据进行加工
    - 接收的行参为state
    - 与computed类似 依赖的数据变化了就会自动改变

mapState & matGetters

- mapState
    - step
        - import {mapState} from 'vuex'
        - 在computed中...mapState({key:value})
        - 如果同名, 可以将{key:value}替换成{['key']}
- mapGetters 同理

mapActions & mapMutations

- notice: 
    - diff with mapState: 方法需要传参
    
   

Vuex 模块化

- Purpose: 让代码更好维护, 让多种数据分类更加明确
notice:
声明时: 
    - 需要给每个模块加上namespaced: true
    - 在store文件夹中声明不同功能的js index中import
  
使用时:
    - 如使用mapxxx等,按照以下格式
        - ...mapState('xxx',['xxx'])
    - 如采用普通模式书写
        需要按照 xxx/xxx 格式

路由

就是一种key-value的关系

原理 key: 就是路径 /class这种 value:就是所展示的组件

notice:如果在actions中对state进行操作,Devtool就监测不到了

SPA页面

- 整个页面只有一个完整的页面
- 点击导航链接不会刷新页面,只会做页面的局部更新
- 数据需要通过ajax请求获取

路由分类

- 后端路由
    - value是function 用于处理客户端提交的请求
    - process: 服务器接收到一个请求时,根据请求路径找到匹配的函数来处理请求,返回响应的数据
- 前端路由
    - value是component 用于展示页面内容
    - 当路径改变时,对应的组件就会显示
    

路由基本使用

 - router-link 实现路由的切换
 - router-view 指定组件的呈现位置
 - active-class 指定组件激活时候的样式名
 
 - 几个注意点
     - 不用的组件会被销毁
     - 组件上的$router是一样的 $route是不一样的
     
     

多级路由

 notice: 需要子路由中声明children添加path时需注意不要添加/ but在router-link中需声明完整路径

路由传参

 - 两种写法
     - 1. to加: 并且之后的值用模版字符串+${}来书写
     - 2. :to={path:xxx, query:xxx}
     
 - 接受query后 用$route.query.xxx来取值
 

命名路由

- 将name取在配置项中
    - 作用: 简化path
        但不是to="name"的写法
        而是:to="{name:xxx}"
        

路由的params属性

- 配置路由的时候必须声明接受params属性 且需要使用占位符
e.g. path:'detail/:id/:count
- 传递的时候 to的字符串写法为 :to="home/id/count"
    to的对象写法:
        需注意不能与path同时使用
        需与name同时使用
        

路由的props配置

声明在路由配置项中

- 1. 值为对象 所有key-value都会以props的形式传递给Detail组件
- 2. 值为Boolean,若为true,将会把所有接收到的params参数以props的形式传递给Detail组件
- 3. 值为函数 所有返回的值都会用props的形式传递,并且会接受$route为行参 这样可以获取到query上的值

路由的replace选项

开启方法有两种
    - 1. 完整模式 :replace="true" 
    - 2. 简写模式 replace
    
作用: 有两种写入方式,分别为push和replace push是追加 也就是入栈 replace是替换该条记录  

编程式路由导航

- 作用: 不借助routerlink实现路由跳转
    - 借助的是$router 而不是$route
    - attention: 重复点击可能会报错
    

keep-alive

- 让不展示的路由组件不被销毁,保持挂载
- keep-alive包裹router view 如不加includes 则所有组件都不会被销毁,如果要加的话需注意是组件名,可写成数组模式

两个路由的生命周期钩子

- activated 
    
- deactivated

- 需要搭配keep-alive使用

路由守卫

- 全局路由守卫
    - beforeEach 3 attribute to from next()
    - afterEach 2 attribute to from 
        - 可以用来给每个路由页面添加title
    
- 路由独享守卫
    - 只有beforeEnter 
    
- 组件守卫
    - beforeRouteEnter (to from enter) 
        - 通过路由规则,进入该组件时被调用
    - beforeRouteLeave (to from enter)
        - 通过路由规则,离开该组件时被调用
    
    

路由工作的两种模式

通过在router中添加mode来改变工作模式

- # hash工作模式
    - 兼容性好
    - #后面的都不会发送给后端
- history工作模式
    - 部署时 容易出问题
    - 需要后端配合
        - nodejs中间件: connect-history-api-fallback

# 未完待续