VUE3 学习日记(一)

一、创建一个新的应用

 1.1应用实例

每个 Vue 应用都是通过 createApp 函数创建一个新的 应用实例

import { createApp } from 'vue'

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

1.2 跟组件。

我们需要一个跟组件来实现挂载。  我们传入的create App的对象实际是一个组件。每个应用都需要一个跟组件。 剩下的都是其子组件。我们可以在main.js 文件中 倒入一个文件做为跟组件。

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

const app = createApp(App)

1.3。 如何实现挂载。

  我们的应用实例必须调用app.mount() 方法后才会渲染出来。 这个方法需要接受一个类似容器(也就是App)作为参数,可以是一个实际的DOM元素 或是一个CSS选择器字符串(就是app)

<div id="app"></div>
-------------------------
app.mount('#app')

1.4 多个实例挂载

在vue3中。应用实例并不只限于一个。createApp API 允许你在同一个页面中创建多个共存的 Vue 应用,而且每个应用都拥有自己的用于配置和全局资源的作用域。这里和vue2不一样。vue2是只能一个实例而已。

const app1 = createApp({
  /* ... */
})
app1.mount('#container-1')

const app2 = createApp({
  /* ... */
})
app2.mount('#container-2')

二、模版语法

2.1. 文本插值

最基本的数据绑定形式是文本插值,它使用的是“Mustache”语法 (即双大括号):

<span>Message: {{ msg }}</span>
 

2.2  如果我们想要插入html的话   需要用到v-tml指令 

<p>Using text interpolation: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>

2.3  Attribute 绑定

双大括号不能在 HTML attributes 中使用。想要响应式地绑定一个 attribute,应该使用 v-bind 指令:   <div v-bind:id="dynamicId"></div>
v-bind 指令指示 Vue 将元素的 id attribute 与组件的 dynamicId 属性保持一致。如果绑定的值是 null 或者 undefined,那么该 attribute 将会从渲染的元素上移除。简写是 

<div :id="dynamicId"></div>
我们还可以动态的钱绑定多个值。如果你有像这样的一个包含多个 attribute 的 JavaScript 对象:

data() {
  return {
    objectOfAttrs: {
      id: 'container',
      class: 'wrapper'
    }
  }
}
<div v-bind="objectOfAttrs"></div>

2.4 使用javascript表达式

{{ number + 1 }}

{{ ok ? 'YES' : 'NO' }}

{{ message.split('').reverse().join('') }}

<div :id="`list-${id}`"></div>

在 Vue 模板内,JavaScript 表达式可以被使用在如下场景上:

  • 在文本插值中 (双大括号)
  • 在任何 Vue 指令 (以 v- 开头的特殊 attribute) attribute 的值中

2.5 指令

  指令是带有 v- 前缀的特殊 attribute。Vue 提供了许多内置指令,包括上面我们所介绍的 v-bind 和 v-html。还有v-if  v-bind(属性) v-on(事件) 

<a v-bind:href="url"> ... </a>

<!-- 简写 -->
<a :href="url"> ... </a>


<a v-on:click="doSomething"> ... </a>

<!-- 简写 -->
<a @click="doSomething"> ... </a>

<!--
注意,参数表达式有一些约束,
参见下面“动态参数值的限制”与“动态参数语法的限制”章节的解释
-->
<a v-bind:[attributeName]="url"> ... </a>

<!-- 简写 -->
<a :[attributeName]="url"> ... </a>

2.6 修饰符

修饰符是以点开头的特殊后缀,表明指令需要以一些特殊的方式被绑定。例如 .prevent 修饰符会告知 v-on 指令对触发的事件调用 event.preventDefault()

<form @submit.prevent="onSubmit">...</form>

还有一些 比如  .stop   .native  .trim(去除前后空格)

三、响应式状态基础

3.1 我们可以使用 reactive() 函数创建一个响应式对象或数组:

import { reactive } from 'vue'

const state = reactive({ count: 0 })

要在组件模板中使用响应式状态,需要在 setup() 函数中定义并返回。

import { reactive} from 'vue'

export default{
    setup(){
        const state = reactive({ count:0 })
        function increment () {
                state.count++
            }
        return {
         state,
        increment
       }    
    }
}

//使用的时候 
<button @click="increment">
  {{ state.count }}
</button>

