Vue3知识大纲

简介: Vue3知识大纲

Vue3知识大纲


Vue.js起步

数据到视图映射

网络异常,图片无法展示
|

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="app">
    <fieldset>
      <legend>数据驱动视图</legend>
      {{ message }}
    </fieldset>
  </div>
  <script>
    const App = {
      data() {
        return {
          message: 'Hello World'
        }
      }
    }
    Vue.createApp(App).mount('#app')
  </script>
</body>
</html>

修改数据

网络异常,图片无法展示
|

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="app">
    <fieldset>
      <legend>数据驱动视图</legend>
      <button @click="add">Click Me</button>
      {{ counter }}
    </fieldset>
  </div>
  <script>
    const App = {
      data() {
        return {
          counter: 0
        }
      },
      methods: {
        add() {
          this.counter++
        }
      },
    }
    Vue.createApp(App).mount('#app')
  </script>
</body>
</html>

属性绑定

网络异常,图片无法展示
|

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://unpkg.com/vue@next"></script>
</head>
![image.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/735ebe023180428c86fde3988d5398a6~tplv-k3u1fbpfcp-watermark.image?)
<body>
  <div id="app">
    <fieldset>
      <legend>属性的绑定</legend>
      <a :href="url" :title="message">百度</a>
      {{ message }}
    </fieldset>
  </div>
  <script>
    const App = {
      data() {
        return {
          url: 'https://baidu.com',
          message: 'Hello World'
        }
      }
    }
    Vue.createApp(App).mount('#app')
  </script>
</body>
</html>

双向绑定

网络异常,图片无法展示
|

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="app">
    <fieldset>
      <legend>双向绑定</legend>
      <input type="text" v-model="search">
      {{search}}
    </fieldset>
  </div>
  <script>
    const App = {
      data() {
        return {
          search: "hello"
        }
      }
    }
    Vue.createApp(App).mount('#app')
  </script>
</body>
</html>

条件渲染

网络异常,图片无法展示
|

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="app">
    <fieldset>
      <legend>条件渲染</legend>
      <p v-if="isShow"> 子组件</p>
      <button @click="isShow = !isShow">Click</button>
    </fieldset>
  </div>
  <script>
    const App = {
      data() {
        return {
          isShow: true
        }
      },
      // methods: {
      //   toggle() {
      //     this.isShow = !this.isShow
      //   }
      // },
    }
    Vue.createApp(App).mount('#app')
  </script>
</body>
</html>
复制代码

循环渲染

网络异常,图片无法展示
|

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="app">
    <fieldset>
      <legend>列表渲染</legend>
      <ul>
        <li v-for="value in items"> {{value}}</li>
      </ul>
      <button @click="add">Click</button>
    </fieldset>
  </div>
  <script>
    const App = {
      data() {
        return {
          items: ['item0', 'item1', 'item2']
        }
      },
      methods: {
        add() {
          this.items.push('item' + this.items.length)
        }
      },
    }
    Vue.createApp(App).mount('#app')
  </script>
</body>
</html>

自定义组件

网络异常,图片无法展示
|

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="app">
    <fieldset>
      <legend>自定义组件</legend>
      <todo-item></todo-item>
      <button @click="add">Click</button>
    </fieldset>
  </div>
  <script>
    const App = {
      data() {
        return {
        }
      }
    }
    const app = Vue.createApp(App)
    app.component('todo-item', {
      data() {
        return { message: 'hello' }
      },
      template: "<div>{{message}} </div>"
    })
    app.mount('#app')
  </script>
</body>
</html>

组件实例、生命周期

