23.5.11 Vue入门学习

1. 前言

        在使用Go重构了仿牛客社区的后端的登录模块以后,就想要学习一下前端,把相应的功能在前端实现,因为没有现成的前端素材,重构前端的工作量太大了,所以决定不重构仿牛客社区了,准备在这个登录模块的基础上,写一个其他项目,下面记录一下今天学的Vue相关的内容。

2. Vue官方教程学习

        首先,vue是通过将.vue文件解析成js文件,然后渲染成DOM元素,来在浏览器上访问的;

        这个部分有13个demo:

2.1 绑定数据

        这个demo绑定了名为message的对象,在template中通过双花括号来访问变量的内容(对象)

<template>
  <!--使用双大括号{{  }}将相应的对象绑定到格式中-->
  <h1>{{ message }}}</h1>
</template>

<script>
export default {
  name: '1_绑定数据',

  data() {
    return {
      message: "message"
    }
  }
}
</script>

<style scoped>

</style>

 

2.2 绑定属性 

        在这个demo中通过v-bind:class绑定了h1的class为titcleClass来改变字体颜色为红色,同时v-bind可以简写为:class。

<template>
<!--  使用:class(v-bind:class)绑定h1的class为titleClass,绑定属性不需要{{}}-->
  <h1 :class="titleClass">Make Me Red</h1>
</template>

<script>
export default {
  name: "2_绑定属性",
  data() {
    return {
      titleClass: 'title'
    }
  }
}
</script>

<style scoped>
  .title {
    color: red;
  }
</style>

 

2.3 绑定事件

        这个demo中,通过@click(或者v-on:click)绑定了按钮的事件increment函数来让count自增。

<template>
<!--  使用@(v-on:click)绑定按钮对应的函数increment-->
  <button @click="increment">count is:{{ count }}</button>
</template>

<script>
export default {
  name: "3_绑定事件",
  data() {
    return {
      count: 0,
      // 定义自增的函数
      increment() {
        this.count++
      }
    }
  }
}
</script>

<style scoped>

</style>

 

2.4 绑定表单

        在这个demo中,通过value="text" @input="input"或者直接使用v-model="text"来获取并绑定表单中的数据到text。

<template>
<!--  使用v-model绑定表单的输入值-->
  <input v-model="text" placeholder="Type here">
  <input :value="text" @input="input">
  <p>{{ text }}</p>
</template>

<script>
export default {
  name: "4_绑定表单",
  data() {
    return {
      text: "",
      input(e) {
        this.text = e
      }
    }
  }
}
</script>

<style scoped>

</style>

 

2.5 v-if的使用

        这个demo使用v-if来控制元素的显示,通过函数toggle来反转awesome的值,控制元素的隐藏与显示。

<script>
export default {
  data() {
    return {
      awesome: true
    }
  },
  methods: {
    toggle() {
      this.awesome = !this.awesome
    }
  }
}
</script>

<template>
  <button @click="toggle">toggle</button>
  <h1 v-if="awesome">Vue is awesome!</h1>
  <h1 v-else>Oh no 😢</h1>
</template>

 

 

2.6 遍历数组元素

        在这个demo中,通过数组的push函数和filter函数分别实现了添加数组元素和过滤数组元素,实现类似软删除的效果,其中removeTodo(e)函数通过遍历数组找到输入的元素,输出除了该元素的所有元素,addTodo()函数则通过push新的元素到数组中来实现元素列表的添加。

<script>
// 给每个 todo 对象一个唯一的 id
let id = 0

export default {
  name: "6_遍历数组元素",
  data() {
    return {
      newTodo: '',
      todos: [
        { id: id++, text: 'Learn HTML' },
        { id: id++, text: 'Learn JavaScript' },
        { id: id++, text: 'Learn Vue' }
      ]
    }
  },
  methods: {
    addTodo() {
      // 添加一个元素
      this.todos.push({ id: id++, text: this.newTodo })
      this.newTodo = ''
    },
    removeTodo(todo) {
      // 过滤器,过滤掉选定的元素,生成一个不包含该元素的数组
      this.todos = this.todos.filter((t) => t !== todo)
    }
  }
}
</script>

