vue2.x 基础学习笔记

vue插值语法

  1. v-html: 用于解析带html标签时的字符串数据

  2. v-pre: 原封不动的输入{{msg}}不会进行编译,比如:<p "v-pre>{{msg}}</p> => {{msg}}"

  3. v-once: 只编译一次,当绑定数据再次发生改变,不会跟着改变

  4. v-cloak: 当js执行完毕之前页面会先输出template中的{{}}内容,这种情况对用户体验不好,该指令可以在js执行完之后渲染{{}}内容,执行前不会显示。

    原理:解析前标签中加v-cloak属性,此时该属性display:none, 解析后标签取消该属性,display 消失就会显示出内容

    <template>
      <h2 v-cloak>{{msg}}</h2>
    </template>
    
    <style>
      [v-cloak] {
        display: none
      }    
    </style> 
    
  5. v-text: 把变量以指令的方式解析,不够灵活不推荐使用

vue绑定 v-bind

属性绑定 绑定样式的三种方式

1. 直接绑定样式:需要在data中定义该类名 <h4 :class="active"><h4>
2. 对象的方式绑定,可以绑定多个:<h4 :class="{类名:boolean,类名:布尔值}"><h4>
3. 数组的方式,可以绑定多个:<h4 :class="[类名1,类名2]"><h4>

style绑定

<h4 :style={属性名:属性值}><h4>  => <h4 :style={fontSize: '100px',color: 'red'}></h4>  

vue 手动获取event对象

<button @click="getEvent('参数1',$event)">
  获取event
</button>
1. 当方法没有参数时可以省略括号,默认会传event对象
2. 当有其他参数时,获取event对象需要用$event

vue事件修饰符

@click.修饰符=“method”

1.prevent: 阻止默认事件,比如 a标签默认跳转

2. stop: 阻止事件冒泡

3. once: 绑定事件只触发一次,再次无效

4. self: 只有event.target是当前操作的元素时才触发事件(也就是说是绑定的该元素本身被点击了才会触发)

5. capture: 事件捕获时触发事件

6. passive: 事件的默认行为立即执行,无需等待事件回调完成

vue键盘事件

@keyup="method" || @keydown="method"(keyup按下并放松才会触发,keydown按下就会触发)
键盘事件修饰符:
1. enter 2. esc 3. shift 4.ctrl 5.....等等

组合使用:@keyup.ctrl.y 必须同时按下ctrl+y才能触发

vue watch(事件监听)

new Vue({
  data: {
    numbers:{
      a:1,
      b:2
    },
    name:'皎月'
  },
  // vue实例可以监测到复杂对象内部变化,但是watch只能监测一层
  watch: {
    numbers: {
      deep:true, // 开启深度监听,默认watch只能监听一层数据,要监听复杂类型需要开启深度监听
      handler(newVlaue,oldValue){
        console.log('我被改变了')
      }
    }
  },
  // 如果监听的数据格式简单,不需要深度监听,可以简写成下面方式
  watch:{
   name(newVlaue,oldValue){
     console.log('监听简单数据,简写方式')
   } 
  }
})

vue中的key(原理)

1. 虚拟dom中key的作用:

key是虚拟dom中对象的标识,当数据发生改变时,vue 会根据新数据生成新的虚拟dom,然后进行虚拟dom的对比,比较规则如下:
  1. 旧的虚拟dom中找到和新的虚拟dom相同的key:
    • 比较虚拟dom元素是否相同,如果不相同就生成新的真实dom,并且替换之前旧的dom。
    • 如果虚拟dom相同,直接拿旧的真实dom进行复用。
  2. 旧的虚拟dom中没有找到和新的虚拟dom相同的key:
    • 直接创建新的真实dom,并且渲染到页面。
  3. 如果用index当做key可能引发的问题
    • 对数据进行逆序添加、删除等破坏顺序的行为时,会导致dom重复更新,效率低。
    • 如果dom中包含输入类的标签,会导致错误的dom更新,导致界面出现问题。
  4. 不添加key会发生什么
    • 默认如果没有加key vue默认会用index当做key来使用。
    • 严格模式下,编译会报警告。

