摘要

本文介绍了如何开始写第一个vue3程序,比较了与vue2的区别。并介绍vue3中非常重要的setup的基本使用。需要你有vue基础。

内容

  1. 第一个vue3程序,重温经典双向绑定

  2. 认识setup配置项

  3. setup 定义响应式数据(ref单值)

  4. setup 定义响应式数据(reactive对象)

  5. setup 定义响应式数据(reactive对象+toRefs)

  6. setup 定义计算属性

  7. setup 定义watch

  8. setup 定义生命周期钩子函数

  9. 小结

第一个vue3程序

学写第一个vue3程序, 感受从vue2到的vue3的平滑过渡。

<script src="https://unpkg.com/vue@next"></script> <body>   <div id="app">     <h3>经典的双向绑定</h3>     <input v-model.trim="msg" />     <div>        {{msg}}     </div>   </div>   <script>     const { createApp } = Vue     const app = createApp({       data() {          return{            msg: 'hello vue3'          }       }       // 正常写其它配置,methods,computed...      })    // 每一个vue应用从创建应用实例开始。    // 1. app是应用实例    // 可以在app上封装应用级别的组件,过滤器,指令    // app.component('SearchInput', SearchInputComponent)    // app.directive('focus', FocusDirective)    // app.use(LocalePlugin)    // 2. vm是根组件,当挂载整个应用时,它是渲染的起点。    // 定义在data中的属性,将通过vm暴露出来    const vm = app.mount("#app")    // vm.msg = '你好,vue3'</script> </body></html> 

注意事项:

  1. app 是应用实例, vm是根组件。

  2. app.mount()的作用是把vue应用实例挂到指定的dom容器中,它的返回值是整个应用的根组件,你可以通过vm.msg来访问数据,或者是修改数据来体现响应式的效果。

  3. createApp()这个函数的参数一个对象,它是根组件的配置项:

  • data必须要用函数返回值的写法,

  • 如果在配置项中设置了template,则渲染的内容会以template为准。

认识setup配置项

vue3中添加了setup配置项,用它来写组合式api,现在我们就来简单地认识一下它。​​​​​​​

<script src="https://unpkg.com/vue@next"></script><body> <div id="app">   <h3>setup</h3>   {{a}} - {{b}}   <button @click="f">f函数</button> </div> <script>   const { createApp } = Vue   const app = createApp({     data() {        return {          a: 1        }     },     setup() {      console.log('setup ....')      return {b: 2, f: function(){console.log('f')}}     },     created() {      console.log('created ....')      console.log(this.a)      console.log(this.b)      setTimeout(()=>this.b=100, 2000)      this.f()     }    })   app.mount("#app")</script></body>

要点:

  1. 这个钩子会在created之前执行

  2. 它的内部没有this

  3. 如果它的返回值是一个对象,则这个对象中的键值对最终会合并到created钩子中的this中去,从而在视图上也能访问相应的数据值(例如上面代码中的b和函数f)

  4. 不做特殊处理的情况下,它的数据不会有响应式的效果: 你修改了b的值,并不会引起视图的更新。

setup定义响应式数据(ref单值)

我们可以通过Vue.ref(基础数据)的方式得到一个具有响应式效果的数据,再通过setup来返回。​​​​​​​

 <script src="https://unpkg.com/vue@next"></script> <body>   <div id="app">     <h3>setup-ref响应式</h3>     <p>希望这里返回的b是响应式的</p>     a:{{a}} - b: {{b}}     <button @click="f">f</button>     <button @click="f1">f1</button>   </div>   <script>     const { createApp, ref } = Vue     const app = createApp({       data() {          return {            a: 1          }       },       setup() {        // 希望这里返回的b是响应式的:改了b的值,页面也会更新        // ref: 会对基础数据进行包装        // 它其实是用proxy代理了一个对象  `{ value: 0 }`        const b = ref(0)        const f1 = () => { b.value = 200}        return { b , f1  }       },       methods: {         f () {           // 这里不能写this.b.value           this.b = 100         }       }      })     app.mount("#app")</script>

如果希望在setup中返回具有响应式效果的数据,你可以用ref函数对数据进行处理。具体步骤:

  1. 在setup中返回一个ref()处理的数据

  2. 在视图中正常用插值{{b}}(不需要加.value)

  3. 如果要修改这个值,有两种方式:

    1) 在setup中暴露一个函数,直接去修改.value

    2) 在methods中定义一个方法,在此方法的内部通过this.XX=新值来修改

setup 定义响应式数据(reactive对象)

我们可以通过Vue.reactive(对象)的方式得到一个具有响应式效果的对象,再通过setup来返回。​​​​​​​

<script src="https://unpkg.com/vue@next"></script> <body>   <div id="app">     <h3>setup-reactive响应式</h3>     <p>希望这里返回的复合数据-obj是响应式的</p>    obj.b: {{obj.b}},  obj.arr:{{obj.arr}}     <button @click="f">f</button>     <button @click="f1">f1</button>     <button @click="f2">f2</button>   </div>   <script>   const { createApp, reactive } = Vue   const app = createApp({     data() {        return {        }     },     setup() {      // reactive: 会对对象进行包装      const obj = reactive({b: 1, arr: [1,2]})      const f1 = () => { obj.b = 200 }      const f2 = () => { obj.arr.push(3)}      return { obj, f1, f2  }     },     methods: {       f () {         this.obj.b = 100       }     }    })   app.mount("#app")</script></body>

步骤:

  1. 在setup中返回一个reactive()处理的对象obj

  2. 在视图中正常用插值,但是要加上obj.

  3. 如果要修改这个值,有两种方式:

    1) 在setup中暴露一个函数,直接去修改 

    2) 在methods中定义一个方法,在内部通过this.ojb.XX=新值 来修改

setup 返回响应式数据(reactive对象+toRefs)

上面的例子,我们需要用{{obj.b}}这种方式在视图中渲染数据,下面我们来优化一下,通过引入toRefs包装一个这个对象,然后再展开,就可以省略obj这个前缀了。​​​​​​​

<script src="https://unpkg.com/vue@next"></script> <body>   <div id="app">     <h3>setup-ref响应式</h3>     <p>希望这里返回的复合数据-obj是响应式的</p>    obj.b: {{b}},  obj.arr:{{arr}}     <button @click="f">f</button>     <button @click="f1">f1</button>     <button @click="f2">f2</button>   </div>   <script>    // vue3中提供一个概念:组合api     const { createApp, reactive, toRefs } = Vue     const app = createApp({       data() {          return {          }       },      //  步骤:      //  1. 在setup中返回一个reactive()处理的对象obj      //  2. 在视图中正常用插值,但是要加上obj.      //  3. 如果要修改这个值,有两种方式:      //   1) 在setup中暴露一个函数,直接去修改      //   2) 在methods中定义一个方法,在内部通过this.XX=新值来修改       setup() {        // reactive: 会对对象进行包装        // 它其实是用proxy代理了这个对象,只是第一个级别,所以不能直接解构        // 如果直接解构,就失去了响应式的特性了        // 这里再用toRefs来包装一下        const obj = reactive({b: 1, arr: [1,2]})        const f1 = () => { obj.b = 200}        const f2 = () => { obj.arr.push(3)}        return { ...toRefs(obj), f1, f2  }       },       methods: {         f () {           this.b = 100         }       }      })     app.mount("#app")</script></body>

核心代码是:return { ...toRefs(obj), f1, f2 }

setup 定义计算属性

<script src="https://unpkg.com/vue@next"></script> <body>   <div id="app">      <h3>setup-computed计算属性</h3>      obj.b: {{obj.b}}      <br>      <p>计算属性:2倍:{{doubleB}} </p>      <p>计算属性:0.5倍:{{halfB}} </p>      <p>计算属性:3倍:{{triangleB}} </p>      <button @click="obj.b+=1">原值+1</button>   </div>   <script>   const { createApp, reactive, computed } = Vue   const app = createApp({     data() {        return {}     },    //  步骤:    //  1. 在setup中通过computed来创建函数,    //  2. 导出     setup() {      // reactive: 会对对象进行包装      const obj = reactive({b: 1})      // 通过computed来创建计算属性      const doubleB = computed(()=>{        return 2*obj.b      })      const triangleB = computed(()=>{        return 3*obj.b      })      return { obj, doubleB, triangleB }     },     computed: {       halfB () {         return this.obj.b / 2       }     }    })   app.mount("#app")</script></body>

通过computed(回调)的方式来计算属性,然后在setup中返回即可。

在setup中写watch​​​​​​​

<script src="https://unpkg.com/vue@next"></script>

   <div id="app">      <h3>setup-watch</h3>      {{obj.b}}, {{a}}      <br>      <button @click="obj.b+=1">原值b+1</button>      <button @click="a+=1">原值a+1</button>   </div>   <script>   const { createApp, reactive, watch, ref } = Vue   const app = createApp({     data() {        return {        }     },     setup() {      // reactive: 会对对象进行包装      const obj = reactive({b: 1})      const a = ref(0)      // 通过watch来监听      watch(() => obj.b ,()=>{        console.log(`obj.b变化了`)      })      watch(a, ()=>{        console.log(`a变化了`)      })      return { obj, a }     }    })   app.mount("#app")</script>

在setup中写钩子函数​​​​​​​

<script src="https://unpkg.com/vue@next"></script><body> <div id="app">    <h3>setup-钩子函数</h3> </div> <script>   const { createApp,onMounted} = Vue   const app = createApp({     data() {        return {        }     },     setup() {      onMounted(()=>{ console.log('setup, mounted1')})      onMounted(()=>{ console.log('setup, mounted2')})     },     mounted () {       console.log('mounted')     }    })   app.mount("#app")</script>

上面的代码只演示了mounted,其它钩子类似。

小结

本文介绍了如何开始写vue3的第一个程序,学习用createApp来创建实例,用mount来挂装实例到dom上,在setup中通过 ref, reactive, toRef,computd,watch, onMounted等api的使用来对比实现vue2中效果,希望对你有帮助。

 

本篇只是一些语法介绍,在下一篇我会介绍setup的具体两个作用。

如果对您有帮助,以下动作建议至少选一个图片

Logo

前往低代码交流专区

更多推荐