0


vue核心语法(超详细)

01_认识Vuejs

  • 全称是Vue.js或者Vuejs。
  • 基于标准HTML,CSS和JavaScript构建,并提供了一套声明式的、组件化的编程模型。

什么是渐近式框架?

  • 表示我们可以在项目中一点点来引入和使用Vue,而不一定需要全部使用Vue来开发整个项目。

02_引入Vue的方式

方式一 : CDN引入

<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script><div id="app">{{ message }}</div><script>const{ createApp }= Vue
  
  createApp({data(){return{message:'Hello Vue!'}}}).mount('#app')</script>

方式二:下载Vue的JavaScript文件,手动引入

方式三: npm 包管理下载

npm init vue@latest

方式四:通过Vue CLI创建项目,并使用


03_声明式和命令式编程

声明式和命令式是两种编程规范。Vue是声明式的,Jquery那样直接操作DOM是命令式

  • 声明式就像你告诉你朋友画一幅画,你不用管他画的细节
  • 命令式就像按照你的命令,一步步把画画出来

换言之:

  • 声明式编程:告诉 “机器”你想要的是什么,让机器想出如何去做。
  • 命令式:命令 “机器” 如何去做事情,这样不管你想要的是什么,他都会按照你的命令去实现。

03-1 MVVM模型

  1. MVVM是前端视图层的概念,主要关注于视图层分离,也就是说:MVVM把前端的视图层,分成了三部分

Model , View ,ViewModel ,

  1. 主要把每个页面,分成了M,V,VM,其中 M对应Model , V对应View , VM对应ViewModel

M:里面保存的是每个页面中单独的数据,比如页面中有一个table表格,而这个table表格需要发送axios请求,服务器会返回一个数据,这个数据可能是对象,也可能是数组,这个返回的数据就是M
V:每个页面中的html页面结构 **
VM
它是一个调度者(中间层),分割了M和V ,**我们的数据需要渲染到页面中,不能直接渲染,需要调用VM,也就是M层的数据需要渲染到V的页面中去,必须经过VM层做处理

MVVM好处:

前端页面中使用MVVM的思想,主要是为了让我们开发更加方便,因为MVVM提供了数据的双向绑定,注意:数据的双向绑定时VM提供的


04_选项式 API (Options API)

选项式 API ,我们可以用包含多个选项的对象来描述组件的逻辑,例如 data 、methods 和 mounted。选项所定义的属性都会暴露在函数内部的this上,它会指向当前的组件实例。

props

用于接收父组件传递过来的属性
详细说明:
props 会暴露到 this上
示例:

exportdefault{props:['foo'],created(){// props 会暴露到 `this` 上
    console.log(this.foo)}}

除了使用字符串数组来声明 prop 外,还可以使用对象的形式:

exportdefault{props:{title: String,likes: Number
  }}

data

用于声明组件初始化响应式状态的函数。
详细说明:
data函数应当返回一个普通JavaScript对象,Vue会将它转换为响应式对象。实例创建后。可以通过this.

    d
   
   
    a
   
   
    t
   
   
    a
   
   
    访问该响应式对象。组件实例也代理了该数据对象上的所有属性,因此
   
   
    t
   
   
    h
   
   
    i
   
   
    s
   
   
    .
   
   
    a
   
   
    等价于
   
   
    t
   
   
    h
   
   
    i
   
   
    s
   
   
    .
   
  
  
   data 访问该响应式对象。组件实例也代理了该数据对象上的所有属性,因此this.a 等价于 this.
  
 
data访问该响应式对象。组件实例也代理了该数据对象上的所有属性,因此this.a等价于this.data.a

