我的springboot学习【10】

        今天正式进入Vue3的学习。既然网上没有好的教程那就干脆看官网学习吧,虽然我真的很喜欢看教程,毕竟那是有老师上课的感觉。废话不多说开始学习。

        Vue.js设计的初衷就是能被渐进式采用,可以通过四种方式写进项目:①在页面上以CDN方式导入②下载js文件③使用npm进行安装④使用官方CLI进行构建。

        CDN不能应用于大型的生产环境,先跳过。

        先暂停一下,我突然想到那个阿里巴巴编码规范了,先打开IDEA,setting的plugins下直接搜索alibaba就能找到java编码规范插件,下载就行,以后敲右键就可以进行代码规范查验了。安装后记得重启IDEA就行了。

        好了回到正题,通过以下地址先拿一下Vue的源码:

https://unpkg.com/vue@next

        然后全选复制,我新建了一个VueStudy的springboot项目,然后在static包下建js包,然后新建一个vue3.js文件,将代码粘贴进去,可见一共有15929行,如果以后有机会的话还是要看一看这个源码的。现在可以写一个简单的Vue应用了。

        templates下新建index.html,引入js文件。写一个最简单的页面,别问为啥这么写,我也不知道,以后就会了。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../static/js/vue3.js"></script>
</head>
<body>
    <div id="counter">
        <p>{{num}}</p>
        <p>{{uname}}</p>
    </div>
    <script>
        const Counter = {  //data是配置对象的方法
            data: function (){
                return{
                    num: 0,
                    uname: "lxc"
                }
            }
        }
        Vue.createApp(Counter).mount('#counter')   //创建对象,将配置对象传入,mount可以理解为挂载
    </script>
</body>
</html>

        运行起来查看一下效果,可见初次尝试成功。

        这里我想看一下这个创建对象到底返回了个什么,所以用一个let对象接受一下然后在前端看一下吧。

        let test = Vue.createApp(Counter).mount('#counter')
        console.log(test)

         可以看到还是返回了不少东西的,这里的函数理论上都可以使用才对。

         这里现在IDEA下载插件吧,首先是在下图的地方激活ESLint。

        接下来直接下载vue.js插件。这两个是Vue开发很有帮助的插件。

        然后再回到主线上,别忘了重启IDEA。这边通过官方文件可以看到,可以通过如下命令创建Vue项目,我来试一下这个。

npm init vue@latest

        这一路下来一顿yes就行了,可以看到新建了不少好东西。

         每个Vue应用都是通过createApp函数创建一个新的应用实例,需要导入createApp方法:

import { createApp } from 'vue'

const app = createApp({
  /* 根组件选项 */
})

         传入createApp的对象是一个组件,每个应用都需要一个根组件和其他若干子组件。之前说过,应用实例必须调用mount()方法后才能渲染出来,该方法会接收一个容器参数,在整个应用配置和资源注册完成后被调用,会被渲染在容器元素里,但容器元素自己不会被视为应用的一部分。

        在未采用构建流程的情况下时可以直接使用根组件模板:

<div id="app">
  <button @click="count++">{{ count }}</button>
</div>
import { createApp } from 'vue'

const app = createApp({
  data() {
    return {
      count: 0
    }
  }
})

app.mount('#app')

        这边我在打开自动生成的APP.vue时,发现第二行的vue-router爆红,这里根据IDEA的提示npm命令操作一下即可解决。Vue是一种声明式渲染,极大提高开发效率,即先声明好然后直接调用渲染。

        我用着这东西这个别扭,,,新建一个空项目吧,取名叫VueTest,然后构建一个新的Vue项目vue-begin02。这次安装我发现了问题,原来是上次我没装到底,我说的怎么没有自动启动呢。这次显示是这样的:

        访问一下试试。。。

        这次感觉好多了哈哈哈。 

        咋说呢我属是可怜,找了一些教程根本看不明白都。。。我还是按照官网一步一步来吧,这里我也不想分天啥的了,这篇直到学完Vue3就一直写吧。。。

        重来!新建一个空项目,命名为VueStudy01,在终端操作,这次我全选No。这里官网解释了,生成的项目中的示例组件是使用组合式API 和 <script setup> 编写的,并非选项式API。运行下面的命令将应用发布到生产环境。

npm run build

        随着学习的深入,会将代码切割为单独的js文件,需要通过http协议为HTML提供服务,需要先安装node.js,然后在HTML所在的文件夹下运行npx serve。进入边动手边学的教程。

        首先看到的是声明式渲染。通过扩展于标准 HTML 的模板语法,我们可以根据 JavaScript 的状态来描述 HTML 应该是什么样子的。当状态改变时,HTML 会自动更新。即响应式布局。data组件应该是一个返回对象的函数,data下的message属性可以通过双大括号的形式进行渲染,而且双大括号内的内容可以使用任何有效的js表达式。下面是这个题的答案:

<script>
export default {
  // 组件选项
  // 此处声明一些响应式状态
  data(){
    return {
      message: 'Make me dynamic!'
    }
  }
}
</script>

<template>
  <h1>{{message}}</h1>
</template>

        下面是Attribute绑定。双大括号(即mustache语法)只能用于文本插值,绑定动态值就需要使用v-bind:指令。为了代码简洁,可以简写为:。本题答案如下:

<script>
export default {
  data() {
    return {
      titleClass: 'title'
    }
  }
}
</script>

<template>
  <h1 v-bind:class="titleClass">Make me red</h1> <!-- 此处添加一个动态 class 绑定 -->
</template>

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

        下面是事件监听。可以使用v-on:指令监听DOM事件,可以简写为@。答案如下:

<script>
export default {
  data() {
    return {
      count: 0
    }
  },
  methods: {
    increment(){
      this.count++;
    }
  }
}
</script>