1、Vue有哪些⽣命周期钩⼦?

  • beforeCreate在实例初始化之后,数据观测(data observer)和event/watcher事件配置之前被调用
  • created在实例创建完成后被立即调用。在这一步,实例已完成以下的配置︰数据观测(data observer),property和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el property目前尚不可用
  • beforeMount在挂载开始之前被调用∶相关的render函数首次被调用
  • mounted实例被挂载后调用,这时 Vue.createApp({}).mount()被新创建的vm.$el替换了。如果根实例挂载到了一个文档内的元素上,当mounted被调用时vm.$el也在文档内。
  • beforeUpdate数据更新时调用,发生在虚拟DOM打补丁之前
  • updated由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子
  • beforeUnmount在卸载组件实例之前调用。在这个阶段,实例仍然是完全正常的
  • unmounted卸载组件实例后调用。调用此钩子时,组件实例的所有指令都被解除绑定,所有事件侦听器都被移除,所有子组件实例被卸载

网络异常,图片无法展示
|

2、   如果需要发送Ajax请求,最好放在哪个钩⼦内?

一般情况下,都放在mounted中,保证逻辑的统一性。因为生命周期是同步执行的,ajax是异步执行的。

服务端渲染不支持mounted方法,所以在服务端渲染的情况下统一放在created中。

3、 ⽗⼦组件嵌套时,⽗组件视图和⼦组件视图渲染完成谁先谁后?

不确定

4、 ⽗⼦组件嵌套时,如果希望在所有组件视图都渲染完成后再执⾏操

作,该如何做?

mounted() { 
     this.$nextTick(function () { 
   // 仅在渲染整个视图之后运⾏的代码 
   });
   }

应用实例与组件实例

网络异常,图片无法展示
|

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="app">
    <fieldset>
      <legend>组件实例</legend>
      {{ message }}
      <button @click="change">Click</button>
    </fieldset>
  </div>
  <script>
    const App = {
      data() {
        return {
          message: 'Hello Vue!!'
        }
      },
      methods: {
        change() {
          console.log(this)
          this.message += '!'
        }
      },
    }
    const app = Vue.createApp(App)
    console.log(app)
    const vm = app.mount('#app')
    console.log(vm)
  </script>
</body>
</html>

问题:左侧代码中的this是什么?

vm对象

生命周期

网络异常,图片无法展示
|

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://unpkg.com/vue@next"></script>
</head>
  <div id="app">
    <fieldset>
      <legend>生命周期钩子</legend>
      <span id="msg">{{ message }}</span>
      <button @click="change">Click</button>
    </fieldset>
  </div>
  <script>
    const App = {
      data() {
        return { message: 'Hello Vue'}
      },
      methods: {
        change() {
          this.message += '!'
        }
      },
      beforeCreate() {
        console.log('beforeCreate', this.message, this.$el)
      },
      created() {
        console.log('created', this.message, this.$el)
      },
      beforeMount() {
        console.log('beforeMount', this.message, this.$el)
      },
      mounted() {
        console.log('mounted', this.message, this.$el) 
      },
      beforeUpdate() {
        console.log('beforeUpdate', this.message, document.querySelector('#msg').innerText)
      },
      updated() {
        console.log('updated', this.message, document.querySelector('#msg').innerText)
      }
    }
    Vue.createApp(App).mount('#app')
  </script>
</body>
</html>

组件销毁生命周期代码演示

网络异常,图片无法展示
|

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="app">
    <fieldset>
      <legend>生命周期钩子</legend>
      <child v-show="isShow"></child>
      <button @click="isShow = !isShow">Click</button>
    </fieldset>
  </div>
  <script>
        const App = {
      data() {
        return { isShow: true }
      },
      beforeCreate() {
        console.log('root beforeCreate', this.message, this.$el)
      },
      created() {
        console.log('root created', this.message, this.$el)
      },
      beforeMount() {
        console.log('root beforeMount', this.message, this.$el)
      },
      mounted() {
        console.log('root mounted', this.message, this.$el) 
      }
    }
    const app = Vue.createApp(App)
    app.component('child', {
      template: '<div>{{text}}</div>',
      data() { 
        return {text: 'I am child'}
      }, 
      created() {
        console.log('child  created')
      },
      mounted() {
        console.log('child mounted')
      },
      beforeUnmount() {
        console.log('child  beforeUnmount')
      },
      unmounted() {
        console.log('child  unmounted')
      },
    })
    app.mount('#app')
  </script>
</body>
</html>

