09vue3 变化补充

【一】 setup写法之ref

1.要用子组件的方法或者属性要保证子组件已经挂载完毕,否则会显示子组件的东西报错undefined
​
2.实例化ref()对象定义的变量名要和标签中的ref="xx"的一致,--》相当于vue2的this.$refs.myhello,后面那个要是你写的ref="的myhello"的myhello,vue3改了以后你需要通过ref()函数创建的响应式引用来访问模板中通过ref="xx"定义的引用,如果不写一样的名,会找不到那个组件
​
3.流程:
  -在子组件中要暴露出你想要被父组件用的变量或属性,前提是你都定义过了
    defineExpose({adddemo, name})
  -在父组件中你要确保子组件已经挂载了,所以最好是写在某点击事件或者onMounted钩子函数中
      -----onMounted(()=>{
          hello.value.adddemo()
        })
      -----const handleClick = () =>{
            myhello.value.adddemo()
             }
    

1.1父组件

<template>
  <h1>我是首页</h1>
    <input type="text" ref="myinput">
  <hello-world ref="myhello"></hello-world>
    
<button @click="handleClick">dianyix</button>
</template>
​
<script setup>
import HelloWorld from '../components/HelloWorld.vue'
import {ref,onMounted} from "vue";
#子组件    
const myhello=ref()
//写在函数里的触发事件,要触发,那么必然这个时候组件已经加载完了
// const handleClick = () =>{
// myhello.value.adddemo()
// }
//因为此时子组件可能还没有被挂载或渲染,应该确保在子组件已经挂载后再调用其方法 myhello.value.adddemo()直接写不行
onMounted(()=>{
  myhello.value.adddemo()
})
    
#普通标签
//在created的时候就已经有值了
const myinput=ref()
//还没挂载,还没有组件还不能操作所以要在挂载的时候搞
//因为这时候
onMounted(()=>{
  console.log(myinput.value)//这时候才是input的dom对象
  myinput.value.value='hahhahhh'
})
​
</script>

1.2子组件

<script setup>
import {ref} from "vue";
​
const name=ref('llh')
const adddemo=()=>{
  console.log("啊哈,adddemo")
}
defineProps({
  msg: String,
})
defineExpose({adddemo, name})
</script>
​
<template>
  <h1 >{{ msg }}</h1>
</template>
​
​

【二】setup写法之插槽

1.方法有很多可以去看官网

2.1子组件中要插的位置

<template>
  <p><slot name="a"></slot></p>
<!--  <h1 >{{ msg }}</h1>-->
  <p><slot name="b"></slot></p>
</template>

2.2父组件中写的位置

在插得时候不会识别到template
<hello-world ref="myhello">
    <template v-slot:a>我是上面的</template>
    <template v-slot:b>我是下面的</template>
  </hello-world>
​
还可以这样写
    <template #a>我是上面的</template>
    <template #b>我是下面的</template>

【三】toRefs和toRef

# vue3 提供的 toRefs---》在结构的时候--把对象中的普通变量都做成响应式
见名知意,就是把对象中的多个普通变量变成响应式
    # 1 toRefs 可以把对象内部的所有值,都做成响应式
    # 2 通过结构赋值,赋值给某些变量---》这些变量就有响应式
    # 3 改这些变量会影响到原来对象中得值----》因为已经把他又包成对象了,对象是引用型,会改变原值
    
    
"""具体解释"""
1.const {name,age}=p结构赋值,但是这个只是拿的值是没有响应式的相当于name=p.name,age=p.age
​
2.要给这两个变量都加响应式const {name,age}=toRefs(p)--》name=ref(p.name),ref(age=p.age)
​
3.这时候name和age已经是一个响应式对象了,所以拿他的值是要name.value,可以直接改值,他也会变,因为这时候他已经是一个响应式对象了
​
4.这里解释一下const {name,age:n1}=toRefs(p)这个:n1的作用
    -它表示从toRefs(p)返回的对象中解构出age属性,但在解构时将其重命名为nl,nl实际上是p中age属性的响应式引用对象--》就是把age结构出来的对象赋值给n1
    
    
    
    
###toRef没有s很明显,就是对当个值包成响应式对象
    const name=toRef(p,'name')
    name.value="xxx"
    console.log(p)
<script>
const p=reactive({name:"llh",age:11})
//const {name,age}=p//相当于name=p.name,age=p.age
//1.也是llh,11,但是只是值类型
console.log(typeof name)//string
console.log(typeof age)//number
//单纯的值是没有响应式的我们给这个值加响应式就是
//2.变成给ref包裹的响应对象了
//它表示从toRefs(p)返回的对象中解构出age属性,但在解构时将其重命名为nl,nl实际上是p中age属性的响应式引用对象
const {name,age}=toRefs(p)
console.log(name)//object
// console.log(age)//object
age.value++//因为age是对象所以原值会改
console.log(age.value)//12
console.log(p)//Proxy(Object) {name: 'llh', age: 12}
function add() {
      nl.value++
      console.log(nl.value)
    }
    console.log(p)
    </script>

