vue3(一)

本文章主要概述了:
1、webpack和vite构建vue项目的区别
2、vue项目创建以及启动
3、vue官方在vscode中推荐的插件
4、vue项目目录解析
5、src目录解析
6、vue2的组合式API到vue3文件的格式
7、响应式数据ref和reactive
8、响应式解构toRefs
9、v-bind和v-model
10、computed
11、watch及监视的五种情况
12、watchEffect

1、webpack和vite构建vue项目的区别
webpack是先把所有东西准备好再启动服务,vite是先启动服务,再把需要的组件放到服务上。vue官方推荐使用vite构建vue项目。

2、vue项目创建以及启动

  • 到项目目录输入vue create vue@latest,这是vue官方推荐的写法,但是我更推荐使用vue cli的自定义配置,里面可以选typescript,接下来按提示输入项目信息。到项目目录下,需要输入npm i安装所有依赖
  • 启动项目用何种命令,是看package.json文件中,如果scrips下是dev,那就用npm run dev,如果是serve,那就用npm run serve

3、vue官方在vscode中推荐的插件
(1)TypeScript Vue Plugin (2)Vue Language Features

4、vue项目目录解析
(1)public文件夹下面存储的favicon.ico叫做页签图标
(2)src是源代码文件
(3)node_modules是项目的依赖,有点像Java的jar包,如果没有这个文件夹,可以通过npm i命令来安装所有依赖**
(4)env.d.ts,该文件用于声明所有你要用到的文件,使得项目能够认识它
(5)index.html是vue项目的入口
(6)package-lock.json 和 package.json是包的管理文件
(7)vite.config.ts是用来装插件或配置代理之类的

5、src目录解析
(1)main.ts文件
import { createApp } from 'vue'//创建应用,相当于花盆
import App from './App.vue'//引入组件,相当于根,以后你可能会写B.vue,C.vue,这些都是花的支叉。
createApp(App).mount('#app')//创建应用,每个应用都有一个根组件,根组件就是APP,并把创建的成果挂载到#app的容器里,容器在index.html中就声明了。(在index。html中有这句代码<div id="app"></div>
(2)components文件夹
(3)App.vue文件是根
(4)assert文件夹存储图片或css样式

6、vue2的组合式API到vue3文件的格式

<script lang = "ts">
export default {
  name: 'Person',
  components: {
  },
  setup(){  //  setup生命周期比beforeCreate()还要早
    //数据
    //方法    //setup里的this是undefined
    return{
      //要给template用的数据、方法放在这里交出去
    }
  }
}
</script>

<script lang = "ts" setup>
//这里面写的数据或方法会自动return出去
</script>

7、响应式数据ref和reactive
(1)ref修饰数据
(2)reactive修饰对象或数组

  • 对于通过ref函数创建的响应式数据,我们可以通过.value属性来访问其实际值;而对于通过reactive函数创建的响应式对象,我们可以直接访问其属性或调用其方法。

  • ref主要是为了解决单一元素/数据的响应式问题,而reactive则是为了解决JavaScript对象和数组等复杂数据结构的响应式问题。

<script lang = "ts" setup name = "Person">
import { reactive } from 'vue'
let car = reactive({brand: '车1', price: 100})
</script>

8、响应式解构toRefs

let person = reactive({
  name: 'zhangsan',
  age: 18
})
let { name,age } = person;  //普通解构
//上面这一行等价于:
let name = person.name;
let age = person.age;
//上面的name和age都不是响应式的,而下面这一行的name和age都是响应式的
let { name,age } = toRefs(person);  //响应式解构,访问要用.value

9、v-bind和v-model

<li v-for="i in games" :key="g.id"></li>
<!-- "v-bind:"含义是把等于号后面的东西当成js表达式去解析 (这里的games是一个数组)-->

再举一个例子:
<input type="text" value="firstname"></input>,这句代码的意思是写了一个输入框,输入框默认的内容是firstname。当firstname是script里的一个变量的时候要如何书写呢?
答案:<input type="text" v-bind:value="firstname"></input>
这时候,firstname就是一个变量了,但是v-bind不支持双向绑定,也就是说当输入框里的内容变化的时候,firstname这个变量的值是不变的,v-model可以很好的解决这个问题,这样书写:
<input type="text" v-model="firstname"></input>

10、computed
计算属性有一个特点,它是有缓存的,当要计算所依赖的数据只要发生变化,它就得重新计算

let firstName = ref('zhang');
let lastName = ref('san');
let fullName = computed(()=>{
  return firstName.value.slice(0,1).toUpperCase() + firstName.value.slice(1) + '-' +lastName.value;
})

上面这段代码里的return是指把数据return给template中供它使用,而不是把值返回给方法,这也是computed是只读的原因,它并不会改变fullname的值。而接下来的这种写法,fullname是可读可写的

let firstName = ref('zhang');
let lastName = ref('san');