data、methods、computed、watch

指令

参考文档

网络异常,图片无法展示
|

data methods

网络异常,图片无法展示
|

computed

网络异常,图片无法展示
|

methods和computed的区别

  1. 调用方式不同。computed直接以对象属性方式调用,不需要加括号,而methods必须要函数执行才可以得到结果。
  2. 绑定方式不同。methods与compute纯get方式都是单向绑定,不可以更改输入框中的值。compute的get与set方式是真正的双向绑定。
  3. 是否存在缓存。methods没有缓存,调用相同的值计算还是会重新计算。competed有缓存,在值不变的情况下不会再次计算,而是直接使用缓存中的值。

watch

网络异常,图片无法展示
|

小结

  • v-text 和 v-html 有什么区别
  • data 为什么要是函数
  • 计算属性缓存是什么,如果不想缓存该怎么做
  • watch、计算属性有什么区别

网络异常,图片无法展示
|

响应式原理

什么是响应式

数据响应式

网络异常,图片无法展示
|
范例

var obj = {}
var age 
Object.defineProperty(obj, 'age', {
    get: function(){
        console.log('get age...')
        return age
    },
    set: function(val){
        console.log('set age...')
        age = val
    }
})
obj.age = 100  // 'set age...'
console.log(obj.age) // 'get age...', 100

Object.defineProperty实现响应式

function observe(data) {
  if(!data || typeof data !== 'object') return
  for(var key in data) {
    let val = data[key]  
    Object.defineProperty(data, key, {
      enumerable: true,
      configurable: true,
      get: function() {
        track(data, key)
        return val
      },
      set: function(newVal) {
        trigger(data, key, newVal)
        val = newVal
      }
    })
    if(typeof val === 'object'){
      observe(val)
    }
  }
}
function track(data, key) {
  console.log('get data ', key)
}
function trigger(data, key, value) {
  console.log('set data', key, ":", value)
}
var data = {
  name: 'hunger',
  friends: [1, 2, 3]
}
observe(data)
console.log(data.name)
data.name = 'valley'
data.friends[0] = 4
data.friends[3] = 5 // 非响应式
data.age = 6  //非响应式
复制代码

网络异常,图片无法展示
|

Proxy和Reflect

网络异常,图片无法展示
|

const dinner = {
  meal: 'tacos'
}
const handler = {
  get(target, prop) {
    console.log('get...', prop)
    //return target[prop]
    return Reflect.get(...arguments)
  },
  set(target, key, value) {
    console.log('set...', key, value)
    //target[key] = value
    return Reflect.set(...arguments)
  }
}
const proxy = new Proxy(dinner, handler)
console.log(proxy.meal)

Proxy实现响应式

function reactive(obj) {
    const handler = {
      get(target, prop, receiver) {
        track(target, prop)
        const value = Reflect.get(...arguments)
        if (typeof value === 'object') {
          return reactive(value)
        } else {
          return value
        }
      },
      set(target, key, value, receiver) {
        trigger(target, key, value)
        return Reflect.set(...arguments)
      }
    }
    return new Proxy(obj, handler)
  }
  function track(data, key) {
    console.log('get data ', key)
  }
  function trigger(data, key, value) {
    console.log('set data', key, ":", value)
  }
  const dinner = {
    meal: 'tacos'
  }
  const proxy = reactive(dinner)
  proxy.meal = 'apple'
  proxy.list = []
  proxy.list.push(1) //响应式

小结

  • Vue3和Vue2的响应式原理分别是什么,二者有什么差异
  • 手写reactive 实现track trigger
  • 用Proxy和Object.defineProperty相比有什么优点和缺点

网络异常,图片无法展示
|

条件、列表、事件、组件、双向绑定、单向数据流

v-if和v-show的区别

网络异常,图片无法展示
|