<template>
  <form @submit.prevent="addTodo">
    <input v-model="newTodo">
    <button>Add Todo</button>
  </form>
  <ul>
    <li v-for="todo in todos" :key="todo.id">
      {{ todo.text }}
      <button @click="removeTodo(todo)">X</button>
    </li>
  </ul>
</template>

 

 

2.7 计算组件的使用

        在这个demo中,通过使用computed组件来实现选择是否过滤特定的元素,即是否显示checkbox为true的内容或是显示全部内容,可选择使用if-else或是三元表达式实现。

<script>
let id = 0

export default {
  data() {
    return {
      newTodo: '',
      hideCompleted: false,
      todos: [
        { id: id++, text: 'Learn HTML', done: true },
        { id: id++, text: 'Learn JavaScript', done: true },
        { id: id++, text: 'Learn Vue', done: false }
      ]
    }
  },
  computed: {
    filteredTodos() {
      // return this.hideCompleted ? this.todos.filter((t) => !t.done) : this.todos
      if (this.hideCompleted === true) {
        return this.todos.filter((t) => !t.done)
      } else {
        return this.todos
      }
    }
  },
  methods: {
    addTodo() {
      this.todos.push({ id: id++, text: this.newTodo, done: false })
      this.newTodo = ''
    },
    removeTodo(todo) {
      this.todos = this.todos.filter((t) => t !== todo)
    }
  }
}
</script>

<template>
  <form @submit.prevent="addTodo">
    <input v-model="newTodo">
    <button>Add Todo</button>
  </form>
  <ul>
    <li v-for="todo in filteredTodos" :key="todo.id">
      <input type="checkbox" v-model="todo.done">
      <span :class="{ done: todo.done }">{{ todo.text }}</span>
      <button @click="removeTodo(todo)">X</button>
    </li>
  </ul>
  <button @click="hideCompleted = !hideCompleted">
    {{ hideCompleted ? 'Show all' : 'Hide completed' }}
  </button>
</template>

<style>
.done {
  text-decoration: line-through;
}
</style>

 

 

2.8 生命周期和模板引用

        在这个demo中,通过mounted组件编辑refs来修改p和h1元素的内容,并且将相应的修改挂载到DOM自动执行。

<script>
export default {
  mounted() {
    this.$refs.p.textContent = 'mounted!'
    this.$refs.h1.textContent = 'I am H1!'
  }
}
</script>

<template>
  <p ref="p">hello</p>
  <h1 ref="h1">
    www
  </h1>
</template>

 

2.9 侦听器

        在这个demo中,定义了一个异步函数fetchData来从特定的url获取数据并通过mounted挂载到DOM上展示,然后通过一个button来增加Id,同时设置了一个侦听组件Watch来侦听todoId的变化,一旦变化就自动执行fetchData来刷新数据。

<script>
export default {
  data() {
    return {
      todoId: 1,
      todoData: null
    }
  },
  methods: {
    // 异步获取
    async fetchData() {
      this.todoData = null
      // 从这个网站通过改变不同的Id获取数据
      const res = await fetch(
          `https://jsonplaceholder.typicode.com/todos/${this.todoId}`
      )
      // await等待把数据转换成json格式
      this.todoData = await res.json()
    }
  },
  // 通过mounted挂载函数到dom
  mounted() {
    this.fetchData()
  },
  watch: {
    todoId() {
      this.fetchData()
    }
  }
}
</script>

<template>
  <p>Todo id: {{ todoId }}</p>
  <button @click="todoId++">Fetch next todo</button>
  <p v-if="!todoData">Loading...</p>
  <pre v-else>{{ todoData }}</pre>
</template>

 

 

2.10 组件的注册与导入

        在这个demo中,通过import组件ChileComp,然后在template中调用来显示ChildComp中的template中的内容。

<script>
import ChildComp from './ChildComp.vue'
export default {
  components: {
    ChildComp,
  }
}
</script>

<template>
  <!-- render child component -->
  <ChildComp></ChildComp>
</template>

ChildComp.vue:

<template>
  <h2>A Child Component!</h2>
</template>

 

2.11 props组件

        在这个demo中,通过在ChildComp.vue中定义props组件来获取父组件中的数据,重载msg中的内容。