<template>
  <!-- 使此按钮生效 -->
  <button v-on:click="increment">count is: {{ count }}</button>
</template>

        接下来是表单绑定。可以同时使用v-bind和v-on在表单的元素上进行双向绑定,为了简化这一过程,提供了一种v-model指令,会将绑定的值与input的值相绑定,这样就不用使用事件处理函数了,还可以用于各种不同类型的输入。

<script>
export default {
  data() {
    return {
      text: '123'
    }
  }
}
</script>

<template>
  <input v-model="text" placeholder="Type here">
  <p>{{ text }}</p>
</template>

        下面来条件渲染。听到条件两个字肯定if没跑了,果然。这里的指令是v-if,即只有在这里是真即Truthy时才会执行,否则过滤。那都有if了,v-elsev-else-if自然也少不了。 

<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>

        列表渲染,使用v-for命令来渲染基于源数组的列表。这部分有点恶心了开始,首先要有一个局部变量这里命名为todo,他给出了一个例子先看一下:

<ul>
  <li v-for="todo in todos" :key="todo.id">
    {{ todo.text }}
  </li>
</ul>

        这里todo对象的id就类似于数据库表的主键,是唯一标识的那种,并将它作为特殊的key绑定到每个<li>上。这里可以用this.todos.push(newTodo)调用变更方法,可以通过this.todos = this.todos.filter()使用新数组代替原数组。理论上v-for是可以与v-if一起使用的,但是不推荐,因为两者的优先级不明显。在同一个节点时if的条件更高,因此无法读取到for中的局部变量,为了解决上述问题可以在外面新建一层template即可。

        为了让Vue更方便的跟踪每个节点,可以给一个唯一的标识符key。当使用template的v-for时,应将key放在template容器上,注意这里的key是通过v-bind绑定的。官方推荐在这里给每个都绑定一个key值。至于操作数组的几个函数都蛮简单的。这题的答案如下:

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

export default {
  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>

        下一个单元是计算属性,是跟上一单元连起来的,通过v-model将done属性绑定,添加了切换的功能,即:

<li v-for="todo in todos">
  <input type="checkbox" v-model="todo.done">
  ...
</li>

        在这之后就引入了这个全新的概念——计算属性,用computed选项进行声明,他的值由其他值计算而来。

<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
    }
  },
  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>

        下面,生命周期与模板引用。模板引用指向模板中的一个DOM元素的ref,在挂载后执行代码需要使用mounted选项。这里注意,虽然也是写在default里面,但执行时已经挂载结束,这被称为生命周期钩子。除了mounted,常见的还有updated和unmounted钩子。答案如下:

<script>
export default {
  data() {
    return {
      message: "hello"
    }
  },
  mounted() {
    this.$refs.p.textContent = "nihao"
  }
}
</script>

<template>
  <p ref="p">{{message}}</p>
</template>

        来继续,侦听器。可以实现比如,在某个数字改变时将其输出到控制台这样的功能。这东西一猜就知道是watch选项。有一说一这部分浪费我不少时间,确实看着代码有些吃力了。这道题的答案如下:

<script>
export default {
  data() {
    return {
      todoId: 1,
      todoData: null
    }
  },
  methods: {
    async fetchData() {
      this.todoData = null
      const res = await fetch(
        `https://jsonplaceholder.typicode.com/todos/${this.todoId}`
      )
      this.todoData = await res.json()
    }
  },
  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>

        以上的全部内容都是单组件来搞的,但是很明显只有单组件是不可能完成复杂的应用的,是需要多个组件嵌套完成才对。果然,父组件可以在模板中渲染子组件,在使用子组件时候需要导入,例如下面:

import ChildComp from './ChildComp.vue'

export default {
  components: {
    ChildComp
  }
}

        在此之上还需要使用components注册组件,然后就可以直接用了<ChildComp />。本题的答案如下所示:

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

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

        子组件可以通过props从父组件接收动态数据,这里要声明接受的props,声明后就可以用this调用了,也可以使用v-bind语法等等。答案如下:

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

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

<template>
  <ChildComp v-bind:msg="greeting"/>
</template>

        子组件还可以向父组件触发事件,这题答案:

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

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

<template>
  <ChildComp @response="(msg) => childMsg = msg"/>
  <p>{{ childMsg }}</p>
</template>

        除了props,还可以用插槽(slots)的形式将片段传给子组件,可使用<slots>元素作为插槽出口,渲染父组件的插槽内容。slot中的内容会作为默认内容,在无传递时候显示。答案如下:

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

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

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

        到目前为止,已经完成了Vue官网的互动教程,人家官方说了咱忽略了大量的细节,所以还得看他那个快速上手、深入指南还有实例,也确实,搞了这么半天也就能输出来一行文字,这照前端的页面那可差远了。

        接下来将上手的内容是快速上手阶段。前面的都是分段式的教程,现在只是会用一些简单的组件之类的,现在要整体来看了。每个Vue应用都是通过createApp函数创建一个新的应用实例。这里注意,所有的函数都需要及进行一个导入:

import { createApp } from 'vue'

const app = createApp({
  /* 根组件选项 */
})

        传入createApp的是一个组件,每个应用都需要一个根组件,其他组件都是这个的子组件。

import { createApp } from 'vue'
// 从一个单文件组件中导入根组件
import App from './App.vue'

const app = createApp(App)

        打开之前创建的空Vue项目或者干脆新建一个也行,然后进行一下上述操作。这里官方教程写的太乱套了根本没说明白要在哪操作,我就尝试着在src文件夹下新建一个vue组件,起名为Test。讲道理这鬼东西根本不知道该往哪写啊。。。只是截取了部分代码谁知道往哪写啊也没说清楚,后面的内容我就自己去官网看了,就不上手写了。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值