<div id="app">
  <button @click="isShow=!isShow">Toggle</button>
  <p v-if="isShow">v-if content</p>
  <p v-show="isShow">v-show content</p>
  <child v-if="isShow" title="v-if"></child>
  <child v-show="isShow" title="v-show"></child>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() {
      return { isShow: true }
    }
  })
  app.component('child', {
    props: ['title'],
    template: `<div>component {{title}}</div>`,
    created() {
      console.log('child created', this.title)
    },
    unmounted() {
      console.log('child unmounted', this.title)
    }
  })
  app.mount('#app')
</script>

v-for列表渲染

网络异常,图片无法展示
|

<div id="app">
  <div v-for="(item,index) in items" >
    <child></child>
    <button @click="remove(index)">delete</button>
  </div>
  <button @click=add>add</button>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
  //[{id:1}, {id:2}, {id:3}]
  //[child1, child2, child3]
  const app = Vue.createApp({
    data() { return { items: [] } },
    methods:{
      remove(index) { 
        console.log('remove ', index)
        this.items.splice(index,1) 
      },
      add() { this.items.push({id: Math.random()}) }
    }
  })
  app.component('child', {
    data() { return { counter: Math.random() } },
    template: `<span>{{counter}} </span>` ,
    unmounted() {
      console.log(this.counter + ' unmounted')
    }, 
  })
  app.mount('#app')
</script>

事件处理

网络异常,图片无法展示
|

<div id="app">
<span v-on:click="sayHello">click</span>
<!-- <span @click="sayHello">click</span>
<span @click="sayHello('hunger')">click</span>
<span @click="sayHello($event), sayHi('hunger')">click</span>
<span @click.once="sayHello(name)">click</span> -->
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
  Vue.createApp({
    data() {
      return {
        name: 'hunger'
      }
    },
    methods: {
      sayHello(name) {
        console.log(name)
      },
      sayHi(name) {
        console.log(name)
      }
    },
  }).mount('#app')
</script>

v-model

网络异常,图片无法展示
|

<div id="app">
  <fieldset>
    <legend> value 和 input </legend>
    <!-- value 和 input -->
    <input v-model="message" /> {{ message }}
  </fieldset>
  <fieldset>
    <legend> value 和 change </legend>
    <!-- value 和 change -->
    <textarea v-model.lazy="message"></textarea> {{ message }}
  </fieldset>
  <fieldset>
    <legend> 复选框 </legend>
    <input type="checkbox" v-model="checked" /> {{checked}}
  </fieldset>
  <fieldset>
    <legend> 多个复选框 </legend>
    <input type="checkbox" value="a" v-model="list" />
    <input type="checkbox" value="b" v-model="list" /> {{list}}
  </fieldset>
  <fieldset>
    <legend> 单选框 </legend>
    <input type="radio" value="a" v-model="theme" />
    <input type="radio" value="b" v-model="theme" /> {{theme}}
  </fieldset>
  <fieldset>
    <legend> select </legend>
    <select v-model="selected" multiple>
      <option value="AA">A</option>
      <option value="BB">B</option>
      <option value="CC">C</option>
    </select>
    <br />
    <span>Selected: {{ selected }}</span>
  </fieldset>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
  Vue.createApp({
    data() {
      return {
         message:  'aa',
         checked: false,
         list: [],
         theme: '',
         selected: []
      }
    }
  }).mount('#app')
</script>

组件基础

网络异常,图片无法展示
|

<div id="app">
  <font-size step="1" :val="fontSize" @plus="fontSize += $event"    
             @minus="fontSize -= $event"></font-size>
  <font-size step="3" :val="fontSize" @plus="fontSize += $event" 
             @minus="fontSize -= $event"></font-size>
  <p :style="{fontSize:fontSize+'px'}">Hello {{fontSize}}</p>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() { return { fontSize: 18 } }
  })
  app.component('font-size', {
    props: ['val', 'step'],
    template: `
      <div>step: {{step}}
        <button @click="onPlus">+</button>
        <button @click="$emit('minus', step)">-</button>
      </div>`,
    methods: {
      onPlus() { this.$emit('plus', parseInt(this.step)) }
    }
  })
  app.mount('#app')
</script>

组件的v-model双向绑定

