day-drf08

发布时间 2023-10-07 17:29:54作者: Py玩家

创建vue3项目

两种方式

方式一:
vue-cli:利用vue脚手架,创建vue项目,构建vue项目,工具链跟之前一样

方式二:
vite :https://cn.vitejs.dev/(官方网站介绍)
npm create vue@latest(创建项目,一路选择选项即可)

运行vue3项目

vue-cli:跟创建vue2一样
vite创建:npm install   npm run dev

vite为什么启动快

1.vite是冷启动,不需要做绑定
2.热加载
3.按需编译

补充

编程语言的链式调用

对象。changeName('lqz').printName().showAge()

python 实现链式调用

class Person:
        def changeName(self,name):
            self.name=name
            return self
        def printName(self):
            print(self.name)
            return self

setup函数

概念

setup是vue3中的一个新的配置项,值为一个函数,我们在组件中用到的数据、方法等等,都要配置在setup中

setup返回值

1、返回一个渲染函数,可以自定义渲染内容(用得不多,了解即可)

import {h} from 'vue'

setup() {
        return () => h('h1','学习')
}

2、返回一个对象,对象中的属性和方法在模板中可以直接使用

methods: {
    test1() {
        console.log(this.sex);
        console.log(this.sayHello);
    }
},
setup() {
    const sex = ref('')
    function sayHello() {
        alert('你好啊')
    }
    return {
        sex,
        sayHello
    }
}

 3、注意

1.在vue2的配置中可读取到vue3配置中的属性和方法
2.在vue3的配置中不能读取vue2配置中的属性和方法
3.如果vue2和vue3的配置有冲突,则vue3的setup优先

4、重要知识点

(1)vue2和vue3的配置尽量不要混用
(2)setup不能是一个async函数,因为返回值不再是return的对象, 而是promise, 模板看不到return对象中的属性。(后期也可以返回一个Promise实例,但需要Suspense和异步组件的配合)

setup两个注意点

1、setup执行的时机

在beforeCreate之前执行一次,this是undefined
beforeCreate(){
    console.log('beforeCreate');
},
setup(){
    console.log('setup',this);
}

2、setup的参数

1、props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性。

在父组件中给子组件传递数据
<Demo msg="你好啊" name="tom" />
在子组件中接收
props:['msg','name'], // 需要声明一下接受到了,否则会报警告
setup(props){
    console.log(props)
}

2、context:上下文对象

3、attrs: 值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性, 相当于 this.$attrs。

4、slots: 收到的插槽内容, 相当于 this.$slots。

5、emit: 分发自定义事件的函数, 相当于 this.$emit。

$符号解释

1、在Vue中,$符号是一个特殊的标记,表示Vue中提供的全局属性或方法。每个Vue实例都有一个与之关联的$root实例,其中包含许多全局属性和方法。

在Vue中使用$符号时,可以直接调用全局属性或方法,例如$el、$data、$props等。其中,$el表示Vue实例所挂载的DOM元素,$data表示Vue实例的数据对象,$props表示Vue实例接收到的props对象。我们可以通过打印这些属性来了解Vue实例中的内部状态和数据。

new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
mounted: function () {
console.log(this.$el);    //
console.log(this.$data);  // { message: 'Hello Vue!' }
}
})

2、除了属性外, Vue还提供了很多全局方法,可以通过$符号直接调用。常用的有$watch和$emit。在Vue中使用$watch可以监控数据变化,当数据变化时执行相应操作;而$emit可以触发自定义事件,当事件被触发时执行相应操作。

new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
mounted: function () {
this.$watch('message', function (newValue, oldValue) {
console.log('message changed', newValue, oldValue);
});
},
methods: {
showMessage: function () {
this.$emit('show-message', this.message);
}
}
})

3、除了全局属性和方法外,Vue还提供了一些实例属性和方法,也以$符号开头。例如:$refs、$slots、$forceUpdate等。其中,$refs表示获取Vue实例中所有的ref属性,并返回一个包含所有引用的对象; $slots表示获取Vue组件传递的插槽;$forceUpdate表示强制重新渲染视图。

Vue.component('my-input', {
template: '',
methods: {
focus: function () {
this.$refs.input.focus();
}
}
})

ref函数

变量要具备响应式---》页面内容变化,变量和变,变量变化,页面也变

普通变量,通过ref绑定响应式

引用类型变量:通过reactive 绑定响应式

<template>
  <div class="home">
    <p>我的名字是:{{ name }}</p>
    <p>我的年龄是:{{ age }}</p>
    <button @click="handleAdd">点我年龄+1</button>
    <button @click="handleChangeName">点我秒变彭于晏</button>
  </div>
</template>

<script>
import {ref} from 'vue'

export default {

  setup() {
    // 1 定义数据
    let name = ref('lqz')
    let age = ref(19)
    // 2 定义方法
    const handleAdd = () => {
      age.value += 1
      console.log(typeof age)
    }
    const handleChangeName = () => {
      name.value = '彭于晏'
    }
    return {name, age, handleAdd,handleChangeName}

  },
}
</script>

解释

作用: 定义一个响应式的数据
语法: const xxx = ref(initValue)
创建一个包含响应式数据的引用对象(reference对象,简称ref对象)。
JS中操作数据: xxx.value
模板中读取数据: 不需要.value,直接:<div>{{xxx}}</div>
备注:
接收的数据可以是:基本类型(值类型)、也可以是对象(引用类型)类型。