<script>
import ChildComp from './ChildComp.vue'
export default {
  components: {
    ChildComp
  },
  data() {
    return {
      greeting: 'Hello from parent'
    }
    props: {
      msg: ""
    }
  }
}
</script>

<template>
<!--  重载子组件中的msg为父组件的greeting-->
  <ChildComp :msg="greeting" />
</template>

ChildComp.vue:

<script>
export default {
  props: {
    msg: String
  }
}
</script>

<template>
  <h2>{{ msg || 'No props passed yet' }}</h2>
</template>

 

2.12 emits组件

        在这个demo中,通过在在ChildComp中定义emits自定义了事件response来向父组件传递数据,将childMsg的值修改为ChildComp的msg的值。

<script>
import ChildComp from './ChildComp.vue'

export default {
  components: {
    ChildComp
  },
  data() {
    return {
      childMsg: 'No child msg yet'
    }
  }
}
</script>

<template>
<!--  自定义事件response重载父组件的childMsg为子组件的msg-->
  <ChildComp @response="(msg) => childMsg = msg" />
  <p>{{ childMsg }}</p>
</template>

ChildComp:

<script>
export default {
  emits: ['response'],
  created() {
    this.$emit('response', 'hello from child')
  }
}
</script>

<template>
  <h2>Child component</h2>
</template>

 

2.13 slot的使用

        在这个demo中,通过在ChildComp的模板中使用slot来接收父组件的数据。

<script>
import ChildComp from './ChildComp.vue'

export default {
  components: {
    ChildComp
  },
  data() {
    return {
      msg: 'from parent'
    }
  }
}
</script>

<template>
  <ChildComp>Message: {{ msg }}</ChildComp>
</template>

ChildComp:

<template>
  <slot>Fallback content</slot>
</template>

 

3. 实战

        在这个部分,我从使用vue渲染了后端接口传递的用户列表数据,并且显示在了页面上。

3.1 UserList.vue的编写

        这个组件中,定义了数据user[] 数组、异步的fetchdata()函数来从后端接口获取定义为entity类型的json数据,并使用mounted()自动挂载到了DOM中,使用按钮调用fetchData()来刷新用户列表,并且使用v-for循环输出用户名为li元素(挂载后访问页面就会自己执行this.fetchData(),此时下面的刷新就要替换为获取数据更为恰当了)。

<script>
export default {
  inject: ['$backendApi'],

  data() {
    return {
      users: [],
    };
  },
  methods: {
    async fetchData() {
      try {
        const response = await this.$backendApi.get('/community/user/getUserList'); // 发送 GET 请求到后端服务器
        this.users = response.data.entity.data; // 更新组件的用户数据
      } catch (error) {
        console.error(error); // 输出错误消息到控制台
      }
    },
  },
  // 挂载后访问页面就会自己执行this.fetchData(),此时下面的刷新就要替换为获取数据更为恰当了
  mounted() {
    this.fetchData()
  },
};
</script>
<template>
  <div>
    <h1>User List</h1>
    <button @click="fetchData">刷新</button>
    <ul>
      <li v-for="user in users" :key="user.id">{{ user.username }}</li>
    </ul>
  </div>
</template>

3.2  App.vue的编写

        import上面的UserList.vue,在template中调用。

<template>
  <img alt="Vue logo" src="./assets/logo.png">
<!--  <HelloWorld msg="Welcome to Your Vue.js App"/>-->
  <UserList></UserList>
</template>

<script>
// import HelloWorld from './components/HelloWorld.vue'
import UserList from "@/components/UserList.vue";

export default {
  name: 'App',
  components: {
    // HelloWorld,
    UserList
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

3.3 main.js的编写

        这里定义了后端运行的端口,并且自动挂载app到DOM。

import { createApp } from 'vue';
import App from './App.vue';
import axios from 'axios';

const app = createApp(App);

// 通过 provide() 将 $backendApi 全局属性注入到应用实例中
app.provide('$backendApi', axios.create({
    baseURL: 'http://localhost:8080', // 设置后端服务器地址和端口号
}));

app.mount('#app');

3.3 效果:

 

添加一个数据,然后点击刷新:

后端的控制台:

4. 总结 

        今天初步学习了vue框架的基本操作,还初步将前后端结合了一下,体会到了前后端分离的美妙感觉!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值