示例:

    Vue.createApp({data(){return{count:100}},// 生命周期 函数created(){
        console.log(this.count)// 100
        console.log(this.$data.count)// 100},}).mount("#app")

注意:
在Vue2.x的时候,data是一个对象
在Vue3.x的时候,必须传入一个函数

methods

用于声明要混入到组件实例中的方法
详细说明:
声明的方法可以直接通过组件实例访问,或者在模板语法表达式中使用。所有的方法都会将它们的this 上下文自动绑定为组件实例。
示例:

exportdefault{data(){return{a:1}},methods:{plus(){this.a++}},created(){this.plus()
    console.log(this.a)// => 2}}

注意:在声明方法时避免使用箭头函数,因为它们不能通过this访问组件实例

computed

用于声明要在组件实例上暴露的计算属性。
详细说明:
该选项接收一个对象,其中键是计算属性的名称,值是一个计算属性getter,或一个具有get和set方法的对象(用于声明可写的计算属性)。
image.png
注意:如果你为计算属性使用了箭头函数,则 this 不会指向该组件实例,可以通过该函数的第一个参数来访问。

exportdefault{computed:{aDouble:(vm)=> vm.a *2}}
computed的set和get
exportdefault{data(){return{a:1}},computed:{// 只读aDouble(){returnthis.a *2},// 可写aPlus:{get(){returnthis.a +1},set(v){this.a = v -1}}},created(){
    console.log(this.aDouble)// => 2
    console.log(this.aPlus)// => 2this.aPlus =3
    console.log(this.a)// => 2
    console.log(this.aDouble)// => 4}}

image.png

methods和computed区别

computed:

  • 调用直接以对象属性方式调用,不需要加括号。
  • 有缓存,也就是说当计算结果不变时,该函数只会调用一次,提高了运行速度。
  • 必须有返回值。

methods:

  • 调用要加括号,以方法的形式调用。
  • 没有缓存,调用相同的值还是会重新计算。

watch

用于声明在数据更改时调用的侦听回调。

基本使用

image.png

监听复杂数据
<script>exportdefault{name:"Home",data(){return{person:{name:""}};},watch:{"person.name":{handler(newVal, oldVal){
        console.log(`新的值: ${newVal}`);
        console.log(`旧的值: ${oldVal}`);},}},};</script>
immediate (立即处理 进入页面就触发)
<template><div>输入:<input type="text" v-model="text"></div></template><script>exportdefault{name:"Home",data(){return{text:"",};},watch:{text:{handler(newVal, oldVal){},immediate:true}},};</script>
deep 深度监听
<script>exportdefault{name:"Home",data(){return{person:{name:""}};},watch:{person:{handler(newVal, oldVal){},deep:true}},};</script>

05_模板语法

Mustache语法

最基本的数据绑定形式是文本插值,Mustache里面可以写入表达式
示例:

<!-- 基本使用 --><h2>{{count}}</h2><!-- 表达式 --><h2>{{ count *2}}</h2>data(){return{count:100}}

常见的基本指令

v-once指令

仅渲染元素和组件一次,之后跳过渲染,可以用来优化更新时的性能。
示例:

<h2  v-once>{{message}}</h2>
v-text指令

更新元素的文本内容
绑定值类型:string
详细说明:
v-text通过设置元素的textContent属性来工作,因此它将覆盖元素中所有现有的内容。如果你需要更新 textContent 的部分,可以使用 Mustache 语法 两者是一样的
示例:

<h2 v-text="message"></h2><!-- 等同于 --><h2>{{message}}</h2>
v-html指令

用法和v-text是一样的,区别在于v-html可以解析html元素

v-pre指令

跳过该元素及其所有子元素的编译。也就是一次都不编译。
详细说明:
元素内具有 v-pre ,所有 Vue 模板语法都会被保留并按原样渲染。
示例:

<span v-pre>{{this will not be compiled }}</span>
v-cloak指令

用于隐藏尚未完成编译的DOM模板
详细说明:
该指令只在没有构建步骤的环境下需要使用。
当使用直接在DOM中书写的模板时,可以会出现一种叫做 “未编译模板闪现” 的情况:用户可能先看到的是还没有编译完成的双大括号标签,直到挂载的组件将它们替换为实际渲染的内容。v-cloak 会保留在所绑定的元素上,直到相关组件实例被挂载后才移出。配合像 [v-cloak] { display: none } 这样的 CSS 规则。
示例:

[v-cloak]{display: none;}
<div v-cloak>
  {{ message }}
</div>

v-bind绑定属性

动态的绑定一个或多个 attribute,也可以是组件的prop。
缩写: : 或者 . (当使用.prop修饰符)
绑定值类型:any (带参数) | object (不带参数)
修饰符:

  - .camel  - 将短横线命名的attribute转变为驼峰式命名
  - .prop - 强制绑定为 DOM property
  - .attr - 强制绑定为 DOM attribute

_用途: _
当用于绑定 class 或 style attribute, v-bind 支持额外的值类型如数组或对象。

绑定基本属性:
<!-- 绑定 img 的 src --><img v-bind:src="imgurl"><img :src="imgurl"><!-- 绑定 a 的 href --><a v-bind:href="baidu">百度一下</a>
<!-- 绑定 attribute --><img v-bind:src="imageSrc"/><!-- 动态 attribute 名 --><button v-bind:[key]="value"></button><!-- 缩写 --><img :src="imageSrc"/><!-- 缩写形式的动态 attribute 名 --><button :[key]="value"></button><!-- 内联字符串拼接 --><img :src="'/path/to/images/' + fileName"/>
绑定class和style
<!--class 绑定 isRed是一个布尔值 --><div :class="{ red: isRed }"></div><div :class="[classA, classB]"></div><div :class="[classA, { classB: isB, classC: isC }]"></div><!-- style 绑定 --><div :style="{ fontSize: size + 'px' }"></div><div :style="[styleObjectA, styleObjectB]"></div><!-- 绑定对象形式的 attribute --><div v-bind="{ id: someProp, 'other-attr': otherProp }"></div><!-- prop 绑定。“prop” 必须在子组件中已声明。 --><MyComponent :prop="someThing"/><!-- 传递子父组件共有的 prop --><MyComponent v-bind="$props"/><!-- XLink --><svg><a :xlink:special="foo"></a></svg>

v-on绑定事件

给元素绑定事件监听器
缩写: @
绑定值类型:event
修饰符:

  - .stop - 调用 event.stopPropagation()
  - .prevent - 调用 event.preventDefault()
  - .capture - 在捕获模式添加事件监听器
  - .self - 只有事件从元素本身发出才触发处理函数
  - .{keyAlias} - 只有某些按键下触发处理函数
  - once - 最多触发一次处理函数
  - .left - 只在鼠标左键事件触发处理函数
  - .right - 只在鼠标右键事件触发处理函数
  - middle - 只在鼠标中键事件触发处理函数。
  - passive - 通过 { passive: true } 附加一个DOM事件。

_用途: _
绑定事件
示例:

<!-- 方法处理函数 --><button v-on:click="doThis"></button><!-- 动态事件 --><button v-on:[event]="doThis"></button><!-- 内联声明 --><button v-on:click="doThat('hello', $event)"></button><!-- 缩写 --><button @click="doThis"></button><!-- 使用缩写的动态事件 --><button @[event]="doThis"></button><!-- 停止传播 --><button @click.stop="doThis"></button><!-- 阻止默认事件 --><button @click.prevent="doThis"></button><!-- 不带表达式地阻止默认事件 --><form @submit.prevent></form><!-- 链式调用修饰符 --><button @click.stop.prevent="doThis"></button><!-- 按键用于 keyAlias 修饰符--><input @keyup.enter="onEnter"/><!-- 点击事件将最多触发一次 --><button v-on:click.once="doThis"></button><!-- 对象语法 --><button v-on="{ mousedown: doThis, mouseup: doThat }"></button>

Vue的条件渲染

v-if

“真正的”条件渲染,动态的向DOM树内添加或删除 DOM元素。v-if适合条件很少改变的情况。初始渲染:v-if初始值为false时,组件不会渲染,生命周期钩子不会执行;
image.png

v-show

v-show无论初始状态是什么,组件都会渲染,v-show 不支持 元素,也不支持 v-else。


v-for列表渲染

基于原始数据多次渲染元素或模板

<div v-for="item in items">{{ item.text }}</div>
v-for中key的作用

v-for中key属性的值应唯一,起到身份认证的作用,避免v-for"就地更新"策略导致的问题。官方说法:v-for中key 主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。 如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。 而使用 key 时,它会基于 key的变化重新排列元素顺序,并且会移除 key 不存在的元素。

key属性可以用来提升v-for渲染的效率!,vue不会去改变原有的元素和数据,而是创建新的元素然后把新的数据渲染进去

认识VNode

VNode的全称是Virtual Node,也就是 虚拟节点
VNode的本质是一个JavaScript的对象
一个个VNode组成的就是虚拟DOM
image.png

v-model数据双向绑定

在表单输入元素或组件上创建双向绑定。
仅限:

  - <input>
  - <select>
  - <textarea>
  - components

修饰符:

  - .lazy -监听 change 事件而不是input
  - .number - 将输入的合法符串转为数字
  - .trim - 移出输入内容两端空格
v-model基本使用
<div id="app"><!-- 手动实现 也是v-model的原理 --><input :value="message" type="text" @input="inpChange"><!-- v-model 实现 --><input type="text" v-model="message"><h2>{{message}}</h2></div><script>const app = Vue.createApp({data(){return{message:"100"}},methods:{inpChange(event){this.message = event.target.value
        }},})// 挂载
    app.mount("#app")</script>
表单输入绑定
<input
  :value="text"
  @input="event => text = event.target.value">

等价于:

<input v-model="text">
textarea多行文本
<span>Multiline message is:</span><pstyle="white-space: pre-line;">{{ message }}</p><textareav-model="message"placeholder="add multiple lines"></textarea>
checkbox复选框

单一的复选框

<input type="checkbox" id="checkbox" v-model="checked"/><label for="checkbox">{{ checked }}</label>
多个复选框
exportdefault{data(){return{checkedNames:[]}}}
<div>Checked names:{{ checkedNames }}</div><input type="checkbox" id="jack" value="Jack" v-model="checkedNames"><label for="jack">Jack</label><input type="checkbox" id="john" value="John" v-model="checkedNames"><label for="john">John</label><input type="checkbox" id="mike" value="Mike" v-model="checkedNames"><label for="mike">Mike</label>
radio 单选框
<div>Picked:{{ picked }}</div><input type="radio" id="one" value="One" v-model="picked"/><label for="one">One</label><input type="radio" id="two" value="Two" v-model="picked"/><label for="two">Two</label>
select选择器
<div>Selected:{{ selected }}</div><select v-model="selected"><option disabled value="">Please select one</option><option>A</option><option>B</option><option>C</option></select>

06 Vue组件化

Vue组件化开发思想

  • 组件化:最初的目的是代码重用,功能相对单一或者独立。在整个系统的代码层次上位于最底层,被其他代码所依赖,所以说组件化是纵向分层。
  • 模块化:最初的目的是将同一类型的代码整合在一起,所以模块的功能相对复杂,但都同属于一个业务。不同模块之间也会存在依赖关系,但大部分都是业务性的互相跳转,从地位上来说它们都是平级的。

注册Vue的全局组件

在任何一个vue实例里面都可以使用

app.component("item-vue", itemVue)

第一个参数为组件的名称,
第二个参数是你要注册的对象(组件)
image.png

注册Vue的局部组件

只能在声明的vue实例里面起作用

const app = Vue.createApp({data(){return{}},// 注册局部组件components:{"home-vue":{template:"<div>你好</div>",data(){return{}},}}})

Vue CLI 安装和使用(请使用vite构建,CLI已维护)

什么是Vue脚手架?

  - 脚手架其实是建筑工程中的一个概念,帮助我们搭建项目的工具称之为脚手架;

Vue脚手架 Vue CLI

  - CLI是 Command-Line Interface ,翻译为命令行界面
  - 我们可以通过CLI选择项目的配置和创建出我们的项目
  - Vue CLI内置了 webpack相关的配置,我们不需要从零来配置
Vue Cli

安装cli

npm install @vue/cli -g

如果是比较旧的版本,可以通过下面命令升级

npm update @vue/cli -g

创建项目

vue create 项目名称

vite脚手架

官方文档:https://vitejs.dev/

安装项目

npm create vite@latest

Vue的项目目录分析

image.png

node_modules
  • 安装所需要依赖的包管理文件
public
  • 静态文件
src
  • 源代码文件
.browserslistrc
  • 对浏览器进行适配
.gitignore
  • 忽略的文件
babel.config.js
  • 对需要转换为babel的配置文件
jsconfig.json
  • 给vscode用的,和我们没有关系
package-lock.json
  • 记录项目安装的依赖项
package.json
  • 记录项目安装的依赖项
README.MD
  • 项目描述
vue.config.js
  • 对全局的配置

07 组件化通信

父组件传递给子组件

父组件传递给子组件: 通过props属性接收
接收方式有两种:数组和对象

exportdefault{props:['foo'],created(){// props 会暴露到 `this` 上
    console.log(this.foo)}}
exportdefault{props:{title: String,likes: Number
  }}

image.png


子组件传递给父组件

官网文档:https://cn.vuejs.org/guide/components/events.html#component-events

子组件传递给父组件:通过$emit触发事件 $emit 方法触发自定义事件

exportdefault{methods:{submit(){this.$emit('someEvent')}}}

父组件可以通过 v-on (缩写为 @) 来监听事件:

<MyComponent @some-event="callback"/>
事件参数:

$emit(‘事件名称’, 你要传递的参数)

<button @click="$emit('increaseBy', 1)">
  Increase by 1</button>

父组件接收

<MyButton @increase-by="increaseCount"/>
methods:{increaseCount(n){this.count += n
  }}
声明触发的事件

组件可以显式地通过 emits 选项来声明它要触发的事件

exportdefault{// 可以清楚的看到有哪些事件发出去emits:["changeCounter"],methods:{addCount(i){this.$emit("changeCounter",i)}}}

非props的attribute

父组件当传递属性给子组件时,子组件没有通过props接收,就会默认传递给子组件的根标签上
image.png

禁用Attribute继承和多根节点
禁用Attributte

父组件传递的属性不想继承在子组件的根节点上可以使用 inheritAttrs 设置为flase
image.png

多个根节点

当有多个根节点时,请使用v-bind绑定$attrs 不然会报警告
image.png

08 插槽Slot和非父子通信

插槽Slot的作用

插槽就是 子组件 中的提供给 父组件 使用的一个占位符,用 表示,父组件可以在这个占位符中填充任何模板代码
插槽显不显示是由父盒子决定的,插槽在哪个位置上显示是由子组件决定的。

插槽Slot基本使用

<FancyButton>
  Click me! <!-- 插槽内容 --></FancyButton>
<buttonclass="fancy-btn"><slot></slot><!-- 插槽出口 --></button>

image.png

具名插槽Slot使用

带 name 的插槽被称为具名插槽 (named slots)。没有提供 name 的 出口会隐式地命名为“default”

子组件,就是给slot标签添加上 name:名字(什么都可以)
父组件,在父组件调用子组件的地方里面添加并加上对应的slot名字,就可以使对应的内容显示在对应的子组件具名插槽中

示例:
image.png

作用域插槽Slot使用

作用域插槽就是通过子组件中 传递值给父组件,父组件接收使用

<slotname="button":title="'你好'">left</slot>
<template#button="slotProps"><button>{{ slotProps.title }}</button></template>

非父子组件通信 Provide和Inject

官方地址:https://cn.vuejs.org/guide/components/provide-inject.html

  1. 基本传值

provide写成一个对象

exportdefault{provide:{message:100}}
  1. 获取data里面的值进行传递

provide写成一个函数

exportdefault{data(){return{message:'hello!'}},provide(){// 使用函数的形式,可以访问到 `this`return{message:this.message
    }}}

09_额外知识补充

组件的生命周期

什么是生命周期?
每一个vue实例从创建到销毁的过程,就是这个vue实例的生命周期。

lifecycle.16e4c08e.png

beforeCreate( 创建前 )
  • 组件被创建之前会调用,data、methods都没有初始化,一般在这个阶段不进行操作。
created( 创建完成 )
  • 这个时候,Vue实例中的data、methods已经被初始化,属性也被绑定,但是此时组件的template还没有被挂载,还是虚拟dom,真实dom还没有生成。
  • 一般在created里面发送网络请求 ,监听watch数据 等等。
beforeMount( 组件挂载之前 )
  • 此时模板已经编译完成,但是还没有渲染到页面中,(即为虚拟dom加载为真实dom)
  • 一般在这个阶段不做操作
mounted( 组件挂载完成 )
  • 虚拟DOM生成真实DOM完成,此时模板已经被渲染成真实DOM
  • 作用:获取DOM,使用DOM
beforeUpdate( 组件更新之前 )
  • 更新前状态(view层的数据还没有改变,data中的数据已经改变了),重新渲染之前触发,然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染。只有view上面的数据变化才会触发beforeUpdate和updated,仅属于data中的数据改变是并不能触发。也就是说数据已经改变了,DOM还没有更新。
updated( 组件更新完成 )
  • 数据已经更改完成,dom也重新render完成。
beforeUnmount( 组件卸载之前 )
  • 当这个钩子被调用时,组件实例依然还保有全部的功能。
  • 作用:清除计时器等等
unmounted( 组件卸载完成 )
  • 在一个组件实例被卸载之后调用。
  • 作用:卸载事件监听

组件中的ref引用

ref用于获取元素和组件实例
用法:给元素或组件绑定一个ref的attribute属性

  1. 基本使用
<input ref="input">

获取:

<script>exportdefault{mounted(){
    console.log(this.$refs.input)}}</script><template><input ref="input"/></template>
  1. 获取组件实例
<template><div class="app"><Home ref="homeCom"></Home></div></template><script>import Home from'./components/Home.vue';exportdefault{components:{
    Home
  },mounted(){
    console.log(this.$refs.homeCom)}}</script>
  1. 在父组件中可以主动调用子组件的对象方法
<template><div class="app"><Home ref="homeCom"></Home></div></template><script>import Home from'./components/Home.vue';exportdefault{components:{
    Home
  },mounted(){this.$refs.homeCom.homeClick()// 我是home}}</script>
<template><div class="home"><p>home</p></div></template><script>exportdefault{methods:{homeClick(){
      console.log("我是home")}}}</script>
  1. 获取子组件中的根元素 $el
<template><div class="app"><Home ref="homeCom"></Home></div></template><script>import Home from'./components/Home.vue';exportdefault{components:{
    Home
  },mounted(){
    console.log(this.$refs.homeCom.$el)}}</script>
    p
   
   
    a
   
   
    r
   
   
    e
   
   
    n
   
   
    t
   
   
    和
   
  
  
   parent和
  
 
parent和root

$parent用来获取当前组件的父组件
$root 用来获取当前组件


动态组件的使用

元素

一个用于渲染动态组件或元素的“元组件”。

**、 **和 具有类似组件的特性,也是模板语法的一部分。但它们并非真正的组件,同时在模板编译期间会被编译掉。因此,它们通常在模板中用小写字母书写。

详细信息:
要渲染的实际组件由 is 决定。

  • 当 is 是字符串,它既可以是 HTML 标签名也可以是组件的注册名。
  • 或者,is 也可以直接绑定到组件的定义。

案例:

<script>import Foo from'./Foo.vue'import Bar from'./Bar.vue'exportdefault{components:{ Foo, Bar },data(){return{view:'Foo'}}}</script><template><component :is="view"/></template>

keep-alive组件

地址:https://cn.vuejs.org/guide/built-ins/keep-alive.html#keepalive

内置组件

image.png
默认会缓存内部的所有组件实例,但我们可以通过 include 和 exclude prop 来定制该行为。这两个 prop 的值都可以是一个以英文逗号分隔的字符串、一个正则表达式,或是包含这两种类型的一个数组.
它会根据组件的 name 选项进行匹配,所以组件如果想要条件性地被 KeepAlive 缓存,就必须显式声明一个 name 选项。

<!-- 以英文逗号分隔的字符串 --><KeepAlive include="a,b"><component :is="view"/></KeepAlive><!--正则表达式(需使用 `v-bind`)--><KeepAlive :include="/a|b/"><component :is="view"/></KeepAlive><!--数组(需使用 `v-bind`)--><KeepAlive :include="['a', 'b']"><component :is="view"/></KeepAlive>

image.png

监听keep-alive里面组件的生命周期

activated 和 deactivated 生命周期
因为keep-alive包裹的组件不会被销毁,所以无法监听 created 和 unmounted 生命周期


异步组件的使用

异步组件是对网站的一种优化,其意思就是懒加载,当我们需要用到那个组件的时候才去打包挂载到DOM树上。

import{ defineAsyncComponent }from'vue'// 会为 Foo.vue 及其依赖创建单独的一个块// 它只会按需加载//(即该异步组件在页面中被渲染时)const Foo =defineAsyncComponent(()=>import('./Foo.vue'))

组件的v-model

v-model 可以在组件上使用以实现双向绑定。是一种组件通信。
v-bind:modelValue 这个等于 父组件传递子组件的属性
@update:modelValue 接收子组件$emit的事件

<CustomInput
  v-bind:modelValue="searchText"//这个等于 父组件传递子组件
  @update:modelValue="searchText = newValue"//接收子组件$emit的事件/>
<script>import CustomInput from'./CustomInput.vue';exportdefault{components:{
    CustomInput
  },data(){return{searchText:100}}}</script>
exportdefault{// 接收父组件传递过来的值  modelValue是固定的props:{modelValue:{type:Number,default:0}},methods:{change(){// 向父组件发出一个事件 update:modelValu 是固定的this.$emit("update:modelValue",9999)}}}

组件的混入Mixin

不再推荐
在 Vue 2 中,mixins 是创建可重用组件逻辑的主要方式。尽管在 Vue 3 中保留了 mixins 支持,但对于组件间的逻辑复用,Composition API** 是现在更推荐的方式。**

10 Composition API

什么是Composition API

Composition API是Vue3 提供了一种新的方式(组合函数式)来组织和编写组件的逻辑代码。


组合式 API:setup()

注意
setup() 组件选项的用法。对于结合单文件组件使用的组合式 API,推荐通过

setup()钩子是组合式API的入口 ,使用场景:

  1. 非单文件组件中使用组合式API
  2. 需要基于选项式API的组件中集成组合式API时

总结:尽量使用

setup()基本使用

在 setup() 函数中返回的对象会暴露给模板和组件实例。其他的选项也可以通过组件实例来获取 setup() 暴露的属性

<script>import{ ref }from'vue'exportdefault{setup(){const count =ref(0)// 返回值会暴露给模板和其他的选项式 API 钩子return{
      count
    }},mounted(){
    console.log(this.count)// 0}}</script><template><button @click="count++">{{ count }}</button></template>

在模板中访问从 setup 返回的 ref 时,它会自动浅层解包,因此你无须再在模板中为它写 .value。当通过 this 访问时也会同样如此解包。

setup()参数props

setup 函数的第一个参数是组件的 props。和标准的组件一致,一个 setup 函数的 props 是响应式的,并且会在传入新的 props 时同步更新。

exportdefault{props:{title: String
  },setup(props){
    console.log(props.title)}}

请注意如果你解构了 props 对象,解构出的变量将会丢失响应性。因此我们推荐通过 props.xxx 的形式来使用其中的 props。
如果你确实需要解构 props 对象,或者需要将某个 prop 传到一个外部函数中并保持响应性,那么你可以使用 toRefs() 和 toRef() 这两个工具函数:

import{ toRefs, toRef }from'vue'exportdefault{setup(props){// 将 `props` 转为一个其中全是 ref 的对象,然后解构const{ title }=toRefs(props)// `title` 是一个追踪着 `props.title` 的 ref
    console.log(title.value)// 或者,将 `props` 的单个属性转为一个 refconst title =toRef(props,'title')}}
setup()参数contxt

传入 setup 函数的第二个参数是一个 Setup 上下文对象。上下文对象暴露了其他一些在 setup 中可能会用到的值:

exportdefault{setup(props, context){// 透传 Attributes(非响应式的对象,等价于 $attrs)
    console.log(context.attrs)// 插槽(非响应式的对象,等价于 $slots)
    console.log(context.slots)// 触发事件(函数,等价于 $emit)
    console.log(context.emit)// 暴露公共属性(函数)
    console.log(context.expose)}}

Setup中的数据响应式

响应式API:reactive()

接收一个复杂数据类型,返回一个对象的响应式代理。
创建一个响应式对象:

const obj =reactive({count:0})
obj.count++

ref的解包:

const count =ref(1)const obj =reactive({ count })// ref 会被解包
console.log(obj.count === count.value)// true// 会更新 `obj.count`
count.value++
console.log(count.value)// 2
console.log(obj.count)// 2// 也会更新 `count` ref
obj.count++
console.log(obj.count)// 3
console.log(count.value)// 3
响应式API:ref()

接受一个值,返回一个响应式的,可以修改的ref对象,这个对象只有一个.vaule属性。

const count =ref(0)
console.log(count.value)// 0

count.value++
console.log(count.value)// 1

ref在模板中自动解包:


<div>{{count}}</div>
<div>{{count + 1}}</div>
响应式API:readonly()

接收一个对象(无论是响应式还是普通的) 或是一个 ref ,返回一个原值的只读代理
单项数据流:
子组件拿到数据后只能使用,不能修改,如果要修改,通过事件传递给父组件来修改。

const original =reactive({count:0})const copy =readonly(original)watchEffect(()=>{// 用来做响应性追踪
  console.log(copy.count)})// 更改源属性会触发其依赖的侦听器
original.count++// 更改该只读副本将会失败,并会得到一个警告
copy.count++// warning!
响应式API:computed()

接受一个 getter 函数,返回一个只读的响应式 ref 对象。该 ref 通过 .value 暴露 getter 函数的返回值。它也可以接受一个带有 get 和 set 函数的对象来创建一个可写的 ref 对象。

const count =ref(1)const plusOne =computed({get:()=> count.value +1,set:(val)=>{
    count.value = val -1}})

plusOne.value =1
console.log(count.value)// 0

Setup中响应式工具

image.png

setup中禁用this

setup中ref获取元素和组件

<template><div class="app"><!--     ref里面是字符串 --><h3 ref="h3El">哈哈哈哈</h3></div></template><script>import{ onMounted, ref }from'vue';exportdefault{setup(){const h3El =ref()onMounted(()=>{
      console.log(h3El.value)})return{
      h3El
    }},}</script>

组件的生命周期函数

在 少了两个生命周期:beforeCreate 和 created
如果需要这两个生命周期,直接在setup中写你的业务逻辑

Provide/Inject使用

官方文档:https://cn.vuejs.org/api/composition-api-dependency-injection.html#provide

provide

provide() 接受两个参数:第一个参数是要注入的 key,可以是一个字符串或者一个 symbol,第二个参数是要注入的值。

<script setup>
import { ref, provide } from 'vue'
import { fooSymbol } from './injectionSymbols'

// 提供静态值
provide('foo', 'bar')

// 提供响应式的值
const count = ref(0)
provide('count', count)

// 提供时将 Symbol 作为 key
provide(fooSymbol, count)
</script>

defineProps() 和 defineEmits()

  - defineProps 和 defineEmits 都是只能在 <script setup> 中使用的**编译器宏**。他们不需要导入,且会随着 <script setup> 的处理过程一同被编译掉。
<script setup>
const props = defineProps({
  foo: String
})

const emit = defineEmits(['change', 'delete'])
// setup 代码
</script>

本文转载自: https://blog.csdn.net/m0_62336865/article/details/129419889
版权归原作者 小罗js 所有, 如有侵权,请联系我们删除。

“vue核心语法(超详细)”的评论:

还没有评论