• vue3.0的新特性的使用与总结


    1、实例化的方式

    // Vue2.0
    new Vue({
     el: "#app",
     router,
     store,
     render: h => h(App)
    })
    

      

    // Vue3.x
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <!-- <script src="../../packages/vue/dist/vue.global.js"></script>
       -->
       <script src="../vue-next/packages/vue/dist/vue.global.js"></script>
    </head>
    
    <body>
      <div id="app"></div>
      <script>
        const {
          createApp,
          reactive,
          computed,
        } = Vue
        const MyComponent = {
          template: `
                    <button @click="click">
                    {{ state.message }}
                    </button>
                `,
          setup() {
            const state = reactive({
              message: 'Hello Vue 3!!'
            })
            function click() {
              state.message = state.message.split('').reverse().join('')
            }
            return {
              state,
              click
            }
          }
        }
        createApp(MyComponent).mount('#app')
    
      </script>
    </body>
    
    </html>

    2、Composition API

    这个是变化最大的地方

    在Vue2.x中是在data中写数据,在methods中写方法,通过this调用

    在Vue3.x中,所有的逻辑代码都是在setup方法中实现,包括data,watch,computed,methods,hooks,不再有this

    Vue3.x中的setup方法在组件生命周期内只执行一次,不会重复执行

    (1)、reactive其实就是Vue3.0中的响应式

    如以下所写

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <!-- <script src="../../packages/vue/dist/vue.global.js"></script>
       -->
       <script src="../vue-next/packages/vue/dist/vue.global.js"></script>
    </head>
    
    <body>
      <div id="app"></div>
      <script>
        const {
          createApp,
          reactive,
          computed,
        } = Vue
        const MyComponent = {
          template: `
                    <button @click="click">
                    {{ state.message }}
                    </button>
                `,
          setup() {
            //  -------reactive响应式-----------
            const state = reactive({
              message: 'Hello Vue 3!!'
            })
            function click() {
              state.message = state.message.split('').reverse().join('')
            }
            return {
              state,
              click
            }
          }
        }
        createApp(MyComponent).mount('#app')
    
      </script>
    </body>
    
    </html>

    在上面那段的click里面添加

    console.log('state',state)
    在控制台则会打印如下:

    (2) ref和toRefs

       其中,ref可以用来初始化一个数,并给这个数初始值,如果你学过React,你就会发现,它其实和useState有些类似

       用toRefs展开保证了state中的数据不失去响应式

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <!-- <script src="../../packages/vue/dist/vue.global.js"></script>
       -->
      <script src="../../vue-next/packages/vue/dist/vue.global.js"></script>
    </head>
    
    <body>
      <div id="app"></div>
      <script>
        const {
          createApp,
          reactive,
          computed,
          ref,
          toRefs
        } = Vue
        const MyComponent = {
          template: `
                    <div><button @click="addCount">点击增加, 数量{{count}}
                   <span>{{count}}</span>
                    </button></div>
                    <div><button @click="addNum">点击减少</button>
                    <span>{{num}}</span></div>
    
                `,
            setup() {
            // reactive响应式
            const state = reactive({
              count: 0
            })
            // ref的使用
            const num = ref(0)
            function addCount() {
              state.count++
            }
            function addNum() {
              num.value++
            }
            return {
              ...toRefs(state),
              num,
              addNum,
              addCount
            }
          }
        }
        createApp(MyComponent).mount('#app')
    
      </script>
    </body>
    
    </html>

    (3)、computed

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <!-- <script src="../../packages/vue/dist/vue.global.js"></script>
       -->
      <script src="../../vue-next/packages/vue/dist/vue.global.js"></script>
    </head>
    
    <body>
      <div id="app"></div>
      <script>
        const {
          createApp,
          reactive,
          computed,
          ref,
          toRefs,
        } = Vue
        const MyComponent = {
          template: `
                    <div><button @click="addCount">点击增加, 数量{{count}}
                   <span>{{count}}</span>
                    </button></div>
                    <div><button @click="addNum">点击减少</button>
                    <span>{{num}}</span></div>
    
                `,
          setup() {
            // reactive响应式
            const state = reactive({
              count: 0,
              // ------
              double: computed(() => {
                return state.count * 2
              })
            })
            // ref的使用
            const num = ref(2)
            function addCount() {
              state.count++
            }
            function addNum() {
              num.value++
            }
            // ---only getter
            const totalCount = computed(() => {
              state.count +  2
            })
    
            // getter & setter
            const doubleCount = computed({
              get() {
                return state.count * 2
              },
              set (newVal) {
                state.count = newVal / 2
             
              }
            })
            return {
              ...toRefs(state),
              // ...state,
              num,
              addNum,
              addCount,
              totalCount,
              // doubleCount
            }
          }
        }
        createApp(MyComponent).mount('#app')
    
      </script>
    </body>
    
    </html>

     (4)、watch & watchEffect

       在Vue2.x中用watch来监听属性

       在Vue3.x中用watch支持监听单个属性,也支持监听多个属性

       在Vue3.x中watchEffect方法会返回一个方法,用于停止监听

       watch跟watchEffect不同的地方在于,watchEffect注册后会立即调用,而watch默认不会,除非

    显示指定immediate=true,而且watchEffect可以停止监听

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <!-- <script src="../../packages/vue/dist/vue.global.js"></script>
       -->
      <script src="../../vue-next/packages/vue/dist/vue.global.js"></script>
    </head>
    
    <body>
      <div id="app"></div>
      <script>
        const {
          createApp,
          reactive,
          computed,
          ref,
          toRefs,
          watch,
           watchEffect 
        } = Vue
        const MyComponent = {
          template: `
                    <div><button @click="addCount">点击增加, 数量{{count}}
                   <span>{{count}}</span>
                    </button></div>
                    <div><button @click="addNum">点击减少</button>
                    <span>{{num}}</span></div>
                    <div>333{{totalCount}}</div>
                    <input type="text" v-model="totalCount" />
                `,
          setup() {
            // reactive响应式
            const state = reactive({
              count: 0,
              // ------
              double: computed(() => {
                return state.count * 2
              }),
              midObj: {
                innerObj: {
                  size: 0
                }
              }
            })
            // ref的使用
            const num = ref(2)
            function addCount() {
              state.count++
            }
            function addNum() {
              num.value++
            }
            // ---only getter
            const totalCount = computed(() => {
              return state.count + 2
            })
            // 监听单个属性
            watch(() => totalCount.value,(newVal, oldVal) => {
              console.log(`count + num = ${newVal}`)
            })
    
            // 监听多个属性
            watch([num, () => totalCount.value], ([numVal, totalVal],[oldNumVal, OldTotalVal]) => {
              console.log(`num is ${numVal}, count + num = ${totalVal}`)
            })
            // 副作用,会立即执行
            let callTimes = 0
            const stopEffect = watchEffect(() => {
              console.log('watchEffect is called!')
              const div = document.createElement('div')
              div.textContent = `totalCount is ${totalCount.value}`
              document.body.appendChild(div)
              // 调用5次后,取消fetch监听
              callTimes++
              if(callTimes >= 5)  stopEffect()
            })
            return {
              ...toRefs(state),
              num,
              addNum,
              addCount,
              totalCount,
            }
          }     
        }  
        createApp(MyComponent).mount('#app')
      </script>
    </body>
    </html>

       运行上图的代码且点击按钮五次后,页面的效果如下:

    3、生命周期钩子

    在Vue2.x中生命周期钩子与data,methods同级

    在Vue3.x中,需要先导入钩子,并且在setup方法中注册钩子回调,并且钩子命名也跟React保持一样了

    Vue3.x中移除了Vue2.x中的beforeCreate和created钩子,通过setup代替,如下图:

     与React Hooks相比:

    基于函数的组合式 API 提供了与 React Hooks 同等级别的逻辑组合能力,
    但是它们还是有很大不同:组合式 API 的 setup() 函数只会被调用一次,这意味着使用 Vue 组合式 API 的代码会是:
    不需要顾虑调用顺序,也可以用在条件语句中;
    不会在每次渲染时重复执行,以降低垃圾回收的压力;
    不存在内联处理函数导致子组件永远更新的问题,也不需要 useCallback;
    不存在忘记记录依赖的问题,也不需要“useEffect”和“useMemo”并传入依赖数组以捕获过时的变量。Vue 的自动依赖跟踪可以确保侦听器和计算值总是准确无误。
    我们感谢 React Hooks 的创造性,它也是本提案的主要灵感来源,然而上面提到的一些问题存在于其设计之中,且我们发现 Vue 的响应式模型恰好为解决这些问题提供了一种思路。

     新增的生命周期钩子:

    onRenderTracked
    onRenderTriggered
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <!-- <script src="../../packages/vue/dist/vue.global.js"></script>-->
      <script src="../../vue-next/packages/vue/dist/vue.global.js"></script>
    </head>
    
    <body>
      <div id="app"></div>
      <script>
        const {
          createApp,
          reactive,
          ref,
          toRefs,
          watch,
          watchEffect,
          computed,
          // 生命周期钩子
          onBeforeMount,
          onMounted,
        } = Vue
        const MyComponent = {
          template: `
                    <div><button @click="addCount">点击增加, 数量{{count}}
                    <span>{{count}}</span>
                    </button></div>
                    <div><button @click="addNum">点击减少</button>
                    <span>{{num}}</span></div>
                    <div>333{{totalCount}}</div>
                    <input type="text" v-model="totalCount" />
                `,
          setup() {
            // 生命周期钩子
            onBeforeMount(() => {
              console.log('component is onBeforeMount')
            })
            onMounted(() => {
              console.log('component is onMounted')
            })
            // reactive响应式
            const state = reactive({
              count: 0,
              // ------
              double: computed(() => {
                return state.count * 2
              }),
              midObj: {
                innerObj: {
                  size: 0
                }
              }
            })
            // ref的使用
            const num = ref(2)
            function addCount() {
              state.count++
            }
            function addNum() {
              num.value++
            }
            // ---only getter
            const totalCount = computed(() => {
              return state.count + 2
            })
            // 监听单个属性
            watch(() => totalCount.value, (newVal, oldVal) => {
              console.log(`count + num = ${newVal}`)
            })
    
            // 监听多个属性
            watch([num, () => totalCount.value], ([numVal, totalVal], [oldNumVal, OldTotalVal]) => {
              console.log(`num is ${numVal}, count + num = ${totalVal}`)
            })
            // 副作用,会立即执行
            let callTimes = 0
            const stopEffect = watchEffect(() => {
              console.log('watchEffect is called!')
              const div = document.createElement('div')
              div.textContent = `totalCount is ${totalCount.value}`
              document.body.appendChild(div)
              // 调用5次后,取消fetch监听
              callTimes++
              if (callTimes >= 5) stopEffect()
            })
            return {
              ...toRefs(state),
              num,
              addNum,
              addCount,
              totalCount,
            }
          }
        }
        createApp(MyComponent).mount('#app')
      </script>
    </body>
    
    </html>

    4、Fragment

    Vue2.x 的vue template只允许有一个根节点

    Vue3.x的vue template支持多个节点

    5、Teleport

    teleport 参照React中的portal,可以将元素渲染在父节点以外的其他地方,

    6、Suspense

    通常在发生异步操作或者在异步的组件中使用

    后面还会继续补充添加代码

    参考:https://juejin.cn/post/6867123074148335624#heading-9

      

     

  • 相关阅读:
    云计算和大数据时代网络技术揭秘(十九)万兆革命 (完)
    云计算和大数据时代网络技术揭秘(十八)刀片服务器的网络
    云计算和大数据时代网络技术揭秘(十七)VOQ机制
    云计算和大数据时代网络技术揭秘(十六)数据中心布线
    云计算和大数据时代网络技术揭秘(十五)大数据网络
    云计算和大数据时代网络技术揭秘(十四)虚拟桌面
    云计算和大数据时代网络技术揭秘(十三)VXLAN
    python3练习100题——037
    python3练习100题——036
    python3练习100题——035
  • 原文地址:https://www.cnblogs.com/Roxxane/p/14445356.html
Copyright © 2020-2023  润新知