最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • vue3.0新特性

    正文概述 掘金(可可爱爱没脑袋)   2020-11-27   496

    vue3.0新特性 动机:组合式api更好的逻辑复用与代码组织。

    安装

    // 确认脚手架在4.5以上,否则就更新脚手架
    1. npm install -g @vue/cli@next
    
    2. vue create projectname
    
    3. 选择vue3版本
    

    vue3.0新特性

    1. setup函数

    setup函数是vue3中所有api的入口。

    export default {
        name: 'XXX',
        components: {},
        ...
        
        setup(props, context) {
        	...
          console.log("context:", context)
        }
    		...
    }
    

    2. ref()和reactive()

    ref()和reactive()定义变量的时候使用。

    • ref()

      定义单值。

      import { ref } from 'vue'
      export default {
        setup() {
          const name = ref('刘亦菲')
        }
      }
      

      获取单值。

      ...
        const getName = name.value// 敲黑板: ref是一个对象,这里需要XX.value的形式
      ...
      
    • reactive()

      定义响应式对象。

      import { reactive } from 'vue'
      export default {
        setup() {
          const userInfo = reactive({
          	name: '刘亦菲'
          })
        }
      }
      

    3. toRefs()

    解构响应式对象数据。主要使用在reactive()上,把一个响应式对象转换成普通对象,该普通对象的每个 property 都是一个 ref ,和响应式对象 property 一一对应。

    <template>
        <h1>解构响应式对象数据</h1>
        <p>name: {{username}}</p>
        <p>age: {{age}}</p>
    </template>
    <script>
      import { reactive, toRefs } from 'vue'
      export default {
        setup() {
          const userInfo = reactive({
          	name: '刘亦菲',
            age: 18
          })
          const userInfoRef = toRefs(userInfo)
          return {
          	...userInfoRef
          }
        }
      }
    </script>
    

    4.v-model多个值变化

    • 给子组件传输多个变量。
      <!-- 父组件 -->
      <my-child v-model:username="username" v-model:age="age"></my-child>
      
      
      <!-- 子组件 -->
      <template>
        <div class="page">
          <label>姓名:<input type="text" :value="username" @input="inputNameChange"></label>
          <label>年龄:<input type="text" :value="age" @input="inputAgeChange"></label>
        </div>
      </template
      <script>
        export default {
          props: ['username','age'],
          setup(props,context) {
            const inputNameChange = (e) => {
              context.emit('update:username', e.target.value)
            }
            const inputAgeChange= (e) => {
              context.emit('update:age', e.target.value)
            }
            return {
              inputNameChange,
              inputAgeChange
            }
          }
        }
      </script>
    

    5.computed计算属性

    const data = reactive({
     age: 20
    });
    
    // 函数式
    const fakeAge = computed(() => {
     return data.age - 10
    });
    
    return { fakeAge };
    

    6.watch变化

    // 侦听一个
    const state = reactive({ count: 0 })
    watch(
      () => state.count,
      (count, prevCount) => {
        ...
      }
    )
    
    // 直接侦听一个ref
    const count = ref(0)
    watch(count, (count, prevCount) => {
     ...
    })
    

    7.watchEffect

    立即执行传入的一个函数,并响应式追踪其依赖,并在其依赖变更时重新运行该函数。

    import { watchEffect } from 'vue'
    export default {
      setup({
        ...
        watchEffect('传入一个函数') // 立即执行
      })
    }
    

    demo

    import { toRefs, reactive, watchEffect } from 'vue'
    export default {
     setup () {
       const data = reactive({
         count: 1,
         total: 999
       })
       const refData = toRefs(data)
    
       /**
       	1. 传入的函数立即执行
       	2. 当watchEffect传入的函数依赖值有变化时,会再次触发watchEffect函数
       */
       watchEffect(() => {
         console.log(data.count)
       })
       setTimeout(() => {
         data.count = data.count + 2 // 【会】触发watchEffect函数
         data.total = data.total + 2 // 【不会】触发watchEffect函数
       }, 2000)
       return {
         ...refData
       }
     }
    }
    
    • 停止侦听
    1. 显示停止
    import { toRefs, reactive, watchEffect } from 'vue'
    export default {
      setup () {
        ...
        const watchFuntion = watchEffect(() => { // 1. 侦听函数
          console.log(data.count)
        })
        
        setInterval(() => {
          data.count = data.count + 1000
        }, 2000)
        
        // 5秒后执行
        setTimeout(() => {
          console.log('停止侦听')
          watchFuntion() // 2. 调用时,停止侦听
        }, 5000)
        return {
          ...refData
        }
      }
    }
    
    1. 隐式停止:当watchEffect在组件的setup()函数或生命周期钩子被调用时,侦听器会被链接到该组件的生命周期,并在组件卸载时自动停止。(比如:页面关闭的时候,或者切换页面的时候)

    8.keyCode不生效

    <!-- 不生效 -->
    <input type="text" @keyup.13="doSomething">
    
    <!-- 生效 -->
    <input type="text" @keyup.enter="doSomething">
    

    9.片段

    在 Vue 3 中,组件现在正式支持多根节点组件,即片段!

    <!-- Layout.vue -->
    <template>
    <!-- div包裹起来消除警告 -->
      <div>
        <header>...</header>
        <main>...</main>
        <footer>...</footer>
      </div>
    </template>
    

    3.x

    <!-- Layout.vue -->
    <template>
      <header>...</header>
      <main>...</main>
      <footer>...</footer>
    </template>
    

    10.readonly

    传入一个对象,该对象不可以修改,返回一个原始对象的只读代理(深层代理)。

    // readonly('传入一个对象或者一个ref') // 因为ref返回的是一个对象
    import { reactive, toRefs, readonly } from 'vue'
    export default {
      setup () {
        const data = reactive({
          count: 0
        })
        const copy = readonly(data)
        const refData = toRefs(data)
        data.count = 111
        copy.count = 222 // 报错:Cannot assign to 'count' because it is a read-only 
        console.log('copy:', copy.count)
        console.log('data.count:', data.count)
        return {
          ...refData
        }
      }
    }
    

    11.vue-router区别

    • 安装
    npm install vue-router@next // 4.0+
    
    • 使用路由
    // 引用
    import { createRouter, createWebHashHistory } from  'vue-router'
    
    //创建
    const router = createRouter({
      routes: [
      	...
      ]
    })
      
    // use使用
     createApp(App).use(router)
    
    • 常用API
    import {useRoute, useRouter} from 'vue-router'
    const route = useRoute(); // 相当于 vue2 中的this.$route
    const router = useRouter(); // 相当于 vue2 中的this.$router
    

    12.teleport 瞬间移动

    • 使用
    <teleport to="将当前组件放置在哪个容器内,接受参数字符串"></teleport>
    
    • 举例
    
    <!-- 弹框组件 -->
    <template>
    	<!-- 重点1: 放置在id为model的容器内 -->
      <teleport to="#model">
        <div class="model" v-if="isOpen">
          <h1>我是弹框内容</h1>
          <button @click="onCloseModel">关闭弹框</button>
        </div>
      </teleport>
    </template>
    
    <script lang='ts'>
    export default {
      name: 'model',
      props: {
        isOpen: Boolean
      },
      //  重点2:emits中使用的方法名称必须是‘a-b’横杠格式
      emits: {
        'close-model': null
      },
      setup (props, context) {
        const onCloseModel = () => {
          context.emit('close-model')
        }
        return {
          onCloseModel
        }
      }
    }
    </script>
    
    <!-- 使用被teleport包裹的组件 -->
    <template>
    <!-- 重点3:使用组件 -->
      <model :isOpen="isOpenModel" @close-model="closeModel"></model>
      <button @click="openModelClick">打开弹框</button>
      <div class="page">
        x:{{x}} y:{{y}}
      </div>
    </template>
    
    <script lang='ts'>
    import { ref, toRefs, reactive, onMounted, onUnmounted } from 'vue'
    import model from '../components/Model.vue'
    export default {
      name: 'Index',
      components: {
        model
      },
      setup () {
    
        // 弹框 (teleport学习)
        const isOpenModel = ref(false)
        const openModelClick = () => {
          isOpenModel.value = true
        }
        const closeModel = () => {
          isOpenModel.value = false
        }
        return {
          isOpenModel,
          openModelClick,
          closeModel
        }
      }
    }
    </script>
    
    <style scoped>
    </style>
    
    
    <!-- app.vue -->
    <template>
    	<div id="#app"></div>
    	<div id="#model">
        <!--重点4:  model组件会渲染到这里 -->
      </div>
    </template>
    

    起源地下载网 » vue3.0新特性

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元