这里可以看出 这种写法需要我们把状态和方法暴露出去   如果是大型项目的话   会非常繁琐   所以vue官网出来一个新的语法   就是 <script setup>  来大幅度地简化代码:

<script setup>
import { reactive } from 'vue'

const state = reactive({ count: 0 })

function increment() {
  state.count++
}
</script>

<template>
  <button @click="increment">
    {{ state.count }}
  </button>
</template>

<script setup> 中的顶层的导入和变量声明可在同一组件的模板中直接使用。你可以理解为模板中的表达式和 <script setup> 中的代码处在同一个作用域中。

3.2 DOM 更新时机

我们在修改响应式状态会  我们的系统会自动更新状态  但是  当我们的DOM更新并不是同步而是异步的时候  ,Vue 将缓冲它们直到更新周期的 “下个时机” 以确保无论你进行了多少次状态更改,每个组件都只更新一次。在vue2版本中一样适用。

若要等待一个状态改变后的 DOM 更新完成,你可以使用 nextTick() 这个全局 API:

import { nextTick } from 'vue'

function increment() {
  state.count++
  nextTick(() => {
    // 访问更新后的 DOM
  })
}

3.3  reactive() 的局限性

reactive() API 有两条限制:

1.仅对对象类型有效(对象、数组和 MapSet 这样的集合类型),而对 stringnumber 和 boolean 这样的 原始类型 无效。

2.因为 Vue 的响应式系统是通过属性访问进行追踪的,因此我们必须始终保持对该响应式对象的相同引用。这意味着我们不可以随意地“替换”一个响应式对象,因为这将导致对初始引用的响应性连接丢失:

let state = reactive({ count: 0 })

// 上面的引用 ({ count: 0 }) 将不再被追踪(响应性连接已丢失!)
state = reactive({ count: 1 })

同时这也意味着当我们将响应式对象的属性赋值或解构至本地变量时,或是将该属性传入一个函数时,我们会失去响应性:

const state = reactive({ count: 0 })

// n 是一个局部变量,同 state.count
// 失去响应性连接
let n = state.count
// 不影响原始的 state
n++

// count 也和 state.count 失去了响应性连接
let { count } = state
// 不会影响原始的 state
count++

// 该函数接收一个普通数字,并且
// 将无法跟踪 state.count 的变化
callSomeFunction(state.count)

3.4 用 ref()来定义响应式的状态

为了解决reactIve() 的局限性  vue官方出了一个 ref() 方法  来允许我们创建可以使用任何值类型的响应式状态:

import { ref } from 'vue'

const count = ref(0)

console.log(count) // { value: 0 }
console.log(count.value) // 0

count.value++
console.log(count.value) // 1

const objectRef = ref({ count: 0 })

// 这是响应式的替换
objectRef.value = { count: 1 }


const obj = {
  foo: ref(1),
  bar: ref(2)
}

// 该函数接收一个 ref
// 需要通过 .value 取值
// 但它会保持响应性
callSomeFunction(obj.foo)

// 仍然是响应式的
const { foo, bar } = obj


  还有当ref 在模板 <template>  中作为顶层属性被访问时,它们会自动“解包”,所以不需要  .value    请注意,仅当 ref 是模板渲染上下文的顶层属性时才适用自动“解包”。 例如, object 是顶层属性,但 object.foo 不是。

<script setup>
import { ref } from 'vue'

const count = ref(0)

function increment() {
  count.value++
}
</script>

<template>
  <button @click="increment">
    {{ count }} <!-- 无需 .value -->
  </button>
</template>

const object = { foo: ref(1) }

//错误用法
{{ object.foo + 1 }}

//正确用法
const { foo } = object
{{ foo + 1 }}


{{ object.foo }}

ref在响应式对象中解包   作为属性被访问或更改时,他会自动解包 

const count = ref(0)
const state = reactive({
  count
})

console.log(state.count) // 0

state.count = 1
console.log(count.value) // 1

如果将一个新的 ref 赋值给一个关联了已有 ref 的属性,那么它会替换掉旧的 ref:

只有当嵌套在一个深层响应式对象内时,才会发生 ref 解包。当其作为浅层响应式对象的属性被访问时不会解包。

const otherCount = ref(2)