reactive函数

变量要具备响应式---》页面内容变化,变量和变,变量变化,页面也变

普通变量,通过ref绑定响应式

引用类型变量:通过reactive 绑定响应式

<template>
  <div class="home">
    <p>我的名字是:{{ data.name }}</p>
    <p>我的年龄是:{{ data.age }}</p>
    <p>我的爱好是:{{ hobby }}</p>
    <button @click="addAge">点我年龄+1</button>
    <br>
    {{ obj.hobby }}
    <br>
    <button @click="changeHobby">点我把保龄球换成足球</button>


    <hr>
    <HelloWorld msg="asdfasdfasdfasdf"></HelloWorld>
  </div>
</template>

<script>import {reactive, ref} from 'vue'
import HelloWorld from "@/components/HelloWorld.vue";

export default {
  name: 'HomeView',
  setup(props) {

    let hobby = ref('篮球')
    let obj = ref({
      age: 99,
      hobby: '保龄球'
    })

    const changeHobby = () => {
      console.log(obj)
      obj.value.hobby = '足球'
    }

    let data = reactive({
      name: '彭于晏',
      age: 19
    })
    const addAge = () => {
      //data.age++
      console.log(typeof data)
      console.log(data) // 是一个代理对象,无法拿出原来对象,但是操作起来跟操作源对象一样
      data.age++
    }
    return {hobby, data, addAge, obj, changeHobby}

},
components: {
HelloWorld
}

}

 

解释

作用: 定义一个对象类型的响应式数据(基本类型不要用它,要用ref函数)
语法:const 代理对象= reactive(源对象)接收一个对象(或数组),返回一个代理对象(Proxy的实例对象,简称proxy对象)
reactive定义的响应式数据是“深层次的”,无论套多少层,都具备响应式

以上总结

 如果用基本数据类型:数字,字符串,布尔,用ref做响应式
 如果是对象类型,用ref和reactive都可以,但是建议使用reactive
 如果使用ref包裹对象类型,多了一层value

计算监听属性

<template>
  <div class="home">
    <input type="text" v-model="name.firstName">
    <input type="text" v-model="name.lastName">
    <br>
    <input type="text" v-model="fullName">


    <button @click="age++">点我年龄加</button>
  </div>
</template>

<script>


import {computed, watch, reactive, ref,watchEffect} from 'vue'

export default {
  name: 'HomeView',
  setup() {
    // 计算属性:computed

    let name = reactive({
      firstName: 'liu',
      lastName: 'qz'
    })

    let fullName = computed({
      get() {
        return name.firstName + '-' + name.lastName
      },
      set(value) {
        const nameArr = value.split('-')
        name.firstName = nameArr[0]
        name.lastName = nameArr[1]

      }
    })

    let age = ref(19)

    // 监听属性

    // 监听基本类型
    watch(age, (newValue, oldValue) => {
      console.log(oldValue)
      console.log(newValue)
    })
    // 监听对象
    watch(() => name.firstName, (newValue, oldValue) => {
      console.log(oldValue)
      console.log(newValue)
    })
    // watchEffect函数
    watchEffect(() => {
      const x1 = age.value
      const x2 = name.firstName
      console.log('watchEffect配置的回调执行了')
    })
    return {name, fullName, age}
  }
}
</script>

 

生命周期

beforeDestroy改名为 beforeUnmount
destroyed改名为 unmounted

<template>
  <div class="home">
    <h1>首页</h1>
  </div>
</template>

<script>

import axios from "axios";
import {
  computed,
  watch,
  reactive,
  ref,
  watchEffect,
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onBeforeUnmount,
  onUnmounted
} from 'vue'

export default {
  name: 'HomeView',
  setup() {

    // 第一个beforeCrete
    console.log('我是beforeCrete')

    // 第二个Creted
    let name = ref('lqz')
    console.log('Creted')
    // axios.get().then(res => {
    //   name.value = res.data.name
    // })

    // 直接启动定时器
    let t = setInterval(() => {
          console.log('lqz')
        }, 3000
    )
    // 第三个:onBeforeMount
    onBeforeMount(() => {
      console.log('挂载了')
    })

    onBeforeUnmount(() => {
      clearInterval(t)
      t = null

    })

    return {}

  },
}
</script>

torefs

<template>
  <div class="home">
    <h1>首页</h1>
    {{ name }}---{{ age }}
  </div>
</template>

<script>

import axios from "axios";
import {
  reactive,
  toRefs

} from 'vue'

export default {
  name: 'HomeView',
  setup() {
    let data = reactive({
      name: 'lqz',
      age: 19
    })

    return {...toRefs(data)}
  },

}

// 对象的解压
let data ={'name':'lqz',age:19}
let dict={...data,hobby:'篮球'}

console.log(dict)

</script>

vue3 setup写法

 以后vue3推荐,把setup函数的代码,直接写在script中

<script setup>
定义变量
写函数
不用return,在html中直接使用
</script>

使用组件,直接导入,不需要配置,直接用即可

import HelloWorld from "../components/HelloWorld.vue";
在html中直接用:<HelloWorld msg="NB"></HelloWorld>

自定义属性,在子组件中接收

<script setup>
    defineProps({
      msg: {
        type: String,
        required: true
      }
    })
</script>