网络异常,图片无法展示
|

  • 父组件通过v-model="属性"把属性传递给子组件。
  • 子组件内有一个modelvalue的ProP,接收父组件传递的数据。
  • 子组件通过触发update:modelValue修改父组件绑定的属性
<div id="app">
  <font-size step="1" v-model="fontSize"></font-size>
  <font-size step="4" v-model="fontSize"></font-size>
  <p :style="{fontSize:fontSize+'px'}">Hello {{fontSize}}</p>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script>
  const app = Vue.createApp({
    data() { return { fontSize: 16 } }
  })
  app.component('font-size', {
    props: ['modelValue', 'step'],
    template: `
      <div>step: {{modelValue}}
        <button @click="$emit('update:modelValue', +step+modelValue)">+</button>
        <button @click="$emit('update:modelValue', modelValue-step)">-</button>
      </div>`
  })
  app.mount('#app')
</script>

单向数据流

  • 什么是单向数据流?
    很多框架都使用单向数据流,指的是父组件能直接传递数据给子组件,子组件不能随意修改父组件状态。
  • 为什么要单向?
    单向数据流的目的是让数据的传递变得简单、可控、可追溯。假设都是用双向数据流,父组件维护一个状态,并且传递给所有的子组件。当其中一个子组件通过双向数据流直接修改父组件的这个状态时,其他子组件也会被修改。当这个结果产生时我们无法得知是拿个子组件修改了数据,在项目庞大时数据的管理和追湖变得更复杂。
  • 如果要双向如何实现?
    一般来说,父组件可用通过设置子组件的props直接传递数据给子组件。子组件想传递数据给父组件时,可以在内部mit一个自定义事件,父组件可在子组件上绑定该事件的监听,来处理子组件mit的事件和数据。 在Vue里,v-models实现的所谓双向绑定,本质上就这种方式。

小结

1、列表循环时key的作用?

  • 简单通俗地讲,没有key时,状态默认绑定的是位置,有key时,状态根据key的属性值绑定到了响应的数组元素。
  • key是为了更高效的更新虚拟DOM
  • 推荐使用数组内的字段(保证唯一性)作为key的唯一标识,不建议直接使用index 2、@click="handler"和@click="handler()"哪个正确?

3、父子组件如何传递数据?

4、单向数据流指的是什么?有什么好处? 5、v-model是如何实现的

Vue3组件注册、Props、Attribute、自定义事件

组件注册

网络异常,图片无法展示
|
组件注册

Props

网络异常,图片无法展示
|

非Prop的属性

网络异常,图片无法展示
|

自定义事件

网络异常,图片无法展示
|

v-model语法糖

网络异常,图片无法展示
|

小结

  • 在Vue中组件的全局注册和局部注册有什么区别,如何局部注册组件?\
  • 如何传递一个字符串类型的prop给子组件?数字类型呢?如何动态给prop赋值?\
  • 对于组件来说非prop的attribute怎么处理?\
  • v-model:foo="bar”与:foo="bar"有什么区别?如何实现v-model:foo="bar” ?\
  • Vue中的插槽是什么?\
  • 如何实现多层级嵌套的父子组件数据传递?\
  • keep-alive有什么作用

插槽、具名插槽、作用域插槽

slot插槽

网络异常,图片无法展示
|

具名插槽

网络异常,图片无法展示
|

作用域插槽

网络异常,图片无法展示
|

keep-alive与生命周期

网络异常,图片无法展示
|

网络异常,图片无法展示
|

小结

  • Vue中的插槽是什么?
  • 具名插槽怎么用?
  • 作用域插槽是什么?

爷孙组件数据传递

Provide和Inject

网络异常,图片无法展示
|

网络异常,图片无法展示
|

过渡与动画

使用class切换实现过渡和动画

网络异常,图片无法展示
|

修改style实现过渡和动画

网络异常,图片无法展示
|

transition组件创建的class

网络异常,图片无法展示
|

transition组件和animate.css便捷实现特

多个元素轮流切换过渡实现

网络异常,图片无法展示
|

动态组件专场效果实现