vue中的过滤器

过滤器filter

1. 假如data中有一个属性date:12343000,把date格式化成2021-7-16这种格式。
<h3>{{time | timeFormarter}}</h3>
2. 过滤器可以传递参数,第一个参数固定是过滤器前的值,第二个参数才是过滤器格式参数。
<h3>{{time | timeFormarter('YYYY-MM')}}</h3>
3. 过滤器可以串联写多个,第三个过滤器的值是第二个过滤器返回的结果,假如有多个以此类推。
<h3>{{time | timeFormarter('YYYY-MM') | myFilter}}</h3>

--->vue中写过滤器
filters:{
  timeFormarter(value,str){
    return datejs(value).formart(str)
  },
  myFilter(value) {
    
  }  
}
  

vue 自定义指令

<h3 v-big="n"></h3>
new Vue({
  data:{
    n:10
  },
  directives: {
    big(element,binding){
      // element 指令绑定dom  binding对象里面有传入的值和指令信息
      // ...进行指令要执行的代码逻辑
    }
  }
})

vue props接收的三种方式

1. 简单接收

// 组件传值
<School name="张三" age="18" sex="男"></School>

export default {
    props: ['name','age','sex']
}

2. 接收同时限制类型

// 组件传值
<School name="张三" :age="18" sex="男"></School>
// age前加: 会把age解析成表达式数字类型18,否则会是字符串“18”
export default {
    props: {
    name: String,
    age: Number,
    sex: String
  }
}

3.接收的同时限制类型,并且给没传的属性默认值

// 组件传值
<School name="张三" sex="男"></School>

export default {
    props: {
    name: {
      type: String, // 接收值的类型
      required: true // 接收的必传
    },
    age: {
      type: Number,
      default: 88 // 默认值,不传age则为88
    }
  }
}

4.备注

组件解析是props优先级比较高,会先解析props在解析组件中的data数据

vue (mixin混入的使用)

1、局部混入

// 可以把组件中的配置项比如data/methods/生命周期等写入一个公共的文件,那个组件要使用,就去引入叫做混入,实现配置项的复用
// 1. 创建一个第三方文件 mixins.js
export const mixin1 = {
  data(){
    name: '张三',
    age: 24  
  }
}
export const mixin2 = {
  methods: {
    showName() {
      alert(this.name)
    }
  }
}
// 2.在需要混入的文件中引入,并且声明
import {mixin1, mixin2} from './mixins.js'
export defalut {
  mixins: [mixin1, mixin2]
}

2.全局引入(不推荐使用)

// 在main.js中引入mixins.js
import {mixin1, mixin2} from './mixins.js'
Vue.mixin(mixin1);
Vue.mixin(mixin2);

3.备注

1.混入的如果是data()/methods和组件内冲突,以组件中的为主

2. 混入的如果是生命周期钩子,那么混入的和组件内的都会执行,并且混入的会先执行,组件内后执行

vue 自定义事件

定义自定义事件两种方式:

1. <School @getSchoolName="getName"></School>
2. <School ref="school"></School> 
// 组件方法
methods: {
  getName(name) {
    console.log(name)
  }
}
// 组件钩子函数
mounted() {
  this.$refs.school.$on("getSchoolName",this.getName)
}

// 子组件触发自定义函数需要用到$emit方法
this.$emit("getSchoolName",this.name)

备注

  1. 如果自定义方式只需要触发一次就失效需要加上once修饰符 <School @getSchoolName.once="getName"></School>or this.$refs.school.$once("getSchoolName",this.getName)
  2. ** 如果要在子组件上绑定原生的js事件,需要加上native修饰符否则不生效 ** <School @click.native="getName"></School>

自定义事件解绑:

  1. this.$off("事件名")解绑一个事件
  2. this.$off(['事件名1','事件名2']) 解绑多个事件

vue 全局事件总线

1.定义全局事件总线

// main.js
import Vue from 'vue'
import App from 'App'
new Vue({
  el:'#app',
  render: h => h(App),
  beforeCreate() {
    Vue.prototype.$bus = this
  }
})

