vue3学习之路

一、开始搭建一个vue3项目

  • 安装vue
yarn global add @vue/cli
  • 通过在终端中运行以下命令,可以使用 Vite 快速构建 Vue 项目。
$ yarn create vite-app <project-name>
$ cd <project-name>
$ yarn
$ yarn dev
  • 为什么是vite而不是cli?链接
    1、vue-cli基于webpack,是vue2的前端构建工具,在启动一些大型项目的时候启动较慢,vite的尤雨溪团队在发布vue3的前端构建工具,优化了启动慢的问题。
    2、两者在生产环境下都是基于源代码文件打包,但是在开发环境下,vite是基于原生es6,无需对代码进行打包,浏览器可以直接调用,在开发环境中体验及其愉快。

二、vue3

官网链接

指令集合

1、v-bind:用于数据绑定,等同于使用{{}}

<span v-bind:title="message">
    鼠标悬停几秒钟查看此处动态绑定的提示信息!
 </span>
 //缩写
 <span :title="message">
    鼠标悬停几秒钟查看此处动态绑定的提示信息!
 </span>
<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      message: 'You loaded this page on ' + new Date().toLocaleString()
    }
  }
}
</script>

2、v-on:添加一个事件监听器

<button v-on:click="reverseMessage">反转 Message</button>
//缩写
<button @click="reverseMessage">反转 Message</button>
methods: {
    reverseMessage() {
      this.message = this.message
        .split('')
        .reverse()
        .join('')
    }
  }
  • 可以同时监听多个方法,如下
<button @click="one($event), two($event)">
  Submit
</button>
  • 事件修饰符
    Vue.js 为 v-on 提供了事件修饰符
    .prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault():
<!-- 阻止单击事件继续传播 -->
<a @click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->
<form @submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联 -->
<a @click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->
<form @submit.prevent></form>

<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div @click.capture="doThis">...</div>

<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div @click.self="doThat">...</div>

<!-- 点击事件将只会触发一次 -->
<a @click.once="doThis"></a>

<!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发   -->
<!-- 而不会等待 `onScroll` 完成                   -->
<!-- 这其中包含 `event.preventDefault()` 的情况   -->
<div @scroll.passive="onScroll">...</div>
  • 键盘修饰符
    Vue 允许为 v-on 或者 @ 在监听键盘事件时添加按键修饰符
<!-- 只有在 `key``Enter` 时调用 `vm.submit()` -->
<input @keyup.enter="submit" />

<!-- 处理函数只会在 $event.key 等于 'PageDown' 时被调用 -->
<input @keyup.page-down="onPageDown" />

常用的如下:.enter、.tab、.delete (捕获“删除”和“退格”键)、.esc、.space、.up、.down、.left、.right

  • 系统修饰键
    仅在按下相应按键时才触发鼠标或键盘事件的监听器
    .ctrl、.alt、.shift、.meta
<!-- Alt + Enter -->
<input @keyup.alt.enter="clear" />
  • .exact 修饰符
    允许你控制由精确的系统修饰符组合触发的事件
<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button @click.ctrl="onClick">A</button>

<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button @click.exact="onClick">A</button>
  • 鼠标按钮修饰符
    .left、.right和.middle

3、v-model:实现表单输入和应用状态之间的双向绑定
可以在表单 input、textarea 及 select 元素上创建双向数据绑定

 <p>message:{{ message }}</p>
<input v-model="message" />

在这里插入图片描述

<!--单行输入文本-->
<input v-model="message" placeholder="edit me" />
<!--多行输入文本-->
<textarea v-model="message" placeholder="add multiple lines"></textarea>
<!--复选框-->
<input type="checkbox" id="checkbox" value="jack" v-model="checked" />
checked为字符串的时候,选中或者未选中的值为truefalse,checked为[]时,值为value的值
<!--单选框-->
<input type="radio" id="one" value="One" v-model="picked" />
<!--选择框-->
<select v-model="selected">
    <option disabled value="">Please select one</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
</select>

修饰符:

  • .lazy
    v-model默认绑定值msg的数据在输入的时候同步改变,加上lazy之后默认change事件之后再同步改变
<input v-model.lazy="msg" />
  • .number
    自动将输入值转换为数值类型
<input v-model.number="age" type="number" />
  • .trim
    自动过滤用户输入的首尾空白字符