【四】axios使用

# 1 安装
	npm install axios -S
    
# 2 基本使用
// let dataList = reactive([])
let dataList = reactive({results:[]})

axios.get('http://192.168.1.108:8000/film/').then((response) => {
  #1.这样赋值的数据只是单纯的数据没有响应式×
  // dataList=response.data.results

  #2.在 axios.get 的回调中重新将 dataList 设置为一个新的响应式对象,这实际上破坏了原有的响应式引用×
  // 导致 Vue 无法追踪到这个新数组的变化×
  // dataList = reactive(response.data.results)

  #3.我们可以想到假如我们给dataList是一个对象,那么他是可以改值的,还有一点就是它的值不是响应对象所以可以直接赋值,所以直接把dataList写成对象
  // dataList.results=response.data.results

  #4.直接把res.data.result dataList.result这种记住就好和上面的一样的原理,复制过去
  // console.log(response.data.results)
  // Object.assign(dataList.results, response.data.results)

  #5.解构赋值-->普通
  // let {results} = response.data//相当于result=response.data.results
  // dataList.results=results

 #6.解构赋值--》嵌套
	//有{}说明就是开始解构这时候我们知道response里有个data属性,然后:{results}就是和前面的age:n1一样,把拿到的data对象赋值给
  //   let {data: {results}} = response{result}然后又进行解构,取出result=data.result
  //   Object.assign(dataList.results, results)

  #7.解构赋值--》直接把data赋过去
  let {data}=response
  Object.assign(dataList, data)

}).catch((error) => {
  console.log('Failed to fetch film list:', error);
});

4.1async 和await写法

async function load(){
  let res=await axios.get('http://192.168.1.108:8000/film/')
  Object.assign(dataList,res.data)
}
load()

【五】 promise语法

1.所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

2.Promise对象代表一个异步操作,有三种状态:`Pending`(进行中)、`Resolved`(已完成,又称 Fulfilled)和`Rejected`(已失败)

# 生活中案例
你跟你女朋友说,5年后等我赚够500w就结婚--》定义函数

    ​ -1 进行中(努力赚钱,其他代码继续执行)
    ​ -2 成功(赚够500w---》结婚)
    ​ -3 失败(没赚够---》分手)

5.1基本使用

"""promise.then()有两个参数,分别是成功的函数和失败的,这个函数的参数是我们在实例化Promise对象是调用resolve或者reject所传的参数,执行成功函数和失败函数,就相当于阻塞了,可以去执行其他的"""
<script setup>
let promise=new Promise(function (resolve,reject){
  console.log("在执行 Promise 了")
//  执行成功函数和失败函数,就相当于阻塞了,可以去执行其他的
//   resolve("赚够五百万了")
  reject("没赚够")
})
console.log("我在promise后面")
//这个value接的是resolve所传的参数,error是reject所传的参数
promise.then(function (value){
  console.log(value)
},function (error){
  console.log(error)
})
console.log("我在最末尾")
</script>


"""
打印结果
在执行 Promise 了
PromiseView.vue:12 我在promise后面
PromiseView.vue:19 我在最末尾
PromiseView.vue:17 没赚够
"""

5.2catch 情况

catch就是捕获异常,有异常就走catch里的函数
<script setup>
let promise=new Promise(function (resolve,reject){
  console.log("在执行 Promise 了")
  throw new Error("我半路变成GGbONG~")
})
console.log("我在promise后面")
promise.then(function (value){
  console.log(value)
},function (error){
  console.log(error)
}).catch(
        function(exception){console.log(exception)}
    )
console.log("我在最末尾")
</script>


"""
在执行 Promise 了
PromiseView.vue:13 我在promise后面
PromiseView.vue:22 我在最末尾
PromiseView.vue:18 Error: 我半路变成GGbONG~
"""

5.3async使用

#写法1和上面的思路差不多
async function fun1() {
  let promise = new Promise(function (resolve, reject) {
        console.log("在执行 Promise 了")
        resolve("赚够五百万了")
      }
  )
  return promise
}

let promise = fun1()
promise.then(function (value) {
  console.log(value)
}).catch(function (exception) {
  console.log(exception)
})

#写法二直接调用promise类的resolve或reject方法然后后续一样
async function fun1(){
    //return 10   // 成功状态,走then
    //throw new Error("异常状态,走catch")
    //let promise = Promise.resolve("成功状态,走then")
    let promise = Promise.reject("失败状态,走catch")
    return promise
}

let promise =fun1()

promise.then(
    function(value){
        console.log("success:"+value)
    }
).catch(
    function(value){
        console.log("fail:"+value)
    }
)

5.4async+await使用

	1. await右侧的表达式一般为一个promise对象,但是也可以是一个其他值
    2. 如果表达式是promise对象,await返回的是promise成功的值
    3. await会等右边的promise对象执行结束,然后再获取结果,后续代码也会等待await的执行
    4. 如果表达式是其他值,则直接返回该值
    5. await必须在async函数中,但是async函数中可以没有await
    6. 如果await右边的promise失败了,就会抛出异常,可以通过 try ... catch捕获处理