2.使用事件总线传递参数

// 在需要接受的组件内绑定监听事件
mounted(name) {
  this.$bus.$on("getName", (name) =>{
    // 回调函数
    console.log(name)
  })
}
// 在需要传递参数的组件内发射事件
methods: {
  handler() {
    this.$bus.$emit("getName", this.name)
  }
}

备注

在监听事件的组件中,最好记得解绑监听的事件,因为$bus是定义在vue原型上最好组件销毁之前手动解绑监听事件

beforeDestory() {
  `this.$bus.$off("getName")`
}

消息订阅与发布(pubsub-js)

1. 安装中间件 npm i pubsub-js -S

2.引入使用

import pubsub from 'pubsub-js'
//  订阅一个消息
// msgName: 事件名称  data:传递的参数
pubsub.subscribe("hello",(msgName, data) => {
  // 回调事件
})

// 发布一个事件
pubsub.publish("hello", this.name)
 

vue跨域配置代理的方式

1.cors(需要后端配置)

2.jsonp(通过script Src属性请求脚本,缺点:只支持get请求)

3. nginx 配合跨域

4. vue-cli配置代理

// 通过cli配置代理需要在vue.config.js中配置选项
module.exports = {
  devServer: {
    "proxy": {
      "/api": {
        target: 'url', //目标服务器路径
        changeOrigin: true, //为true时ajax请求的url和服务器一致,为false时ajax请求的url是真实的主机地址, 默认为true
        pathRewrite: {'^/api': '' }, // 请求服务器资源替换api为空
      }
    }
  }
}

vue 插槽

1. 插槽的作用:适用于父组件往子组件中传递结构 父组件>>>子组件

2.插槽的分类: 默认插槽 、具名插槽、作用域插槽

父组件:
  <template>
    <Category>
      <h4>我的默认插槽的内容</h4>
    </Category>  
  </template>
子组件:
    <template>
      <slot>默认插槽</slot>
    </template>

---------------------------------------------------------------------
  
父组件:
  <template>
    <Category>
        <--写法1-->
      <h4 slot="top">我的具名插槽的内容</h4>
            <h4 slot="bottom">我的具名插槽的内容</h4>

            <--写法2-->
      <template v-slot:bottom>
        <h4>我的具名插槽的内容</h4>
      </template>
    </Category>  
  </template>
子组件:
    <template>
      <slot name="top">我是顶部内容</slot>
            <slot name="bottom">我是底部内容</slot>
    </template>

3.作用域插槽

// 作用域插槽适用于,数据在子组件中,如果展示数据的结构在父组件中定义,子组件>>>父组件

父组件:
  <template>
    <Category>
        <--写法1-->
      <template scope="data">
            <h4 v-for="(item,index) in data.cates">{{item}}</h4>
        </template>
            <--写法2-->
      <template slot-scope="data">
            <h4 v-for="(item,index) in data.cates">{{item}}</h4>
        </template>
    </Category>  
  </template>
子组件:
    <template>
      <slot :cates="cates">我是作用域插槽</slot>
    </template>

    data() {
    return{
      cates: ['热门','新闻','政治']
    }
  }

vuex使用

当有多个组件需要共享一个状态时候,就可以使用vuex来管理那个共享状态

1.安装vuex

npm i vuex -S

2. 在src下创建store文件夹(创建store仓库)
// store下的index.js
import Vue from 'vue'
import Vuex from 'vuex'
// 挂载vuex
Vue.use(Vuex)

// vuex核心 三大模块内容actins, mutations, state 皆是一个对象
// 1.actions: 通常用于和组件实例的交互行为,通俗的讲就是接收组件实例中dispatch分发的方法,然后commit一个mutations,在actions中可以执行一些异步任务
const actions = {
  // context: 上下文对象,里面包含commit,dispatch等
  // value: 组件实例调用方法时传的参数
  increment(context, value) {
    // 提交一个mutations
    context.commit('INCREMENT', value)
  }
},
// 2.mutations: 用于改变state中状态
const mutations = {
  // state: 状态管理对象
  // value: actions提交时传递的参数
  INCREMENT(state, value) {
    state.sum += value  
  }
},
// 3. state: 管理共享数据的仓库
const state = {
  sum: 0
}
// 4. getters: 相当于组件中的computed,如果state中的某个状态需要加工后返回可以使用,getters必须有返回值
const getters = {
  doubleSum(state) {
    return state.sum * 2
  }
}