state.count = otherCount
console.log(state.count) // 2
// 原始 ref 现在已经和 state.count 失去联系
console.log(count.value) // 1

跟响应式对象不同,当 ref 作为响应式数组或像 Map 这种原生集合类型的元素被访问时,不会进行解包。

const books = reactive([ref('Vue 3 Guide')])
// 这里需要 .value
console.log(books[0].value)

const map = reactive(new Map([['count', ref(0)]]))
// 这里需要 .value
console.log(map.get('count').value)

四、计算属性

4.1 基础示例

我们知道  在模板中我们可以写一些简单的操作 但是如果是逻辑太多的话  会显得臃肿或者执行不成功  所以我们有一个计算属性的方法可以实现这个,首先这个计算属性相当于一个方法或者一个函数 里面写我们想要的逻辑 然后return 出去就行

computed() 方法期望接受一个getter函数  返回值为计算属性ref  和其他的一样 可以通过 XX.value去访问  同理 计算属性ref 也会在模板中自动解绑  所以在模板中无需添加 .value。

vue的计算属性会自动追踪响应式依赖  所以计算属性 依赖于 响应式数据  当响应式数据发生变化  相应的计算属性的值也会发生变化   示例:

<script setup>
import { reactive, computed } from 'vue'

const author = reactive({
  name: 'John Doe',
  books: [
    'Vue 2 - Advanced Guide',
    'Vue 3 - Basic Guide',
    'Vue 4 - The Mystery'
  ]
})

// 一个计算属性 ref
const publishedBooksMessage = computed(() => {
  return author.books.length > 0 ? 'Yes' : 'No'
})
</script>

<template>
  <p>Has published books:</p>
  <span>{{ publishedBooksMessage }}</span>
</template>

4.2  计算属性缓存  VS 方法

了解完计算属性  我们会发现这个和方法似乎没啥不一样  一样可以实现逻辑,但是不同的是  计算属性值会基于响应式依赖被缓存   只有响应式数据发生变化才会重新计算  而方法不一样 是不会改变的。而为什么需要缓存 是因为计算属性是一个需要计算的东西  如果我们没有缓存的话  我们会重复执行很多次的getter  而实际并不必要。

还有 大部分我们写计算属性都是用来只读的   不会去修改。但是有些特殊场景中  不得不对计算属性进行写的操作,我们可以通过getter 和 setter  来创建入  看代码  现在当你再运行 fullName.value = 'John Doe' 时,setter 会被调用而 firstName 和 lastName 会随之更新。

<script setup>
import { ref, computed } from 'vue'

const firstName = ref('John')
const lastName = ref('Doe')

