Vue 学习笔记(一)

1、环境安装

# 创建项目
$ npm init vite vue-vite-ts
Need to install the following packages:
  create-vite@3.2.0
Ok to proceed? (y) y
√ Select a framework: » Vue
√ Select a variant: » TypeScript

Scaffolding project in D:\vscode\vue-vite-ts...

Done. Now run:

  cd vue-vite-ts
  npm install
  npm run dev

# 切换目录
$ cd vue-vite-ts
# 安装pnpm
$ npm install -g pnpm
# 安装依赖
$ pnpm i
# 运行
$ pnpm dev

2、如何修改启动端口号

  • 修改package.json
"scripts": {
    "dev": "vite --port 80",
    "build": "vue-tsc && vite build",
    "preview": "vite preview"
  },

3、父组件给子组件传值

  • 父组件:通过属性msg传值
<script setup lang="ts">
import HelloWorld from './components/HelloWorld.vue'
</script>

<template>  
  <HelloWorld msg="Vue + Vite" :id="23"/>
</template>
  • 子组件:通过defineProps拿到父组件属性值
    • 因为id是number,需要前面加上冒号
    • string可以直接不用加冒号
<script setup lang="ts">
defineProps<{ msg: string,id:number }>()
</script>

<template>
  <h1>{{ msg }}</h1>
</template>

4、模板语法

  • 支持运算和方法调用
<script setup lang="ts">
import { ref } from 'vue';
defineProps<{ msg: string, id: number }>()
const name = ref('周末快乐')
// age=0为假反之为真
const age: number = 2
const temp = ref('周,末,快,乐')
</script>

<template>
  <h1>msg:{{ msg }}</h1>
  <h1>id:{{ id }}</h1>
  <h2>{{name}},{{age}}</h2>
  <!-- 使用表达式 -->
  <h2>{{ age ? '我是真的' : '我是假的' }}</h2>
  <h2>{{ temp.split(',') }}</h2>
  <h2>{{ temp.split(',').map(i => ` 【${i}】 `) }}</h2>
</template>

5、指令

  • v- 开头都是vue 的指令

  • v-text 用来显示文本

  • v-html 用来展示富文本

  • v-if 用来控制元素的显示隐藏(切换真假DOM)

  • v-else-if 表示 v-if 的“else if 块”。可以链式调用

  • v-else v-if条件收尾语句

  • v-show 用来控制元素的显示隐藏(display none block Css切换)

  • v-on 简写@ 用来给元素添加事件

  • v-bind 简写: 用来绑定元素的属性Attr

  • v-model 双向绑定

<script>
import { ref } from 'vue';
// 必须用ref包括,否则无法双向绑定
const name = ref('周末快乐')
</script>
<template>
  <input v-modle="name" type="text" />
  <div>{{ name }}</div>
</template>
  • v-for 用来遍历元素
<script>
const names = [{
  id: 1,
  name: "张三",
  age: 18
}, {
  id: 2,
  name: "张三",
  age: 18
}, {
  id: 3,
  name: "张三",
  age: 18
}, {
  id: 4,
  name: "张三",
  age: 18
}]
const arr = [1, 2, 3, 4, 5]

</script>
<div v-for="(item, i) in arr" :key="i">{{ i }}、{{ item }}</div>
<table border="1">
    <tr v-for="item in names">
      <td style="width: 60px;">{{ item.id }}</td>
      <td style="width: 120px;">{{ item.name }}</td>
      <td style="width: 80px;">{{ item.age }}</td>
    </tr>
  </table>
  • v-on修饰符 冒泡案例

6、ref类型在事件中调用,需要使用value

let age = ref(0)
const changeNum = () => {
  age.value++
}

7、阻止表单提交

<button @click.prevent="submit" type="submit">submit</button>

8、绑定样式和多类绑定

<script>
const styleTeml = {
  "color": "green",
  "height":"200px"
}
const flag = ref(false)
</script>