// 导出store仓库
export default new Vuex.Store({
  actions,
  mutations,
  state,
  getters
})
3. 在main.js引入store仓库挂载到组件实例对象上
// main.js
import Vue from 'vue'
import App from 'App'
import store from './store'

new Vue({
  el:'#app',
  store,
  render: h => h(App)
}) 
4. 组件中如何使用vuex中的state?
// a.vue组件
//1. 访问vuex管理的数据 借助vuex中mapState方法
import { mapState, mapGetters } from 'vuex'
// 2.在计算属性中获取
export default {
  computed() {
    // 对象的简写形式
    // mapState函数实际上就是返回一个计算属性,number就是template中使用的值,sum对应state中状态数据
    ...mapState({number: 'sum'})
    // 数据的简写形式
    //使用数组简写时,实际上就是{sum: 'sum'},要求state中的数据必须是sum,在template使用是也是sum
    ...mapState(['sum'])
  }
}
// mapGetters 使用方法和上面一致
5.组件中如何使用vuex中的actions和mutations?
// a.vue组件
//1. 使用vuex管理actions 借助vuex中mapActions方法
import { mapActions, mapMutations } from 'vuex'
// 2.在methods属性中获取
export default {
  methods() {
    // 对象的简写形式
    // mapActions add就是template中使用的方法名,increment对应actions中方法
    ...mapActions({add: 'increment'})
    // 数据的简写形式
    //使用数组简写时,实际上就是{increment: 'increment'},要求actions中必须是increment,在template使用是也是increment
    ...mapActions(['increment'])
  }
}
// mapMutations 使用方法和上面一致

vuex模块化

// store/count/index.js
// 模块一
export const count = {
  namespaced: true, // 使用模块化必须开启命名空间
  actions: {},
  mutations: {},
  state: {},
}
// store/person/index.js
// 模块二
export const person = {
  namespaced: true, // 使用模块化必须开启命名空间
  actions: {},
  mutations: {},
  state: {},
}

// store/index.js
import {count} from './count'
import {person} from './count'
export default new Vuex.Store({
  modules: {
    count,// 模块化名
    person // 模块化名
  }
})

使用模块化

// 组件中
import { mapState, mapActions } from 'vuex'
export default {
  computed() {
    // mapState接收两个参数
    // 第一个:count是模块名
    // 第二个: sum是count模块中state中定义的数据名
    ...mapState('count', ['sum'])
    // 直接读取的方式
   // this.$store.count.sum
  },
  methods: {
    // mapActions接收两个参数
    // 第一个:person是模块名
    // 第二个: add是person中actions中定义的方法名
    ...mapActions('person', ['add'])
    // 第二种写法 person/add:模块/方法名 2: 参数
    //this.$store.dispatch('person/add', 2)
  }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容

  • 书本信息:  << Vue.js 实战 >> 作者: 梁灏 学习笔记 部分内容摘自书 非原创 侵删 第二章 数据绑...
    blue_avatar阅读 716评论 0 2
  • 一个 Vue 应用由一个通过 new Vue 创建的根 Vue 实例,以及可选的嵌套的、可复用的组件树组成。 所有...
    w_tiger阅读 304评论 0 0
  • 这篇文章是接着我的上部vue学习笔记写的,之所以分开写这两篇文章是因为我意识到不知道什么时候就写了非常多的字了,所...
    看物看雾阅读 839评论 0 1
  • 前言 接触 Vue 也有一段时间了,很多时候在项目里面会用,但是由于对整个 Vue 的了解比较片面,让我不得不一次...
    你的肖同学阅读 945评论 0 12
  • Vue一文学会? Vue大家都知道就是一个国内非常流行的框架,最近因为过了许久没用Vue对于Vue的许多早已淡忘,...
    看物看雾阅读 601评论 0 3