Vue - day05

35 阅读2分钟

一、组件通信方式

  • props 父子通信
  • $emit 子父通信(四步)
  • $refs 直接获取组件对象
  • provide/inject 依赖注入
  • 透传 Attribute
  • $root 获取根对象
  • $parent 获取父级对象
  • vuex 状态管理器

二、TransitionGroup的使用

<body>
    <div id="app">
      <button @click="handleAdd">按钮</button>
      <transition-group
        enter-active-class="animate__animated animate__rotateInDownLeft"
      >
        <div class="box" v-for="item in arr" :key="item">{{ item }}</div>
      </transition-group>
    </div>
</body>
<script>
    Vue.createApp({
      //创建vue应用
      data() {
        //数据包
        return {
          arr: [1, 2, 3, 4],
        };
      },
      methods: {
        handleAdd() {
          let n = this.arr.length + 1;
          this.arr.push(n);
        },
      },
    }).mount("#app");
</script>

三、动态组件与KeepAlive

<div id="app">
      <!-- 静态调用组件 -->
      <!-- <my-comp1></my-comp1>
      <my-comp2></my-comp2>
      <my-comp3></my-comp3> -->
      <!-- 动态组件 -->
      <button v-for="item in 3" @click="handleTab(item)">菜单{{item}}</button>
      <keep-alive>
        <component :is="compName"></component>
      </keep-alive>
</div>
<script>
    let app = Vue.createApp({
      //创建vue应用
      data() {
        //数据包
        return {
          compName: "my-comp1",
        };
      },
      methods: {
        handleTab(i) {
          this.compName = `my-comp${i}`;
        },
      },
    });
    app.component("my-comp1", {
      data() {
        return {
          bool: false,
        };
      },
      template: `<div :class="bool?'active':''" @click="bool=!bool">组件1</div>`,
    });
    app.component("my-comp2", {
      data() {
        return {
          bool: false,
        };
      },
      template: `<div :class="bool?'active':''" @click="bool=!bool">组件2</div>`,
    });
    app.component("my-comp3", {
      data() {
        return {
          bool: false,
        };
      },
      template: `<div :class="bool?'active':''" @click="bool=!bool">组件3</div>`,
    });
    app.mount("#app");
</script>

四、Teleport传送门

  • 传送门 Teleport 可以将组件 DOM 节点传送并渲染到 to 所指定的标签内
  • 应用场景:封装的遮罩弹窗效果,需要在最外层覆盖所有其他元素的时候,可以使用 Teleport
<div id="app">
      <div>
        第一层容器
        <div>
          第二层容器
          <my-comp></my-comp>
        </div>
      </div>
</div>
<script>
    let app = Vue.createApp({
      //创建vue应用
      data() {
        //数据包
        return {
          msg: "Hello Vue",
        };
      },
    });
    app.component("my-comp", {
      template: `<Teleport to="body">
          <div class="modal">这是一个组件</div>
        </Teleport>`,
    });
    app.mount("#app");
</script>

五、组合式API

<div id="app">
      <h1 @click="handleNum">{{num}}---{{count}}</h1>
</div>
<script>
    Vue.createApp({
      setup() {
        // 逻辑关注点1
        let num = 100; //非响应式数据
        let count = Vue.ref(233); //响应式数据
        const handleNum = () => {
          num++;
          count.value++;
          console.log(num);
        };
        // 此处return的内容才能在标签区域使用
        return {
          num,
          handleNum,
          count,
        };
      },
    }).mount("#app");
</script>

5.1 reactive实现响应式数据

<div id="app">
      <h1 @click="handleNum">{{state.num}}</h1>
      <button @click="handleAdd">新增学员</button>
      <div v-for="(item,index) in stu" :key="index">
        姓名:{{ item.name }} , 分数:{{item.score}}
      </div>
</div>
Vue.createApp({
      setup() {
        // 逻辑关注点1
        let state = Vue.reactive({ num: 100 });
        const handleNum = () => {
          state.num++;
          console.log(state.num);
        };

        // 逻辑关注点2
        let stu = Vue.ref([
          { name: "张三丰", score: 100 },
          { name: "三丰", score: 90 },
        ]);
        const handleAdd = () => {
          stu.value.push({
            name: "无忌",
            score: 80,
          });
        };
        return {
          state,
          handleNum,
          stu,
          handleAdd,
        };
      },
    }).mount("#app");
</script>

5.2 其他组合式API

<div id="app">
      <h1 @click="msg='你走'">{{msg}}</h1>
      <h2>{{reMsg}}</h2>
      <h2>{{reMsg}}</h2>
      <h2>{{reMsg}}</h2>
      <input type="text" ref="myInput" />
      <h1 ref="myH1">这是h1</h1>
</div>
<script>
    Vue.createApp({
      setup() {
        //setup内部无法使用this,也没必要使用this
        // 逻辑关注点1
        const msg = Vue.ref("Hello");
        // 使用computed,计算属性
        const reMsg = Vue.computed(() => {
          return msg.value.split("").reverse().join("");
        });
        
        console.log(msg, reMsg);

        // 生命周期,没有create系列钩子,多了一个会优先与所有其他生命周期执行的setup
        const myInput = Vue.ref(); //定义一个ref对象
        const myH1 = Vue.ref();
        Vue.onMounted(() => {
          myInput.value.focus();
        });

        // watch监听
        Vue.watch(msg, () => {
          console.log("检测到了msg的变化");
        });
        return {
          msg,
          reMsg,
          myInput,
          myH1,
        };
      },
    }).mount("#app");
</script>

六、选项式 API 对应的组合式 API

  • 所有的组合式 API 需要写在 setup 区域
  • data(){} 对标的 Vue.ref() Vue.reactive()
  • computed:{} 对标的 Vue.computed()
  • methods:{} 对标的 const handleXXX = ()=>{}
  • mounted(){} 对标的 onMounted(()=>{}) 取消了create系列生命周期
  • watch:{} 对标的组合式 watch('被检测的数据',()=>{回调函数})
  • directives:{'focus':{}} 挂载局部指令 const vFocus = {mounted(){}}
  • components:{} 对标的组合式 直接引入使用,免注册

七、ref() 与 reactive() 实现响应式

  • ref 处理响应式
    • ref() 可以将基本类型处理为响应式 let num = Vue.ref(100)
    • ref() 可以将对象类型处理为响应式
  • reactive
    • reactive() 只能将对象处理为响应式 let state = Vue.reactive({num:100})
  • 实现原理
    • ref() 是通过数据劫持(Object.defineProperty)实现响应式能力
    • reactive() 是通过数据代理(Proxy)实现的响应式能力
  • 操作手段的不同
    • ref() 的操作需要 xxx.value
    • reactive() 是直接操作

八、@vue/cli 脚手架

文档 Nodejs 版本 v16.18.1

8.1 安装

npm i @vue/cli -g   全局安装
vue -V    查看脚手架版本号

8.2 使用脚手架提供的命令创建 vue 项目

vue create 项目名称

8.3 按需选择项目依赖

8.4 启动项目进行预览开发

cd my-app       进入项目目录终端
npm run serve   启动项目

九、认识 Vue 工程化目录

  • node_modules 项目依赖文件夹
  • public 项目启动后所浏览的 html 页面,是以内部 index.html 为模板生成的
  • src 项目业务代码
    • assets 静态资源文件夹(img、css)
    • components 公共组件
    • App.vue 根组件
    • main.js 项目入口文件
  • .gitignore 可以让 git 忽略某些文件、文件夹
  • package.json 项目相关信息的记录文件(基本信息、命令、依赖)