#写法1 
    async function fun1() {
    let promise =await Promise.resolve("赚够五百万了")
  return promise
}

let promise = fun1()
promise.then(function (value) {
  console.log(value)
}).catch(function (exception) {
  console.log(exception)
})
#写法2
async function fun1() {
  console.log("我在进来fun1了")
  return 10

}

async function fun2() {
  try {
    console.log("我在进来fun2了")
    let res = await fun1()
    console.log("我在调用fun1后")

  } catch (e) {
    console.log("catch got:" + e)
  }

}

console.log("我在调用fun2前")
fun2()
console.log("我在调用fun2后")

        
        """
        执行结果:
        我在调用fun2前
        我在进来fun2了
        我在进来fun1了
        我在调用fun2后
        我在调用fun1后
        """

【六】vue-router

6.1路由跳转

1.之前是 this.$route   this.$router

2.现在没有this这个东西了,没有就导入
import {useRouter, useRoute} from 'vue-router'

3.
注意导入后要实例化
let router=useRouter()
let route=useRoute()
用的时候
router.push('')


"""
Vue.use(VueRouter) 是Vue的插件安装方法,用于在Vue应用中全局安装Vue Router插件。
useRouter(在Vue 3的Composition API中)是Vue Router提供的函数,用于在组件的setup函数中访问router实例。
"""
在全局的地方用安装插件的方式,在组件这种局部使用实例化的方式

6.2前置路由守卫

1.注意在vue3中实例化createRouter,和vue2不一样
2.然后直接写路由守卫就行
import { createRouter, createWebHistory } from 'vue-router';

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
});

router.beforeEach((to, from, next) => {
    if (to.name === 'login' || to.name === 'register') {
        next();
    } else {
        let token = cookies.get('token');
        if (token) {
            next();
        } else {
            ElMessage.error('您没有登录,请先登录');
            next({ name: 'login' });
        }
    }
});

6.3组件中如何写路由跳转

import router from "@/router";
 router.push({
        path: '/user',
        query: {loginuser: response.data.username, loginuser_id: response.data.user_id}
      })

【七】pinia

# 状态管理器
npm install pinia -S


"""
1.注意action中的方法可以直接这么写那么getter中的不行要在组件中调用函数然后改值
2.可以有多个状态管理器的文件,但是他们的id必须唯一,store文件可以有多个,
"""

7.1基本使用

<template>
  <div>
    <p>User: {{ store.username }}</p>
    <p>age: {{ store.age }}</p>
    <p>hobby: {{ store.hobbies }}</p>
    <button @click="addage">年龄加1</button>
<!--    action中的方法可以直接这么写那么getter中的不行要在组件中调用函数然后改值-->
    <button @click="store.doubleAge">doubleAge</button>
  </div>

  <h1>vuex</h1>
  <p>{{ count }}</p>
  <button @click="increment">Increment</button>
</template>

<script setup>
import { computed } from 'vue';
import { useUserStore } from '../store/useUserStore';
import { useStore } from 'vuex';
let store = useUserStore();
const addage=()=>{
  store.age=store.getAge
}
#vuex
 const storevuex = useStore();

    const count = computed(() => storevuex.state.count);
    const increment = () => storevuex.commit('increment');
</script>

7.2vuex的js文件

// src/store/index.js
import { createStore } from 'vuex';

export default createStore({
  state() {
    return {
      count: 0
    };
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    incrementIfOddOnRootSum({ state, commit, rootState }) {
      if ((state.count + rootState.otherCount) % 2 === 1) {
        commit('increment');
      }
    }
  },
  getters: {
    doubleCount: (state) => state.count * 2
  },
  modules: {
    // 模块化的store
  }
});

7.3pinia的js文件

// src/stores/useUserStore.js
import { defineStore } from 'pinia';
//这个id必须唯一,store文件可以有多个
export const useUserStore = defineStore('user',    {
        id: 'storePinia', //必须唯一
        state: () => { // state中用于定义数据
            return {
                username: '张三',
                age: 3,
                hobbies: ['唱歌', '跳舞']
            }
        },
        getters: {// 用于定义一些通过数据计算而得到结果的一些方法 一般在此处不做对数据的修改操作
            // getters中的方法可以当做属性值方式使用
            getHobbiesCount() {
                return this.hobbies.length
            },
            getAge() {
                return this.age+1
            }
        },
        actions: { // 用于定义一些对数据修改的方法
            doubleAge() {
                this.age = this.age * 2
            }
        }
    }
)

【八】elementui-plus

# 安装
npm install element-plus -S

# 使用main.js
import {createApp} from 'vue'
import './style.css'
import App from './App.vue'
import router from "./router";


// 导pinia
import {createPinia} from 'pinia'
// 创建pinia对象
let pinia = createPinia()


import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

createApp(App).use(router).use(pinia).use(ElementPlus).mount('#app')


# 复制粘贴即可
https://element-plus.org/zh-CN/component/popover.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值