【vue2】回顾vue2纯语法(建议收藏 不包括router)

template(必须) 影响组件渲染的结构 html

只能有一个根元素

vue通过data提供数据

data必须是一个函数,并且返回一个对象

export default {
  data () {
    return {
      money: 100,
      msg: 'hello'
    }
  }    
}

插值表达式显示数据  {{}}

{{ msg }}
{{ obj.name }}
{{ msg.toUpperCase() }}
{{ obj.age > 18 ? '成年' : '未成年' }}

v-bind与v-on指令

v-bind:动态的设置html元素的属性

<!-- 缩写 -->
<a :href="url"></a>

v-bind对于style 的增强

<div class="box" :class="isRed ? 'red': ''">123</div>

v-on:绑定事件

<button v-on:click="addMoney(1)">搬砖</button>

v-on事件修饰符

  • .prevent 阻止默认行为
  • .stop 阻止冒泡
 <a @click.prevent="fn" href="http://www.baidu.com">去百度</a>

v-on获取事件对象

  • 没有传参, 通过形参接收 e
@click="fn2"

methods: {
   fn2(e) {
     e.preventDefault()
   }
}
  • 传参了, 通过$event指代事件对象 e
@click="fn2(100, $event)"

methods: {
   fn2(num, e) {
     e.preventDefault()
   }
}

v-if 和 v-show

v-show:实质是在控制元素的 css 样式, display: none;

v-if:实质是在动态的创建 或者 删除元素节点;是惰性的, 如果初始值为 false, 那么这些元素就直接不创建了, 节省一些初始渲染开销

v-else 和 v-else-if

v-model

给表单元素使用, 双向数据绑定

v-model 修饰符:

  • v-model.number="age":自动将用户的输入值, 用parseFloat转成数字类型
  • v-model.trim="msg":自动过滤用户输入的首尾空白字符

v-model 语法糖:==》等价于 给一个input框提供了 :value属性以及 @input事件

  • 数据发生了改变,页面会自动变 v-bind:value
  • 页面输入改变 , 数据会自动变化 v-on:input
<input type="text" v-model="msg">

<input type="text" :value="msg" @input="msg = $event.target.value">

v-text 和 v-html

  • v-text:更新元素的innerText
  • v-html:更新DOM对象的innerHTML

v-for

v-for="(item, index) in 数组名" 

<ul>
  <li v-for="(value, key) in user" :key="key">{{value}} ---{{key}}</li>
</ul>

v-for设置 和 不设置 key 有什么区别:==》 提高虚拟DOM的对比复用性能

计算属性(computed):计算属性必须是一个 function,计算属性必须有返回值

<p>{{ reverseMsg }}</p>

computed: {
  reverseMsg () {
    return this.msg.split('').reverse().join('')
  }
}

计算属性的缓存的问题

  • 计算属性只计算了一次,就会把结果缓存起来,以后多次使用计算属性,直接使用缓存的结果
  • 如果计算属性依赖的属性发生了改变,计算属性会重新计算一次,并且缓存

属性监听(watch):只要监听的属性发生了改变,这个函数就会执行

watch: {
  // 参数1: value    变化后的值
  // 参数2: oldValue 变化前的值
  msg (value, oldValue) {
    console.log('你变了', value, oldValue)
  }
}

watch的属性:

  • deep: true  如果true,代表深度监听
  • immediate: 立即 立刻  是否立即监听 默认是false
  • handler 数据发生变化,需要执行的处理程序
data() {
  return {
    list: JSON.parse(localStorage.getItem('score-case')) || []
  }
}

watch: {
  list: {
    deep: true,
    handler() {
      localStorage.setItem('score-case', JSON.stringify(this.list))
    }
  }
}

组件的全局注册与局部注册  

全局注册的组件,可以在任意的组件模板范围中使用

//main.js
import HmHeader from './components/HmHeader'

// 全局注册
// Vue.component(名字, 组件)
Vue.component('HmHeader', HmHeader)

局部注册的组件,只能在当前注册的组件模板范围内使用

<template>
  <div>
    <hm-header></hm-header>
  </div>
</template>

import HmHeader from './components/HmHeader'
export default {
  components: {
    HmHeader
  }
}

通过 name 注册组件

<template>
  <button>按钮组件</button>
</template>

<script>
export default {
  name: 'HmButton'
}
</script>
import HmButton from './components/hm-button.vue'
Vue.component(HmButton.name, HmButton)  
// 等价于 app.component('HmButton', HmButton)

组件的样式冲突 scoped

  • 默认情况下,写在组件中的样式会全局生,会影响到整个 index.html 中的 dom 元素;
  • 可以给组件加上 scoped 属性, 可以让样式只作用于当前组件

组件通信

父传子 props 传值

父组件通过给子组件加属性传值

//父 属性传值
<Son price="100" title="不错" :info="msg"></Son>

//子 通过props属性接收
props: ['price', 'title', 'info']

传递给子组件的数据, 为了提高 子组件被使用时 的稳定性, 可以进行props校验