网络异常,图片无法展示
|

transition-group

网络异常,图片无法展示
|

使用Vue CLI4搭建Vue项目

网络异常,图片无法展示
|

目录结构与执行流程

网络异常,图片无法展示
|

引入Sass解决各种bug

网络异常,图片无法展示
|

scoped

网络异常,图片无法展示
|

@vue:cli-service# @vue:cli-service

网络异常,图片无法展示
|

vue.config.js配置

网络异常,图片无法展示
|

webpack

网络异常,图片无法展示
|

Vite 搭建项目

vite是什么解决什么问题

网络异常,图片无法展示
|

诞生思路

网络异常,图片无法展示
|

vite体验

网络异常,图片无法展示
|

Composition API

选项式API的痛点

网络异常,图片无法展示
|

组合式API的优势和用法

网络异常,图片无法展示
|

用法

选项式API改造成组合式API

生命周期钩子概览

网络异常,图片无法展示
|

Setup、ref、reactive、toRef、toRefs用法详解

网络异常,图片无法展示
|

网络异常,图片无法展示
|

网络异常,图片无法展示
|

VueRouter

VueRouter4的安装

网络异常,图片无法展示
|

VueRouter4的使用

网络异常,图片无法展示
|

原生JS造一个Hash模式的Router

网络异常,图片无法展示
|

原生JS造一个History模式的Router

网络异常,图片无法展示
|

VueRouter4的Hash模式和History模式

网络异常,图片无法展示
|

动态路由与响应参数变化(路由匹配)

网络异常,图片无法展示
|

导航守卫

网络异常,图片无法展示
|

在组合式API中使用VueRouter

网络异常,图片无法展示
|

beforeRouteUpdate路由守卫的使用场景

路由懒加载

网络异常,图片无法展示
|

路由切换过渡动效

网络异常,图片无法展示
|

Vuex4.0的使用和原理

组件间数据传递的几种方法、为什么需要Vuex

网络异常,图片无法展示
|

EventBus的不便之处

网络异常,图片无法展示
|

相关文章
|
17天前
vue3学习(3)
vue3学习(3)
|
14天前
|
JavaScript API
Vue3中的计算属性能否动态修改
【9月更文挑战第5天】Vue3中的计算属性能否动态修改
49 10
|
7天前
|
JavaScript
Vue3中路由跳转的语法
Vue3中路由跳转的语法
111 58
|
10天前
|
前端开发
vue3+ts项目中使用mockjs
vue3+ts项目中使用mockjs
214 58
|
6天前
|
JavaScript 索引
Vue 2和Vue 3的区别以及实现原理
Vue 2 的响应式系统通过Object.defineProperty来实现,它为对象的每个属性添加 getter 和 setter,以便追踪依赖并响应数据变化。
21 9
|
7天前
|
JavaScript 开发工具
vite如何打包vue3插件为JSSDK
【9月更文挑战第10天】以下是使用 Vite 打包 Vue 3 插件为 JS SDK 的步骤:首先通过 `npm init vite-plugin-sdk --template vue` 创建 Vue 3 项目并进入项目目录 `cd vite-plugin-sdk`。接着,在 `src` 目录下创建插件文件(如 `myPlugin.js`),并在 `main.js` 中引入和使用该插件。然后,修改 `vite.config.js` 文件以配置打包选项。最后,运行 `npm run build` 进行打包,生成的 `my-plugin-sdk.js` 即为 JS SDK,可在其他项目中引入使用。
|
8天前
|
JavaScript 开发者
彻底搞懂 Vue3 中 watch 和 watchEffect是用法
彻底搞懂 Vue3 中 watch 和 watchEffect是用法
|
14天前
|
JavaScript API
如何使用Vue3的可计算属性
【9月更文挑战第5天】如何使用Vue3的可计算属性
44 13
|
5天前
|
JavaScript 调度
Vue3 使用 Event Bus
Vue3 使用 Event Bus
10 1
|
6天前
|
JavaScript
Vue3 : ref 与 reactive
Vue3 : ref 与 reactive
9 1