let fullName = computed(()=>{
  get(){
    return firstName.value.slice(0,1).toUpperCase() + firstName.value.slice(1) + '-' +lastName.value;
  }
  set(val){
    const [str1,str2] = val.split('-');  //按‘-’拆分字符串
    firstName.value = str1;
    lastName.value = str2; 
  }
})

function changeFullName(){  //说明,一个事件绑定了本方法,触发了接下来的修改fullName操作
  fullName.value = "li-si";  //本行代码会引起computed里的set调用
}

11、watch及监视的五种情况
vue官方指明,watch只能监视以下四种数据:

  1. ref定义的数据。
  2. reactive定义的数据。
  3. 一个函数,返回一个值
  4. 一个包含上述内容的数组

情况一:监视ref定义的基本类型数据

<script lang = "ts" setup name = "Person">
  import { ref, watch } from 'vue';
  //数据
  let sum = ref(0);
  //方法
  function changeSum(){
    sum.value += 1;
  }
  //监视    //格式:watch(谁?,回调函数)
  watch(sum,(newValue,oldValue)=>{  //sum不需要.value,因为sum.value不属于上述四种中的一种
    console.log('sum变化了',newValue,oldValue);
  })  
  //在vue.js中watch这个函数的返回值是一个停止监视的函数。如果当sum大于10时要停止监视,watch要写成下面这种
  const stopWatch = watch(sum,(newValue,oldValue)=>{
    console.log('sum变化了',newValue,oldValue);
    if(newValue >= 10){
      stopWatch();
    }
  })  
</script>

情况二:监视ref定义的对象类型数据

<script lang = "ts" setup name = "Person">
  import { ref, watch } from 'vue';
  let person = ref({
    name: 'zhangsan',
    age: 18
  })

  watch(person,(newValue,oldValue)=>{  //监视的是对象的地址值,要想监视对象内部属性的变化,需要手动开启深度监视
    console.log("person变化了",newValue,oldValue)
  },{deep: true, immediate: true})  //  加上“{deep: true}”表示开启深度监视
  //加上“immediate: true”表示不论数据是否发生变化,都先执行这段监视代码
  //当修改整个对象的时候newValue与oldValue值不同,当修改对象内部数据时,newValue等于oldValue的值,实际开发过程中,一般只写一个参数value
  function changeName(){
    person.value.name += '~'
  }
  function changeAge(){
    person.value.age += 1;
  }
  function changePerson(){
    let person = ref({name: "lisi",age: 90})  //这一行是修改整个人,删除原有对象并重新创建一个对象
    //Object.assign(person,{name:'李四',age:90})  //这一行是批量修改属性,并不对原有对象的地址进行修改
  }
</script>

情况三:监视reactive定义的对象类型数据
与ref不同的是,reactive是自动开启深度监视的,且不可关闭

情况四:只监视某一对象的某一属性

<script lang = "ts" setup name = "Person">
  import { reactive, watch } from 'vue';
  let person = reactive({name: 'zhangsan',age: 18})  
  
  watch(()=>{return person.name},()=>{
    console.log("person.name变化了", newValue, oldValue);
  })
  
  function changeName(){
    personName += '~';
  }
  function changeAge(){
    personAge += 1;
  }
  function changePerson(){
    let person = reactive({name: "lisi",age: 90})
  }
</script>

情况五:监视上述的多个数据

<script lang = "ts" setup name = "Person">
  import { reactive, watch } from 'vue';
  let person = reactive({name: 'zhangsan',age: 18})  
  //  监视的对象可以是数组也可以是对象
  watch([()=>{return person.name,person.car}],()=>{
    console.log("person.name变化了", newValue, oldValue);
  })
  
  function changeName(){
    personName += '~';
  }
  function changeAge(){
    personAge += 1;
  }
  function changePerson(){
    let person = reactive({name: "lisi",age: 90})
  }
</script>

12、watchEffect
立即运行一个函数,提示响应式地追踪其依赖,并在依赖更改时重新执行该函数。
当有两个数据要监视时,可以写成下面这种

<script lang = "ts" setup name = "Person">
  import { ref, watch } from 'vue';
  let temperature = ref(0);
  let height = ref(0)

  watch([temperature,height],(val)=>{
    //从value中获取最新的水温和水位
    let [newTemp,newHeight] = val;
    if(newTemp>=60 || newHeight>=80){
      console.log("给服务器发请求")
    }
  })
  function changeTemerature(){
    temperature.value += 5;
  }
  function changeHeight(){
    height.value += 1;
  }
</script>

那当有1000个数据要监视时间,那数组里是不是要写1000个数据呢?为了解决这个问题,引入了watchEffect,它不明确指出要监视哪些属性,函数中要用到哪些属性,就监视哪些属性。

watchEffect(()=>{
    if(newTemp>=60 || newHeight>=80){
      console.log("给服务器发请求")
    }
})
posted @ 2024-01-01 23:34  惊朝  阅读(12)  评论(0编辑  收藏  举报