<template>
  <h1 :style="styleTeml">绑定样式</h1>
  <div :class="['a', 'b']">呵呵</div>

  <button @click="flag = !flag">换颜色</button>
  <div :class="[flag ? 'a' : 'c']">呵呵</div>
</template>

<style scoped>
.a {
  color: aqua;
}

.b {
  height: 200px;
}

.c {
  color: red;
}

9、ref

  • 接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象仅有一个 .value property,指向该内部值
  • 在检查元素后面 点小齿轮,选中“启用自定义格式化工具”,可以直接查看ref
    • customRef:customRef 是个工厂函数要求我们返回一个对象 并且实现 get 和 set 适合去做防抖之类的
    • triggerRef:强制更新页面DOM
    • ShallowRef:创建一个跟踪自身 .value 变化的 ref,但不会使其值也变成响应式的
  • 注意被ref包装之后需要.value 来进行赋值
  • 获取dom元素
<template>
  <div ref="div" id="12">
    我是div
  </div>
  <button @click="btn"> 获取dom</button>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const div = ref<HTMLElement>()
// 获取div内部内容
const btn = () => {
  console.log(div.value?.innerHTML);
}
</script>

10、reactive

  • 用来绑定复杂的数据类型 例如 对象 数组,Map,Set,但ref支持所有类型
  • ref赋值需要加value,reactive不用
// 内部定义 ref
export declare function ref<T extends object>(value: T): [T] extends [Ref] ? T : Ref<UnwrapRef<T>>;
// 内部定义 reactive
export declare function reactive<T extends object>(target: T): UnwrapNestedRefs<T>;
  • 表单提交
<template>
  <form>
    <input v-model="form.name" style="width: 200px;height: 30px;line-height: 20px;" type="text" />
    <hr>
    <input v-model="form.tel" style="width: 200px;height: 30px;line-height: 20px;" type="text" />
    <hr>
    <!-- 阻止默认的刷新 -->
    <input type="submit" @click.prevent="btn" />
  </form>
</template>

<script setup lang="ts">
import { ref, customRef, triggerRef, ShallowRef, reactive } from 'vue'
const div = ref<HTMLElement>()
const name = ref(6)
const form = reactive({
  name: "",
  tel: ""
})

const btn = () => {
  console.log(form);
}
</script>
  • 异步操作,无法更新ui
<template>
  <button @click="btn">添加</button>
  <li v-for="item in list"> {{ item }}</li>
</template>

<script setup lang="ts">
import { ref, customRef, triggerRef, ShallowRef, reactive } from 'vue'
let list: string[] = reactive([])
const btn = () => {
  // 同步添加没有问题;
  // list.push('add');
  // 异步添加,直接赋值,则无法渲染,因为reactive是proxy对象,直接赋值会破坏响应式对象,两种解决办法,第一种 push+解构
  setTimeout(() => {
    // list = ['add', 'del', 'save']
    // console.log(list);
    // 第一种办法:
    let res = ['add', 'del', 'save']
    list.push(...res)
    console.log(list);
  }, 2000)
}
</script>
  • 第二种解决异步问题,添加一个对象,把数组当做属性使用
<template>
  <button @click="btn">添加</button>
  <li v-for="item in list.arr"> {{ item }}</li>
</template>

<script setup lang="ts">
import { ref, customRef, triggerRef, ShallowRef, reactive } from 'vue'
let list = reactive<{ arr: string[] }>({
  arr: []
})
const btn = () => {
  // 同步添加没有问题;
  // list.push('add');
  // 异步添加,直接赋值,则无法渲染
  setTimeout(() => {
    let res = ['add', 'del', 'save']
    list.arr = res
    console.log(list);

  }, 2000)
}
  • readonly:把一个reactive赋值给readonly,就会变成只读,但是会受原始对象影响
<script setup lang="ts">
import { readonly, reactive } from 'vue'
let list = reactive({
  name: "李四"
})
let listR = readonly(list)
const btn = () => {
  console.log(list, listR)
}
</script>
posted @ 2022-11-05 09:14  his365  阅读(28)  评论(0编辑  收藏  举报