<input v-model.trim="msg" />

4、v-if:条件表达式

<span v-if="seen">现在你看到我了</span>
<h1 v-else>Oh no 😢</h1>

v-else-if,顾名思义,充当 v-if 的“else-if 块”,可以连续使用:

<div v-if="type === 'A'">
  A
</div>
<div v-else-if="type === 'B'">
  B
</div>
<div v-else-if="type === 'C'">
  C
</div>
<div v-else>
  Not A/B/C
</div>

v-else-if,v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。

v-show

<h1 v-show="ok">Hello!</h1>

v-show和v-if的区别:v-show元素初始总是会被渲染,之后基于css进行样式切换,v-if条件为真的时候才会被渲染。v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
5、v-for:数据的循环表达
建议尽可能在使用 v-for 时提供 key attribute

<li v-for="item in items" :key="item.id">
      {{ item.text }}
</li>

状态维护策略:当 Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。

items可以是数组,也可以是对象

  • items是数组时:
<li v-for="(item, index) in items">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
  • items是对象时:
<li v-for="(value, key, index) in items">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
</li>

value-键值 key-键名 index-索引
也可以用of代替in

<div v-for="item of items"></div>

6、v-once:一次性绑定,数据改变时,插值内容不再改变

<span v-once>这个将不会改变: {{ msg }}</span>

7、v-html:解释html代码

<p>Using mustaches: {{ rawHtml }}</p>
<span v-html="rawHtml"></span>

输出图片

注意:动态渲染html是非常危险的,容易导致XSS攻击,不要将用户输入的内容作为插值

8、动态参数绑定

<a v-on:[eventName]="doSomething"> ... </a>

在这个示例中,当 eventName 的值为 “focus” 时,v-on:[eventName] 将等价于 v-on:focus


#### 组件化

