美文网首页
vue3基础概念

vue3基础概念

作者: alicemum | 来源:发表于2021-04-26 19:13 被阅读0次

    官网

    https://v3.cn.vuejs.org/guide/introduction.html

    Vue3的特点

    由原来的Object.defineProperty 的getter 和 setter,改变成为了ES2015 Proxy 作为其观察机制。
    Proxy的优势:消除了以前存在的警告,使速度加倍,并节省了一半的内存开销。

    总体来说:1. 更快 2. 更小 3. 更容易维护 4. 更加友好 5. 更容易使用

    安装

    cnpm i vue @vue/cli -g
    

    初始化项目

    vue create myapp
    

    组合式API

    用组件的选项 (data、computed、methods、watch) 组织逻辑在大多数情况下都有效。然而,当我们的组件变得更大时,逻辑关注点的列表也会增长。这可能会导致组件难以阅读和理解,尤其是对于那些一开始就没有编写这些组件的人来说。
    如果我们能够将与同一个逻辑关注点相关的代码配置在一起,这样会更好。而这正是组合式 API 使我们能够做到的。

    setup()

    为了开始使用组合式 API,我们首先需要一个可以实际使用它的地方。在 Vue 组件中,我们将此位置称为 setup。

    defineComponent ()

    要让 TypeScript 正确推断 Vue 组件选项中的类型,需要使用 defineComponent 全局方法定义组件:

    import { defineComponent } from 'vue'
    
    const Component = defineComponent({
      // 已启用类型推断
    })
    

    ref: 定义响应数据的初始值

    一次只能定义一个,要用return返回
    模板

    <template>
      <div class="wrapper">
        home
        <div>{{num}}</div>
        <div>{{age}}</div>
        <div>{{arr}}</div>
        <div>{{obj}}</div>
      </div>
    </template>
    

    js

    <script>
    import {defineComponent,ref} from 'vue'
    export default defineComponent({
      name: 'home',
      props: {},
      components: {},
      setup(props,ctx){
        //ref只能一次定义一个数据,可以直接return ,模板中直接使用 {{num}}
        let num = ref(0)
        let age = ref(18)
        let arr = ref(['a','b'])
        let obj = ref({
          age: 1,
          name: 'jack'
        })
        return {
          num,
          age,
          arr,
          obj
        }
      }
    });
    </script>
    

    reactive: 一次定义多个响应式数据

    结合 toRefs()进行返回

    <template>
      <div class="wrapper">
        home
        <div>{{num}}</div>
        <div>{{age}}</div>
        <div>{{arr}}</div>
        <div>{{obj}}</div>
      </div>
    </template>
    
    <script>
    import {defineComponent,ref,reactive,toRefs} from 'vue'
    export default defineComponent({
      name: 'home',
      props: {},
      components: {},
      setup(props,ctx){
        //reactive可以定义多个数据 
        let data = reactive({
          num: 1,
          age: 100,
          arr: [1,2],
          obj: {
            name: 'jack',
            age: 18
          }
        })
        return {
          // ...data
          ...toRefs(data)
        }
      }
    });
    </script>
    <style lang="scss" scoped>
    </style>
    
    

    定义方法,更新响应式数据

    方法要return出去
    更新ref定义的数据: 数据.value=新值
    更新reactive定义的数据 : 对象.属性=新值

    <template>
      <div class="wrapper">
        home
        <hr>
        <div @click="clickNum(100)">num--{{num}}</div>
        <div @click="clickAge">age----{{age}}</div>
        <div @click="clickArr">{{arr}}</div>
        <div>{{obj}}</div>
      </div>
    </template>
    
    <script>
    import {defineComponent,ref,reactive,toRefs} from 'vue'
    export default defineComponent({
      name: 'home',
      props: {},
      components: {},
      setup(props,ctx){
        let num = ref(1)
        let data = reactive({
          age: 100,
          arr: [1,2],
          obj: {
            name: 'jack',
            age: 18
          }
        })
    
        //定义的方法也要return才能使用
        let clickNum = (val)=>{
          console.log('num新值',val);
          // ref定义的数据,访问时要加上value,因为数据是封装后的数据 
          console.log(num.value);
        }
    
        let clickAge = ()=>{
          // reactive定义的数据,直接用data访问属性名即可
          console.log(data.age)
        }
        return {
          ...data,
          num,
          clickNum,
          clickAge
          // ...toRefs(data)
        }
      }
    });
    </script>
    <style lang="scss" scoped>
    </style>
    
    

    计算属性的使用

    <template>
      <div class="wrapper">
        home
        <hr />
        <div>num1---{{ num1 }}</div>
        <div>num2---{{ num2 }}</div>
        <div>result---{{ result }}</div>
        <div><button @click="add">add</button></div>
      </div>
    </template>
    
    <script>
    import { defineComponent, ref,computed } from "vue";
    export default defineComponent({
      name: "home",
      props: {},
      components: {},
      setup(props, ctx) {
        let num1 = ref(20);
        let num2 = ref(30);
    
        // 计算属性API computed()
        let result = computed(()=>{
           return num1.value + num2.value
        })
    
        //num1,num2的值发生变化,result会重新计算
        let add = ()=>{
          num1.value++
          num2.value++
        }
        return {
          num1,
          num2,
          result,
          add
        };
      },
    });
    </script>
    <style lang="scss" scoped>
    </style>
    
    

    watch监听

    watch有2个参数, 第一个参数是监听的数据对象, 可以是单个变量、数组、函数;
    第二个参数是数据改变时的回调函数, 有2个参数, 第一个是改变后的数据, 第二个是改变前的数据;

    引入watch

    import { ref, defineComponent, watch } from "vue";
    

    在setup里面使用

    /*监听props*/
    watch(props,(newProps, oldProps) => {
         showModal.value = newProps.isOpened;
         editData.value = newProps.editData as IAdminUser;
     });
    
    

    使用Vuex

    vuex的五个属性和vue2中的定义相同
    引入组件中的方式发生变化

    <template>
      <div class="wrapper">
        home
        <hr />
        <!-- 不能像vue2一样直接用store.state.list访问数据 ,vue3没有this -->
        <!-- 但如果在setup中return出来store,是可以访问的 -->
        <!-- <div>store中的list---{{ store.state.list }}</div> -->
    
    
        <!-- <div>store中的list---{{ store.state.list }}</div> -->
        <div>store中的list---{{ list }}</div>
        
      </div>
    </template>
    
    
    <script>
    
    // vuex中定义state还和以前一样
    // 使用方式和以前不同
    import { defineComponent, ref,computed} from "vue";
    
    //引入useStore方法
    import {useStore} from 'vuex'
    
    export default defineComponent({
      name: "home",
      props: {},
      components: {},
      setup(props, ctx) {
        //获取vuex中的store对象
        let store = useStore()
    
        //---------------------------------------------------------
        // 一般用计算属性获取store中的数据
        let list = computed(()=>{
            return store.state.list
        })
        return {
          //  store
          list
        };
      },
    });
    </script>
    <style lang="scss" scoped>
    </style>
    
    

    路由跳转和路由传参

    路由配置和vue2相同
    在组件中引入方式不同

    <template>
      <div class="wrapper">
        home
        <hr />
    
        <button @click="goto">跳转至about</button>
        
      </div>
    </template>
    
    <script>
    import { defineComponent, ref,computed} from "vue";
    import {useRouter} from 'vue-router'
    export default defineComponent({
      name: "home",
      props: {},
      components: {},
      setup(props, ctx) {
        //获取全局路由对象
        let router = useRouter()
        // console.log(router);
        // console.log(router.options)
        const goto = ()=>{
          // router.push("/about")
    
          // router.push({
          //   path: '/about'
          // })
          let obj = {
                age: 18,
                name: 'xx'
              }
          //路由传参------query
          // 可以和path选项 或 路由的name属性结合 ,刷新后参数还在
          // router.push({
          //   path: '/about',
          //   query: {
          //     num: 10,
          //     color: 'red',
    
          //     //下方传递的方法,接收到是字符串 "[object object]"
          //     // obj: {
          //     //   age: 18,
          //     //   name: 'xx'
          //     // }
          //     obj: JSON.stringify(obj)
          //   }
          // })
    
          // 路由传参------params (不能用path+params,只能用路由name+params)
          // 刷新后参数不在
          router.push({
            name: 'About',
            params: {
              num: 10000
            }
          })
        }
        return {
          goto
        };
      },
    });
    </script>
    <style lang="scss" scoped>
    </style>
    

    接收路由参数

    <template>
      <div class="about">
        <h1>This is an about page</h1>
      </div>
    </template>
    <script>
    import { defineComponent} from "vue";
    import { useRoute} from "vue-router";
    export default defineComponent({
      name: 'about1',
      setup(props, ctx) {
        
        //获取当前路由信息
        let route = useRoute()
        console.log(route);
    
        // -----------------------query接收的全是字符串
        // console.log(route.query.num);
        // console.log(route.query.obj);
        // console.log(typeof route.query.obj);
        // --------------------------接收params的值
        console.log(route.params.num);
        
        return {
    
        } 
    
      },
    });
    </script>
    
    

    vue3中的生命周期

    <template>
      <div class="wrapper">
        home
        <hr />
    
        <button @click="goto">跳转至about</button>
        
      </div>
    </template>
    
    <script>
    import { defineComponent, onMounted , onUnmounted} from "vue";
    export default defineComponent({
      name: "home",
      setup(props, ctx) {
        
        // 常用的生命周期函数
        // 1. 初始化阶段 setup
        // 2. 挂载之后  onMounted()
    
        onMounted(()=>{
          console.log('ajax请求');
          console.log('dom操作');
          console.log('接收路由参数');
        })
        onUnmounted(()=>{
          console.log('清除定时器');
          console.log('清除闭包函数');
        })
        return {
        }
      },
    });
    </script>
    <style lang="scss" scoped>
    </style>
    
    

    子组件向父组件传值

    <template>
      <div class="wrapper">
        Child
        <div>接收父组件值:{{msg}}</div>
        <div><button @click="send">向父组件传值</button></div>
      </div>
    </template>
    
    <script>
    import { defineComponent} from "vue";
    export default defineComponent({
      name: "home",
    
      //------------------------特别注意
      // props的值不需要在setup中return,直接在模板中使用即可
      // 如果在setup中使用,需要用props.属性名来访问
      props: {
        msg: {
          type: String,
          required: true
        }
      },
      setup(props, ctx) {
        let send = ()=>{
          //用setup第二个参数上下文,来调用emit分发事件send
          ctx.emit("send",{
            num: 1,
            color: 'red'
          })
        }
        return {
          send
        }
      },
    });
    </script>
    <style lang="scss" scoped>
    </style>
    
    

    父组件接收子组件的值

    <template>
      <div class="wrapper">
        Home
        <hr />
        <Child :msg="msg" @send="getData"></Child>
      </div>
    </template>
    
    <script>
    import { defineComponent, ref } from "vue";
    import Child from "./Child";
    export default defineComponent({
      name: "home",
      components: {
        Child,
      },
      setup(props, ctx) {
        let msg = ref("父组件的值1");
        let getData = (data)=>{
          console.log('父组件接收到数据 ',data);
        }
        return {
          msg,
          getData
        };
      },
    });
    </script>
    <style lang="scss" scoped>
    </style>
    
    

    相关文章

      网友评论

          本文标题:vue3基础概念

          本文链接:https://www.haomeiwen.com/subject/ridlrltx.html