const fullName = computed({
  // getter
  get() {
    return firstName.value + ' ' + lastName.value
  },
  // setter
  set(newValue) {
    // 注意:我们这里使用的是解构赋值语法
    [firstName.value, lastName.value] = newValue.split(' ')
  }
})
</script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 很高兴回答你的问题。作为一个 AI 语言模型,我没有实际的经验来记录日记。但是,我可以告诉你,Vue 是一个流行的 JavaScript 框架,它可以帮助开发人员构建交互式的 Web 应用程序。Vue 具有简单易学、灵活性强、性能优异等优点,因此在开发中得到了广泛的应用。如果你有任何关于 Vue 开发的具体问题,我很乐意帮助你解答。 ### 回答2: 第一天: 今天开始了一周的vue开发。首先,我花了一些时间了解了一下vue的基本概念和语法规则。我了解到vue是一个渐进式的JavaScript框架,它可以用于构建用户界面。我通过阅读官方文档和参考一些教程来学习如何使用vue。初步了解了vue的组件化开发和数据绑定的概念。 第二天: 今天,我决定尝试一下使用vue来构建一个简单的ToDo列表应用程序。我创建了一个vue项目,并在主组件中定义了一些数据和方法。然后,我使用v-for指令来遍历数据,并使用v-bind指令实现了数据的双向绑定。我还添加了一些样式来美化界面。整个过程相对顺利,虽然在处理一些细节时遇到了一些问题,但最终成功完成了ToDo列表应用。 第三天: 今天我决定学习一下vue的路由功能。我在项目中引入了vue-router,并创建了一些路由组件。然后我定义了一些路由规则,并在主组件中使用<router-view>显示当前路由对应的组件。我还添加了一些导航链接,并用router-link指令实现了路由的切换。学习路由功能过程中遇到了一些语法和配置问题,但最终解决了。 第四天: 今天我开始学习vue的状态管理功能。我在项目中引入了vuex,并创建了一些状态和mutations。然后我在主组件中使用mapState和mapMutations辅助函数来访问和修改状态。学习状态管理的过程中,我发现了vuex的一些特性,比如模块化和插件化,并尝试使用这些特性来简化代码结构。 第五天: 今天我专注于学习vue的动画功能。我在项目中引入了vue的动画模块,并尝试了一些基本的动画效果,如淡入淡出和滑动效果。我还了解到了过渡和动态组件的概念,并尝试通过vue的transition和transition-group组件实现了这些效果。学习动画功能让我的应用程序变得更加生动和有趣。 第六天: 今天我决定学习vue的性能优化技巧。我通过懒加载和按需加载等技术来优化我的应用程序的加载速度。我还使用vue-devtools工具来分析和优化组件的性能。学习性能优化的过程中,我了解到了一些常见的优化策略,如减少不必要的重新渲染和合理使用计算属性等。 第七天: 今天是我这一周的vue开发的最后一天。我回顾了一下这一周的学习和实践,发现自己在vue的开发中有了很大的进步。我对vue的基本概念和语法有了更深入的了解,也掌握了一些高级功能和优化技巧。我觉得通过这一周的实践,我对vue的开发有了更加扎实的基础,以后可以更好地应用它来构建复杂的应用程序。 ### 回答3: 第一天: 今天开始进行vue开发,首先安装了vue-cli脚手架工具,并创建了一个新的vue项目。然后我使用vue-router插件来搭建了项目的路由系统,可以通过不同的URL来实现页面的跳转。接下来,我创建了几个组件,包括Header、Footer和Home等,并在页面中引入和使用了这些组件。通过组件化的开发方式,我可以更好地管理和复用代码。 第二天: 今天我继续进行vue开发,学习vue的数据绑定和事件绑定。我在组件中创建了一些数据属性,然后在模板中使用双花括号语法将数据和页面进行绑定。并且,我还通过v-on指令绑定了一些事件处理函数,实现了一些交互功能,比如点击按钮触发弹窗等。vue的数据驱动模型让我对整个开发过程更加流畅和高效。 第三天: 今天我开始研究vue的组件通信问题。我学习了父子组件之间的通信方式,包括props和$emit方法,可以实现父组件向子组件传递数据和子组件向父组件发送事件。我还学习了兄弟组件之间的通信方式,可以使用事件总线或者vuex来实现不同组件之间的数据传递和状态管理。掌握了这些通信方式后,我能够更好地组织和管理组件之间的关系。 第四天: 今天我学习vue的生命周期钩子函数。通过对生命周期的理解,我可以在不同阶段进行一些初始化或者清理工作。其中,created和mounted是最常用的两个钩子函数,分别在实例创建之后和实例挂载到页面之后被调用。我可以在这两个钩子函数中进行一些异步数据请求或者DOM操作,确保在渲染之前或之后进行必要的操作。 第五天: 今天我开始学习vue的状态管理模式vuex。在复杂的应用中,组件之间的状态管理变得非常重要,而vuex提供了一个集中式的存储管理方案。我创建了一个vuex的store,包括state、mutations、actions和getters等。通过mutations和actions,我可以对state进行修改,并且可以通过getters获取state中的数据。vuex的使用大大简化了整个应用的状态管理流程。 第六天: 今天我继续进行vue开发,学习了异步组件和动态路由的使用。在项目中,如果有一些组件比较大或者需要懒加载,可以使用异步组件的方式按需加载。我使用了import函数和webpack的代码分割功能来实现异步组件的加载。另外,动态路由可以使得路由的配置更加灵活,可以根据需要动态添加或删除路由配置。这样我可以更好地管理和控制路由。 第七天: 今天是我进行vue开发的最后一天,我进行了项目的打包和部署。通过vue-cli提供的命令,我将项目进行了打包,生成了静态资源文件。然后,我将这些静态资源文件上传到服务器,并配置了nginx代理,使得项目可以通过域名访问。最后,我进行了一些简单的测试和优化,确保项目在生产环境下正常运行。整个vue开发流程结束,我对vue的开发有了更深入的了解。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值