一篇干货,轻松上手Vue.js 3.0

开发 前端
以下是最新的 vue3.x 一些新特性 - 希望对你上手Vue最新版有所帮助!

[[344419]]

以下是最新的 vue3.x 一些新特性 - 希望对你上手Vue最新版有所帮助!

1. 初始化项目 

  1. // ① npm i -g @vue/cli  
  2. // ② vue create my-project  
  3. // ③ npm install @vue/composition-api -S  
  4. // ④ main,js  
  5. import Vue from 'vue'  
  6. import VueCompositionApi from '@vue/composition-api'  
  7. Vue.use(VueCompositionApi) 

2. setup方法

setup是vue3.x中新的操作组件属性的方法,它是组件内部暴露出所有的属性和方法的统一API。

2.1 执行时机

setup的执行时机在:beforeCreate 之后 created之前 

  1. setup(props, ctx) {  
  2.     console.log('setup')  
  3.   },  
  4.   beforeCreate() {  
  5.     console.log('beforeCreate')  
  6.   },  
  7.   created() {  
  8.     console.log('created')  
  9.   }, 

2.2 接受props数据 

  1. <!-- 组件传值 -->  
  2. <com-setup p1="传值给 com-setup"/>  
  1. // 通过 setup 函数的第一个形参,接收 props 数据:  
  2. setup(props) {  
  3.   console.log(props)  
  4. },  
  5. // 在 props 中定义当前组件允许外界传递过来的参数名称:  
  6. props: {  
  7.     p1: String  
  8.  
  9. /*  
  10. {}  
  11. p1: "传值给 com-setup"  
  12. get p1: ƒ reactiveGetter()  
  13. set p1: ƒ reactiveSetter(newVal)  
  14. __proto__: Object  
  15. */ 

2.3 context

setup 函数的第二个形参是一个上下文对象,这个上下文对象中包含了一些有用的属性,这些属性在 vue 2.x 中需要通过 this 才能访问到,在 vue 3.x 中,它们的访问方式如下: 

  1. setup(props, ctx) {  
  2.     console.log(ctx)  
  3.     console.log(this) // undefined  
  4.   },  
  5. /*  
  6. attrs: Object  
  7. emit: ƒ ()  
  8. listeners: Object  
  9. parent: VueComponent  
  10. refs: Object  
  11. root: Vue  
  12. ...  
  13. */ 

注意:在 setup() 函数中无法访问到 this

3. reactive

reactive函数接收一个普通函数,返回一个响应式的数据对象。

reactive函数等价于 vue 2.x 中的 Vue.observable() 函数,vue 3.x 中提供了 reactive() 函数,用来创建响应式的数据对象,基本代码示例如下: 

  1. <template>  
  2.   <div>  
  3.     <!-- 在 template 中访问响应式数据 -->  
  4.     <p>当前的 count 值为:{{count}}</p>  
  5.     <button @click="count += 1">+1</button>  
  6.   </div>  
  7. </template>  
  8. <script>  
  9. import {reactive} from '@vue/composition-api'  
  10. export default {  
  11.   setup(props, ctx) {  
  12.     // 创建响应式数据对象,得到的 state 类似于 vue 2.x 中 data() 返回的响应式对象  
  13.     const state = reactive({ count: 0 })  
  14.     state.count += 1  
  15.     console.log(state)  
  16.      // setup 函数中将响应式数据对象 return 出去,供 template 使用  
  17.     return state  
  18.   }  
  19.  
  20. </script> 

4. ref

ref() 函数用来根据给定的值创建一个响应式的数据对象,ref() 函数调用的返回值是一个对象,这个对象上只包含一个 .value 属性: 

  1. <template>  
  2.   <div>  
  3.     <h3>02.ref.vue 文件</h3>  
  4.     <p>refCount:{{refCount}}</p>  
  5.     <button @click="refCount += 1">+1</button>  
  6.   </div>  
  7. </template>  
  8. <script>  
  9. import { ref } from '@vue/composition-api'  
  10. export default {  
  11.   setup() {  
  12.     // / 创建响应式数据对象 count,初始值为 0  
  13.     const refrefCount = ref(0)  
  14.     // 如果要访问 ref() 创建出来的响应式数据对象的值,必须通过 .value 属性才可以,只有在setup内部才需要 .value 属性  
  15.     console.log(refCount.value) // 输出 0  
  16.     // 让 refCount 的值 +1  
  17.         refCount.value++  
  18.     // 再次打印 refCount 的值  
  19.         console.log(refCount.value) // 输出 1  
  20.     return {  
  21.       refCount  
  22.     }  
  23.   }  
  24.  
  25. </script> 

4.1 在 reactive 对象中访问 ref 创建的响应式数据

当把 ref() 创建出来的响应式数据对象,挂载到 reactive() 上时,会自动把响应式数据对象展开为原始的值,不需通过 .value 就可以直接被访问,例如: 

  1. setup() {  
  2.   const refrefCount = ref(0)  
  3.   const state = reactive({refCount})  
  4.   console.log(state.refCount) // 输出 0  
  5.   state.refCount++ // 此处不需要通过 .value 就能直接访问原始值  
  6.   console.log(refCount) // 输出 1  
  7.   return {  
  8.     refCount  
  9.   }  

注意:新的 ref 会覆盖旧的 ref,示例代码如下: 

  1. setup() {  
  2.   // 创建 ref 并挂载到 reactive 中  
  3.   const c1 = ref(0);  
  4.   const state = reactive({ c1 });  
  5.   // 再次创建 ref,命名为 c2  
  6.   const c2 = ref(9);  
  7.   // 将 旧 ref c1 替换为 新 ref c2  
  8.   state.c1 = c2 
  9.   state.c1++; 
  10.   console.log(state.c1); // 输出 10  
  11.   console.log(c2.value); // 输出 10  
  12.   console.log(c1.value); // 输出 0  

5. isRef

isRef() 用来判断某个值是否为 ref() 创建出来的对象;应用场景:当需要展开某个可能为 ref() 创建出来的值的时候,例如: 

  1. import { ref, reactive, isRef } from "@vue/composition-api";  
  2. export default {  
  3.   setup() {  
  4.     const unwrapped = isRef(foo) ? foo.value : foo  
  5.   } 
  6. }; 

6. toRefs

toRefs() 函数可以将 reactive() 创建出来的响应式对象,转换为普通的对象,只不过,这个对象上的每个属性节点,都是 ref() 类型的响应式数据。 

  1. <template>  
  2.   <div>  
  3.     <h3>03.toRefs.vue文件</h3>  
  4.     <p>{{ count }} - {{ name }}</p>  
  5.     <button @click="count += 1">+1</button>  
  6.     <button @click="add">+1</button>  
  7.   </div>  
  8. </template>  
  9. <script>  
  10. import { reactive, toRefs } from "@vue/composition-api";  
  11. export default {  
  12.   setup() {  
  13.     // 响应式数据  
  14.     const state = reactive({ count: 0, name: "zs" });  
  15.     // 方法  
  16.     const add = () => {  
  17.       state.count += 1;  
  18.     };  
  19.     return {  
  20.       // 非响应式数据  
  21.       // ...state,  
  22.       // 响应式数据  
  23.       ...toRefs(state),  
  24.       add  
  25.     };  
  26.   }  
  27. };  
  28. </script> 

7. computed计算属性

7.1 只读的计算属性 

  1. <template>  
  2.   <div>  
  3.     <h3>04.computed.vue文件</h3>  
  4.     <p>refCount: {{refCount}}</p>  
  5.     <p>计算属性的值computedCount : {{computedCount}}</p>  
  6.     <button @click="refCount++">refCount + 1</button>  
  7.         <!-- 点击报错 -->  
  8.     <button @click="computedCount++">计算属性的值computedCount + 1</button>  
  9.   </div>  
  10. </template>  
  11. <script>  
  12. import { computed, ref } from '@vue/composition-api'  
  13. export default {  
  14.   setup() {  
  15.     const refrefCount = ref(1)  
  16.     // 只读  
  17.     let computedcomputedCount = computed(() => refCount.value + 1)  
  18.     console.log(computedCount)  
  19.     return {  
  20.       refCount,  
  21.       computedCount  
  22.     }  
  23.   }  
  24. };  
  25. </script> 

7.2 可读可写的计算属性 

  1. <template>  
  2.   <div>  
  3.     <h3>04.computed.vue文件</h3>  
  4.     <p>refCount: {{refCount}}</p>  
  5.     <p>计算属性的值computedCount : {{computedCount}}</p>  
  6.     <button @click="refCount++">refCount + 1</button>  
  7.   </div>  
  8. </template>  
  9. <script>  
  10. import { computed, ref } from '@vue/composition-api'  
  11. export default {  
  12.   setup() {  
  13.     const refrefCount = ref(1)  
  14.     // 可读可写  
  15.     let computedcomputedCount = computed({  
  16.       // 取值函数  
  17.       get: () => refCount.value + 1,  
  18.       // 赋值函数  
  19.       set: val => {  
  20.         refCountrefCount.value = refCount.value -5  
  21.       } 
  22.      })  
  23.     console.log(computedCount.value)  
  24.     // 为计算属性赋值的操作,会触发 set 函数  
  25.     computedCount.value = 10  
  26.     console.log(computedCount.value)  
  27.     // 触发 set 函数后,count 的值会被更新  
  28.     console.log(refCount.value)  
  29.     return {  
  30.       refCount, 
  31.        computedCount  
  32.     }  
  33.   }  
  34. };  
  35. </script> 

8. watch

watch() 函数用来监视某些数据项的变化,从而触发某些特定的操作,使用之前需要按需导入: 

  1. import { watch } from '@vue/composition-api' 

8.1 基本用法 

  1. <template>  
  2.   <div>  
  3.     <h3>05.watch.vue文件</h3>  
  4.     <p>refCount: {{refCount}}</p>  
  5.   </div>  
  6. </template>  
  7. <script>  
  8. import { watch, ref } from '@vue/composition-api'  
  9. export default {  
  10.   setup() {  
  11.     const refrefCount = ref(100)  
  12.     // 定义 watch,只要 count 值变化,就会触发 watch 回调  
  13.     // 组件在第一次创建的时候执行一次 watch  
  14.     watch(() => console.log(refCount.value), { lazy: false})  
  15.     setInterval(() => {  
  16.       refCount.value += 2  
  17.     }, 5000)  
  18.     return {  
  19.       refCount  
  20.     }  
  21.   }  
  22. };  
  23. </script> 

8.2 监视数据源

监视 reactive 类型的数据源: 

  1. <template>  
  2.   <div>  
  3.     <h3>05.watch.vue文件</h3>  
  4.     <p>count: {{count}}</p> // 不是响应式数据  
  5.   </div>  
  6. </template>  
  7. <script>  
  8. import { watch, ref, reactive } from '@vue/composition-api'  
  9. export default {  
  10.   setup() {  
  11.     const state = reactive({count: 100})  
  12.     watch(  
  13.       // 监听count  
  14.       () => state.count,  
  15.       // 如果变换 执行以下函数  
  16.       (newVal, oldVala) => {  
  17.         console.log(newVal, oldVala)  
  18.       },  
  19.       { lazy: true }  
  20.     )  
  21.     setInterval(() => {  
  22.       state.count += 2  
  23.     }, 5000)  
  24.     return state  
  25.   }  
  26. };  
  27. </script> 

监视 ref 类型的数据源: 

  1. export default {  
  2.   setup() {  
  3.     // 定义数据源  
  4.     let count = ref(0);  
  5.     // 指定要监视的数据源  
  6.     watch(count, (count, prevCount) => {  
  7.       console.log(count, prevCount)  
  8.     })  
  9.     setInterval(() => {  
  10.       count.value += 2  
  11.     }, 2000)  
  12.     console.log(count.value)  
  13.     return {  
  14.       count  
  15.     }  
  16.   }  
  17. }; 

8.3 监听多个数据源

监视 reactive 类型的数据源: 

  1. export default {  
  2.   setup() {  
  3.     const state = reactive({count: 100, name: 'houfei'})  
  4.     watch(  
  5.       // 监听count name  
  6.       [() => state.count, () => state.name],  
  7.       // 如果变换 执行以下函数  
  8.       ([newCount, newName], [oldCount, oldName]) => {  
  9.         console.log(newCount, oldCount)  
  10.         console.log(newName, oldName)  
  11.       },  
  12.       { lazy: true} // 在 watch 被创建的时候,不执行回调函数中的代码  
  13.     )  
  14.     setTimeout(() => {  
  15.       state.count += 2  
  16.       state.name = 'qweqweewq'  
  17.     }, 3000)  
  18.     return state  
  19.   }  
  20. }; 

监视 ref 类型的数据源: 

  1. export default {  
  2.   setup() {  
  3.     // 定义数据源  
  4.     const count = ref(10)  
  5.     const name = ref('zs')  
  6.     // 指定要监视的数据源  
  7.     watch(  
  8.       [count, name],  
  9.       ([newCount, newName], [oldCount, oldName]) => {  
  10.         console.log(newCount, oldCount)  
  11.         console.log(newName, oldName)  
  12.       },  
  13.       { lazy: true} 
  14.     )  
  15.     setInterval(() => {  
  16.       count.value += 2 
  17.     }, 2000)  
  18.     console.log(count.value)  
  19.     return {  
  20.       count  
  21.     }  
  22.   }  
  23. }; 

8.4 清除监视

在 setup() 函数内创建的 watch 监视,会在当前组件被销毁的时候自动停止。如果想要明确地停止某个监视,可以调用 watch() 函数的返回值即可,语法如下: 

  1. <script>  
  2. // 创建监视,并得到 停止函数  
  3. const stop = watch(() => {  
  4.   /* ... */  
  5. })  
  6. // 调用停止函数,清除对应的监视  
  7. stop()  
  1. <template>  
  2.   <div>  
  3.     <!-- <h3>05.watch.vue文件</h3> -->  
  4.     <p>count: {{ count }}</p>  
  5.     <button @click="stopWatch">停止监听</button>  
  6.   </div>  
  7. </template>  
  8. <script>  
  9. import { watch, ref, reactive } from "@vue/composition-api";  
  10. export default {  
  11.   setup() {  
  12.     // 定义数据源  
  13.     const count = ref(10)  
  14.     const name = ref('zs')  
  15.     // 指定要监视的数据源  
  16.     const stop = watch 
  17.       [count, name],  
  18.       ([newCount, newName], [oldCount, oldName]) => {  
  19.         console.log(newCount, oldCount)  
  20.         console.log(newName, oldName)  
  21.       },  
  22.       { lazy: true}  
  23.     )  
  24.     setInterval(() => {  
  25.       count.value += 2 
  26.        name.value = 'houyue'  
  27.     }, 2000)  
  28.     // 停止监视  
  29.     const stopWatch = () => {  
  30.       console.log("停止监视,但是数据还在变化")  
  31.       stop()  
  32.     }  
  33.     console.log(count.value)  
  34.     return {  
  35.       stop,  
  36.       count,  
  37.       stopWatch  
  38.     }  
  39.   }  
  40. };  
  41. </script> 

8.5 在watch中清除无效的异步任务

有时候,当被 watch 监视的值发生变化时,或 watch 本身被 stop 之后,我们期望能够清除那些无效的异步任务,此时,watch 回调函数中提供了一个 cleanup registrator function 来执行清除的工作。这个清除函数会在如下情况下被调用:

watch 被重复执行了

watch 被强制 stop 了

Template 中的代码示例如下: 

  1. <template>  
  2.   <div>  
  3.     <!-- <h3>05.watch.vue文件</h3> -->  
  4.     <input type="text" v-model="keywords" /> 
  5.      <p>keywords:--- {{ keywords }}</p>  
  6.   </div>  
  7. </template> 

Script 中的代码示例如下: 

  1. <script>  
  2. import { watch, ref, reactive } from "@vue/composition-api";  
  3. export default {  
  4.   setup() { 
  5.     // 定义响应式数据 keywords  
  6.     const keywords = ref("");  
  7.     // 异步任务:打印用户输入的关键词  
  8.     const asyncPrint = val => {  
  9.       // 延时 1 秒后打印  
  10.       return setTimeout(() => {  
  11.         console.log(val);  
  12.       }, 1000);  
  13.     };  
  14.     // 定义 watch 监听  
  15.     watch(  
  16.       keywords,  
  17.       (keywords, prevKeywords, onCleanup) => {  
  18.         // 执行异步任务,并得到关闭异步任务的 timerId  
  19.         const timerId = asyncPrint(keywords);  
  20.         // 如果 watch 监听被重复执行了,则会先清除上次未完成的异步任务  
  21.         onCleanup(() => clearTimeout(timerId));  
  22.       },  
  23.       // watch 刚被创建的时候不执行  
  24.       { lazy: true }  
  25.     );  
  26.     // 把 template 中需要的数据 return 出去  
  27.     return {  
  28.       keywords  
  29.     };  
  30.   }  
  31. };  
  32. </script> 

9. provide & inject 组件传值

provide() 和 inject() 可以实现嵌套组件之间的数据传递。这两个函数只能在 setup() 函数中使用。父级组件中使用 provide() 函数向下传递数据;子级组件中使用 inject() 获取上层传递过来的数据。

9.1 共享普通数据

app.vue 根组件: 

  1. <template>  
  2.   <div id="app">  
  3.     <h1>父组件</h1>  
  4.     <button @click="color = 'blue'">蓝色</button>  
  5.     <button @click="color = 'red'">红色</button>  
  6.     <button @click="color = 'yellow'">黄色</button>  
  7.     <son></son>  
  8.     <son></son>  
  9.   </div>  
  10. </template>  
  11. <script>  
  12. import { ref, provide } from '@vue/composition-api'  
  13. import Son from './components/06.son.vue'  
  14. export default {  
  15.   name: 'app',  
  16.   components: {  
  17.     'son': Son  
  18.   },  
  19.   setup() {  
  20.     const color = ref('green')  
  21.     provide('themecolor', color)  
  22.     return {  
  23.      color  
  24.     }  
  25.   }  
  26.  
  27. </script> 

06.son.vue son 组件: 

  1. <template>  
  2.   <div>  
  3.     <h3 :style="{color: color}">son 组件</h3>  
  4.     <grandson></grandson>  
  5.   </div>  
  6. </template>  
  7. <script>  
  8. import { inject } from '@vue/composition-api'  
  9. import Grandson from './07.grandson.vue'  
  10. export default {  
  11.     components: {  
  12.     'grandson': Grandson  
  13.   },  
  14.   setup() {  
  15.     const color = inject('themecolor')  
  16.     return {  
  17.      color  
  18.     }  
  19.   }  
  20.  
  21. </script> 

07.grandson.vue son 组件: 

  1. <template>  
  2.   <div>  
  3.     <h5 :style="{color: color}">grandson 组件</h5>  
  4.   </div>  
  5. </template>  
  6. <script>  
  7. import { inject } from '@vue/composition-api'  
  8. export default {  
  9.   setup() {  
  10.     const color = inject('themecolor')  
  11.     return {  
  12.       color  
  13.     }  
  14.   }  
  15.  
  16. </script> 

9.2 共享ref响应式数据

app.vue 根组件: 

  1. <template>  
  2.   <div id="app">  
  3.     <h1>父组件</h1>  
  4.     <son></son>  
  5.   </div>  
  6. </template>  
  7. <script>  
  8. import { provide } from '@vue/composition-api'  
  9. import Son from './components/06.son.vue'  
  10. export default {  
  11.   name: 'app',  
  12.   components: {  
  13.     'son': Son  
  14.   },  
  15.   setup() {  
  16.     provide('themecolor', 'red')  
  17.   }  
  18.  
  19. </script> 

06.son.vue son 组件: 

  1. <template>  
  2.   <div>  
  3.     <h3 :style="{color: color}">son 组件</h3>  
  4.     <grandson></grandson>  
  5.   </div>  
  6. </template>  
  7. <script>  
  8. import { inject } from '@vue/composition-api'  
  9. import Grandson from './07.grandson.vue'  
  10. export default {  
  11.     components: {  
  12.     'grandson': Grandson  
  13.   },  
  14.   setup() {  
  15.     const color = inject('themecolor')  
  16.     return {  
  17.       color 
  18.     }  
  19.   }  
  20.  
  21. </script> 

07.grandson.vue son 组件: 

  1. template>  
  2.   <div>  
  3.     <h5 :style="{color: color}">grandson 组件</h5>  
  4.   </div>  
  5. </template>  
  6. <script>  
  7. import { inject } from '@vue/composition-api'  
  8. export default {  
  9.   setup() { 
  10.      const color = inject('themecolor')  
  11.     return {  
  12.       color  
  13.     }  
  14.   }  
  15.  
  16. </script> 

10. 节点的引用 template ref

10.1 dom的引用 

  1. <template>  
  2.   <div>  
  3.     <h3 ref="h3Ref">TemplateRefOne</h3>  
  4.   </div>  
  5. </template>  
  6. <script>  
  7. import { ref, onMounted } from '@vue/composition-api'  
  8. export default {  
  9.   setup() {  
  10.     // 创建一个 DOM 引用  
  11.     const h3Ref = ref(null)  
  12.     // 在 DOM 首次加载完毕之后,才能获取到元素的引用  
  13.     onMounted(() => {  
  14.       // 为 dom 元素设置字体颜色  
  15.       // h3Ref.value 是原生DOM对象  
  16.       h3Ref.value.style.color = 'red'  
  17.     })  
  18.     // 把创建的引用 return 出去  
  19.     return {  
  20.       h3Ref  
  21.     }  
  22.   }  
  23.  
  24. </script> 

10.2 组件的引用

App父组件: 

  1. <template>  
  2.   <div id="app">  
  3.     <h1>父组件</h1>  
  4.     <button @click="showComRef">展示子组件的值</button>  
  5.     <son ref="comRef"></son>  
  6.   </div>  
  7. </template>  
  8. <script>  
  9. import Son from './components/06.son.vue'  
  10. export default {  
  11.   name: 'app',  
  12.   components: {  
  13.     'son': Son  
  14.   },  
  15.   setup() {  
  16.     const comRef = ref(null)   
  17.     const showComRef = () => {  
  18.       console.log(comRef)  
  19.       console.log('str1的值是' + comRef.value.str1)  
  20.       comRef.value.setStr1()  
  21.     }  
  22.     return {  
  23.       comRef,  
  24.       showComRef  
  25.     }  
  26.   }  
  27.  
  28. </script> 

06.son.vue子组件: 

  1. <template>  
  2.   <div>  
  3.     <h3 :style="{color: color}">son 组件</h3>  
  4.     <p>{{str1}}</p>  
  5.   </div>  
  6. </template>  
  7. <script>  
  8. import { ref } from '@vue/composition-api'  
  9. export default {  
  10.   setup() {  
  11.     const str1 = ref('这是一个子组件!!')  
  12.     const setStr1 = () => {  
  13.       str1.value = '被赋值了'  
  14.     }  
  15.     return {  
  16.       str1,  
  17.       setStr1  
  18.     }  
  19.   }  
  20.  
  21. </script> 

11 nextTick 

  1. <template>  
  2.   <div>  
  3.     <h3>09.nextTick 组件</h3>  
  4.     <p>学习 $nextTick</p>  
  5.     <button v-if="isShowInput === false" @click="showInput">展示文本框</button>  
  6.     <input type="text" v-else ref="ipt">  
  7.   </div>  
  8. </template>  
  9. <script>  
  10. export default {  
  11.   data() {  
  12.     return {  
  13.       isShowInput: false  
  14.     }  
  15.   },  
  16.   methods: {  
  17.     showInput() {  
  18.       this.isShowInput = !this.isShowInput  
  19.       // console.log(this.$refs) 
  20.       this.$nextTick(() => {  
  21.         this.$refs.ipt.focus()  
  22.       })  
  23.     }  
  24.   }  
  25.  
  26. </script>  

 

责任编辑:庞桂玉 来源: 前端教程
相关推荐

2016-11-23 19:01:31

vue

2020-09-16 06:12:30

Vue.js 3.0Suspense组件前端

2017-07-31 15:14:07

Glide项目缩放

2022-02-24 07:56:42

开发Viteesbuild

2020-10-22 09:37:20

Vue开发优化

2020-09-29 08:26:17

Vue3中新增的API

2021-02-24 08:32:45

Web Compone前端Web 应用

2018-04-04 10:32:13

前端JavascriptVue.js

2017-07-04 17:55:37

Vue.js插件开发

2016-11-04 19:58:39

vue.js

2022-03-03 22:00:19

Hooks函数组件React

2021-11-24 08:51:32

Node.js监听函数

2022-01-19 22:18:56

Vue.jsVue SPA开发

2024-05-13 08:04:26

Vue.jsWeb应用程序

2017-07-11 18:00:21

vue.js数据组件

2017-07-20 11:18:22

Vue.jsMVVMMVC

2020-09-07 14:40:20

Vue.js构建工具前端

2021-01-22 11:47:27

Vue.js响应式代码

2017-07-14 10:10:08

Vue.jsMixin

2016-11-01 19:10:33

vue.js前端前端框架
点赞
收藏

51CTO技术栈公众号