props: {
    // 基础的类型检查
    propA: Number,
    // 多个可能的类型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: true
    },
    // 带有默认值
    propD: {
      type: Number,
      default: 100
    }
}

子传父

子组件可以通过 this.$emit('事件名', 参数1, 参数2, ...) 触发事件的同时传参

//子 通过this.$emit()
this.$emit('sayPrice', 2)

//父
<son @sayPrice="sayPrice"></son>

methods: {
  sayPrice (num) {
    console.log(num)
  }
}

 ref 和 $refs:可以用于获取 dom 元素 或者组件实例

每个 vue 的组件实例上,都包含一个$refs 对象,里面存储着对应的DOM 元素

  • 给需要获取的 dom 元素或者组件, 添加 ref 属性
<div>
  <div ref="box">我是div盒子</div>
  <jack ref="jack"></jack>
  <button @click="fn">按钮</button>
</div>
  • 通过 this.$refs.xxx 获取  
import Jack from './jack.vue'
export default {
  methods: {
    fn () {
      console.log(this.$refs.box)
      console.log(this.$refs.jack)
      this.$refs.jack.sayHi()
    }
  },
  components: {
    Jack
  }
}

自定义指令:自定义全局指令跟自定义局部指令

插槽:允许在封装组件时,把不确定的、希望由用户指定的部分定义为插槽

  • 默认插槽
// 父
<my-dialog>
  <p>请输入正确的手机号码</p>
</my-dialog>

// 子
<template>
  <div class="my-dialog">
    <div class="header">
      <h3>友情提示</h3>
    </div>
    <div class="content">
      <slot></slot>
    </div>
 // 设置默认值
 // <div class="content">
 //     <slot>设置的默认值</slot>
 // </div>
    <div class="footer">
      <button>关闭</button>
    </div>
  </div>
</template>
  • 具名插槽 :可以实现定向分发
  1. 给插槽起名字 ;
  2. 使用 template 标签, 将内容包裹成一个整体;
  3. 通过 v-slot:插槽名, 指定具体分发给谁
// 父
<my-dialog> 
  //具名插槽的简写  <template #header>
  <template v-slot:header>  
    <h3>这是大标题</h3>
  </template>
  //具名插槽的简写  <template #default>
  <template v-slot:default> 
    <p>这是内容</p>
  </template>
  //具名插槽的简写  <template #footer>
  <template v-slot:footer> 
    <button>确认</button>
    <button>取消</button>
  </template>
</my-dialog>

// 子
<template>
  <div class="header">
    <slot name="header"></slot>
  </div>
  <div class="content">
    <slot>这是后备内容</slot>
  </div>
  <div class="footer">
    <slot name="footer"></slot>
  </div>
</template>

组件生命周期

  •  beforeCreate:data数据初始化之前,组件还没有数据
  •  created: data数据初始化之后,可以获取到组件的数据
  •  beforeMount:DOM渲染之前,DOM还没渲染
  •  mounted:DOM渲染之后,可以操作DOM了
  •  beforeUpdate: 数据更新,DOM更新前
  •  updated: 数据更新,DOM更新后
  •  beforeDestroy: 组件销毁前
  •  destroyed: 组件销毁后

单页应用程序的缺点:不利于 SEO 搜索引擎优化

vuex

多个组件共享状态,才存储在vuex中;对于某个组件中的私有数据,依旧存储在data中

配置项含义注意
state单一状态树类似data
mutations数据管家(同步)唯一修改state地方
actions异步请求要改state需要提交给mutations
gettersvuex计算属性类似computed
modules模块拆分

state

// 方式1: 组件内视图 JS内直接 - 直接使用  
this.$store.state.模块名.变量名

// 方式2:
import { mapState } from 'vuex';
...mapState("模块名", ['state变量名'])        //同名直接获取
...mapState("模块名", {新名字:'state变量名'}) //改名

getters

// 方式1: 组件内 - **直接**使用
this.$store.getters['模块名/计算属性名']

// 方式2: 组件内 - **映射**使用
import { mapGetters } from 'vuex';
...mapGetters("模块名", ['getters里计算属性名'])        // 同名获取
...mapGetters("模块名", {新名字:'getters里计算属性名'}) // 改名

mutations

// 方式1: 组件内 - **直接**使用
this.$store.commit("模块名/mutations里的函数名", 具体值)

// 方式2: 组件内 - **映射**使用
import { mapMutations } from 'vuex';
...mapMutations("模块名", ['mutations里方法名'])        // 同名获取
...mapMutations("模块名", {新名字:'mutations里方法名'}) // 改名

actions  

// 方式1: 组件内 - **直接**使用
this.$store.dispatch("模块名/actions里的函数名", 具体值)

// 方式2: 组件内 - **映射**使用
import { mapActions } from 'vuex';
...mapActions("模块名", ['actions里方法名'])         // 同名获取
...mapActions("模块名", {新名字:'actions里方法名'})   // 改名

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

来自湖南的阿晨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值