vue3基础梳理

项目安装

webpack方式

cnpm install -g @vue/cli

1.vue create 项目名 // 项目名不能有大写字母
2. 选择ts及vue3即可 // 选择ts就会加入ts

vite方式

全局安装 Vite
npm install -g create-vite-app

使用 Vite 创建 Vue3 项目
create-vite-app vue3-vite

Treeshaking特性

Tree shaking 是一种通过清除多余代码方式来优化项目打包体积的技术,专业术语叫 Dead code elimination
简单来讲,就是在保持代码运行结果不变的前提下,去除无用的代码。

Tree shaking是基于ES6模板语法(import与exports),主要是借助ES6模块的静态编译思想,在编译时就能确定模块的依赖关系,以及输入和输出的变量
Tree shaking无非就是做了两件事:
编译阶段利用ES6 Module判断哪些模块已经加载
判断那些模块和变量未被使用或者引用,进而删除对应代码

语法

setup

setup执行的时机
在beforeCreate之前执行(一次), 此时组件对象还没有创建
this是undefined, 不能通过this来访问data/computed/methods / props
其实所有的composition API相关回调函数中也都不可以
setup的参数
setup(props, context) / setup(props, {attrs, slots, emit})
props: 包含props配置声明且传入了的所有属性的对象 // 父子传值
attrs: 包含没有在props配置中声明的属性的对象, 相当于 this. a t t r s / / 父 子 传 值 s l o t s : 包 含 所 有 传 入 的 插 槽 内 容 的 对 象 , 相 当 于 t h i s . attrs // 父子传值 slots: 包含所有传入的插槽内容的对象, 相当于 this. attrs//slots:,this.slots // 插槽
emit: 用来分发自定义事件的函数, 相当于 this.$emit // 子传父的emit方法

ref

用法一 响应式数据

js 里需要.value
监听简单的数据(也可以监听复杂的对象,最终也会转为Proxy),进行响应式

  setup(){
    const num=ref(0)
    function  addNum() {
      num.value++
    }
    return {
      num,
      addNum
    }
  }

获取节点
<template>
  <div ref="myRef">获取单个DOM元素</div>
</template>

<script>
import { ref, onMounted } from 'vue';
export default {
  setup() {
    const myRef = ref(null);
    onMounted(() => {
      console.dir(myRef.value);
    });
    return {
      myRef
    };
  }
};
</script>

**// 或者**
 <input type="text" ref="inputRef">
setup() {
    const inputRef = ref<HTMLElement|null>(null)

    onMounted(() => {  // 自动获取焦点
      inputRef.value && inputRef.value.focus()
    })

    return {
      inputRef
    }
  },

ts下的处理
    const inputRef = ref<HTMLInputElement | null>(null);

    const getInputRef = () => {
      console.log((inputRef.value as HTMLInputElement).value);
    };

v-bind() 注入方式

const color = ref("red");

<style lang='less' scoped>
h1 {
  // 这种注入的方式只能使用ref
  color: v-bind(color);
  background-color: v-bind(bckColor);
}
</style>

toRefs

用于将reactive中的数据展开为响应式数据,可以直接在模板中访问使用

  const userdata=reactive({
      username:"小明"
})
 return {
      ...toRefs(userdata)
    };

// 使用
  <p>
    {{username}}
  </p>

toRef

可以使用reactive包裹的部分数据

  const userdata = reactive({
      username: "小明",
      age:18
    });

const refname=toRef(userdata,"username")

 return {
      refname
};

  <p>
    ref----{{refname}}
  </p>

isRef

用于判断值是不是ref

reactive

监听复杂的对象,可以深度监听

  setup() {
      // reactive 实现了深度监听
    const user: any= reactive({
      username: "小明",
      age: 18,
      likes: ["item-0", "item-1"],
    });
    function  changeUserdata() {
      user.username="小红",
      user.likes[0]="见哈哈哈",
      user.sex="男"
    }
    return {
      user,
      changeUserdata
    };
  },

hooks

在src下新建hooks文件夹,useUser.js文件(文件建立在哪都不重要,主要是函数式分离业务)

import {ref,reactive} from "vue"
function useUser(){
    const inputEle=ref("")
    const userdata = reactive({
      username: "小白",
      age: "18",
    })

    const getInputVal=()=>{
        console.log(inputEle.value.value)
    }
    return {
      userdata,
      inputEle,
      getInputVal
    }
}
export default useUser

在需要的组件导入使用
import  useUser  from "@/hook/useUser.js";
import { toRefs } from 'vue';
export default {
  setup() {
    const { userdata, inputEle, getInputVal } = useUser();
    return {
      ...toRefs(userdata),
      inputEle,
      getInputVal,
    };
  },
};

setup参数

provide/inject

深度传参