```javascript
//创建一个组件
const app = Vue.createApp({
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data() {
    return { count: 4 }
  },
  methods: {
    reverseMessage() {
    }
  }
})
//挂载
const vm = app.mount('#app')

还有各种其他的组件选项,可以将用户定义的 property 添加到组件实例中,例如 methods,props,computed,inject 和 setup.

生命周期

1、生命周期钩子
钩子函数:
beforeCreate、
created、
beforeMounte、
mounted、
beforeUpdate、
updated 和
beforeUnmounte、
unmounted
2、生命周期图示
vue3生命周期

data和methods

1、data
data是一个函数,返回一个对象,以$data形式存储在组件实例中。

const app = Vue.createApp({
  name: 'HelloWorld',
  data() {
    return { count: 4 }
  }
})
const vm = app.mount('#app')
vm.count = 4
vm.$data.count = 4

2、methods

const app = Vue.createApp({
  name: 'HelloWorld',
  methods: {
    reverseMessage() {
    }
  }
})
const vm = app.mount('#app')
vm.reverseMessage() //执行

vue自动为methods方法绑定this,指向组件实例,在定义 methods 时应避免使用箭头函数,因为这会阻止 Vue 绑定恰当的 this 指向。
3、防抖和节流
Vue 没有内置支持防抖和节流,但可以使用 Lodash等库来实现。如下:
若组件仅仅使用一次:

<script src="https://unpkg.com/lodash@4.17.20/lodash.min.js"></script>
<script>
Vue.createApp({
    methods: {
      // 用 Lodash 的防抖函数
      click: _.debounce(function() {
        // ... 响应点击 ...
      }, 500)
    }
  }).mount('#app')
</script>

但若组件复用,则多个组件实例会共享同一个防抖函数,为了各个组件实例相互独立,可以在created 里添加该防抖函数。

app.component('save-button', {
  created() {
    // 用 Lodash 的防抖函数
    this.debouncedClick = _.debounce(this.click, 500)
  },
  unmounted() {
    // 移除组件时,取消定时器
    this.debouncedClick.cancel()
  },
  methods: {
    click() {
      // ... 响应点击 ...
    }
  },
  template: `
    <button @click="debouncedClick">
      Save
    </button>
  `
})
计算属性和侦听器

计算属性vs方法vs侦听器

<div id="demo">{{ fullName }}</div>

侦听器

const vm = Vue.createApp({
  data() {
    return {
      firstName: 'Foo',
      lastName: 'Bar',
      fullName: 'Foo Bar'
    }
  },
  watch: {
    firstName(val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName(val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
}).mount('#demo')

计算属性
计算属性默认只有 getter,不过在需要时你也可以提供一个 setter

const vm = Vue.createApp({
  data() {
    return {
      firstName: 'Foo',
      lastName: 'Bar'
    }
  },
  computed: {
    fullName:{
      // getter
      get() {
        return this.firstName + ' ' + this.lastName
      },
      // setter
      set(newValue) {
        const names = newValue.split(' ')
        this.firstName = names[0]
        this.lastName = names[names.length - 1]
      }
    }
  }
}).mount('#demo')

方法

<div id="demo">{{ fullName() }}</div>

const vm = Vue.createApp({
  data() {
    return {
      firstName: 'Foo',
      lastName: 'Bar'
    }
  },
  methods: {
    fullName() {
      return this.firstName + ' ' + this.lastName
    }
  }
}).mount('#demo')

计算属性和方法的不同:计算属性是基于它们的反应依赖关系缓存的,相比之下,每当触发重新渲染时,调用方法将总会再次执行函数(我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性 list,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 list。如果没有缓存,我们将不可避免的多次执行 list 的 getter!如果你不希望有缓存,请用 method 来替代)

class和style绑定

1、class
对象语法
使用v-bind动态切换class

<div  :class="{ active: isActive, 'text-danger': hasError }"></div>
data() {
  return {
    isActive: true,
    hasError: false
  }
}

渲染的结果为

<div class="active"></div>

数组语法

<div :class="[activeClass, errorClass]"></div>
data() {
  return {
    activeClass: 'active',
    errorClass: 'text-danger'
  }
}

三元表达式

<div :class="[isActive ? activeClass : '', errorClass]"></div>

当组件存在多个根元素,可以定义哪些部分接受这个类,可以使用 $attrs 组件属性执行此操作,如下

<div id="app">
  <my-component class="baz"></my-component>
</div>
const app = Vue.createApp({})

app.component('my-component', {
  template: `
    <p :class="$attrs.class">Hi!</p>
    <span>This is a child component</span>
  `
})

2、style
对象语法

<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

绑定一个对象可以使得语法更清晰

<div :style="styleObject"></div>
data() {
  return {
    styleObject: {
      color: 'red',
      fontSize: '13px'
    }
  }
}

数组语法
数组中包含多个对象

<div :style="[baseStyles, overridingStyles]"></div>
vue方法

数组方法:
Vue 将被侦听的数组的变更方法进行了包裹
如下方法会改变原始数组

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()
    如下方法不改变原始数组,返回一个新的数组
  • filter()、concat() 和 slice()
vue组件基础
  • 单个组件
// 创建一个Vue 应用
const app = Vue.createApp({})

// 定义一个名为 button-counter 的新全局组件
app.component('button-counter', {
  data() {
    return {
      count: 0
    }
  },
  template: `
    <button @click="count++">
      You clicked me {{ count }} times.
    </button>`
})

单个组件可以进行任意次数的复用<button-counter></button-counter>

  • 组件注册:
    组件的注册分为两种类型:全局注册和局部注册
  • 父子组件通信
    父子组件之间的通信为单向数据流,只能从父组件流向子组件
    1、 一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。
    注意: 1、尽量避免再子组件内部改变props内部的值,如有必要,将props的值作为data内部定义数据的初始值或者以props的值来定义一个计算属性;2、通过props传递数组和对象的时候是通过引用传入的,擅自改动在子组件中的状态会影响到父组件中的数值
app.component('button-counter', {
  props: ['title'],
})
<button-counter title='相信自己'></button-counter>

props也可以指定数据类型,如下:

props: {
  title: String
}

title可以时任意数据类型,字符串,数组和对象等等,仅需要写在双引号内。对于对象的传递,有如下方法

post: {
  id: 1,
  title: 'My Journey with Vue'
}
<button-counter v-bind:id="post.id" v-bind:title="post.title"></button-counter>
等价于<button-counter v-bind="post"></button-counter>

2、通过插槽传递

app.component('button-counter', {
  template: `<slot></slot>`
})
<button-counter>相信自己</button-counter>

子组件渲染出来的slot元素就是相信自己

三、高阶指南

响应式原理
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值