外层组件:
setup() {
    const childdata = ref("默认数据");
    const userdata=reactive({
      username:"李白白",
      age:18
    })
    // 定义一个修改provide数据的函数
    const updataUser=(val)=>{
        userdata.username=val
    }
    provide("userdata",userdata)
    provide("updataUser",updataUser)  // 将方法传递给组件

// 子组件
   const userdata1=inject("userdata")
   const updataUser=inject("updataUser")
   <button @click="updataUser('杜甫')">在子组件修改provide数据</button>

父子组件的传值(同v2)

1.可以使用v2的
2.使用v3的setup参数来修饰

  props: ["msg"],   // 必须要先接收一下
  setup(props) {
    const { userdata, inputEle, getInputVal } = useUser();
    const f_str = ref(props.msg + "-------子组件添加的数据");  // 可以对父组件传递过来的数据进行修饰
    return {
      ...toRefs(userdata),
      f_str,
      inputEle,
      getInputVal,
    };
  },
子传父
 setup(props, context) {
    const { userdata, inputEle, getInputVal } = useUser();
    const f_str = ref(props.msg + "-------子组件添加的数据"); // 可以对父组件传递过来的数据进行修饰

    const childdata = ref("");
    const handleF = () => {
      context.emit("getChilddata",childdata.value)
    };
    return {
      ...toRefs(userdata),
      childdata,
      f_str,
      inputEle,
      getInputVal,
      handleF,
    };
  },

4.v-for(同v2)

computed计算属性

    // 计算属性计算出的全部姓名
    const fullname = computed({
      get() {
        return user.firstname + "_" + user.lastname;
      },
      set(val: string) {
        const valarr = val.split("_");
        user.firstname = valarr[0];
        user.lastname = valarr[1];
      },
});


// 如果不对新的值修饰,可以采用下面的写法
    const newCount = computed(() => {
      return "新的count" + count1.value;
    });

watch 监听

 watch(
      user,	// ref
      () => {
        fullname1.value = user.firstname + "---" + user.lastname;
      },
      { immediate: true }
);

   watch(
      () => {
        // ref对象可以直接使用值,reactive的对象,需要写成函数形式
        return userdata.username;
      },
      () => {
        console.log("userdata.username发生了改变");
      },
      { immediate: true }   // 表示一开始就会执行上面的监听
    );


    // watch 的第二种用法,自带第一次的显示
    // watch监听获取到的全部姓名
    watchEffect(() => {
      fullname1.value = user.firstname + "---" + user.lastname;
    });

监听多个

就需要以数组的形式监听,watchEffect不能监听

  watch([
      ()=>state.name1
      ,
      ()=>state.name2
      ,
    ],([new1,new2],[old1,old2])=>{
      console.log("new1",new1)
      console.log("old1",old1)
      console.log("new2",new2)
      console.log("old2",old2)
    })

参考链接

生命周期

与 2.x 版本生命周期相对应的组合式 API
beforeCreate -> 使用 setup()

created -> 使用 setup()

beforeMount -> onBeforeMount

mounted -> onMounted

beforeUpdate -> onBeforeUpdate

updated -> onUpdated

beforeDestroy -> onBeforeUnmount

destroyed -> onUnmounted

errorCaptured -> onErrorCaptured

需要先从vue中导出才能使用 回调函数
onMounted(() => {
console.log(’–onMounted’)
})

路由周期 onBeforeRouteUpdate

// 切换路由时触发,第一次渲染不会触发
    onBeforeRouteUpdate(async (val) => {
      id.value = val.params.id;  // 获取得到路由的参数   /:id
      if (id.value >= 0 && id.value < 8) {
        let data1 = await getBooks(
          {
            num: 1,
            pageSize: 6,
          },
          id.value
        );
        data.booklist = data1.data;
      }
    });

路由

路由的基本结构

import { createRouter,createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about/:id',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  }
]
const router = createRouter({
  // history: createWebHashHistory(),   // hash模式,
  history:createWebHistory(),   // 模式可以直接修改,需要先导入
  routes
})
export default router


函数式跳转
import { useRouter } from "vue-router";   // 导入

    const router = useRouter();   // 不用return
    const goAbout = () => {
      router.push(`/about/123`)
    };

动态路由参数获取
import {useRoute} from "vue-router"   // 导入

    const route=useRoute()
方式一
/:id         动态路由
route.params.id               // 获取方式
方式二
router.push({path:/home”,query:{name:’hhh’}})   // 形如 /home?name=’hhh’
route.query.name    // 获取方式

路由的默认类名

在移动端做nav时使用

  <nav class="nav">
    <router-link to="/home">
      首页
    </router-link>
    <router-link to="/Category">
      分类
    </router-link>
    <router-link to="/shopCart">
      购物车
    </router-link>
    <router-link to="/profile">
      个人中心
    </router-link>
  </nav>

<style lang="scss">
a{
  color: #444;
  &.router-link-exact-active{
    color: yellowgreen;
  }
}
</style>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值