您的位置:首页 > 文旅 > 旅游 > 腾讯云网站搭建教程_短视频创作平台_柏乡seo快排优化_在线咨询 1 网站宣传

腾讯云网站搭建教程_短视频创作平台_柏乡seo快排优化_在线咨询 1 网站宣传

2024/12/23 9:05:10 来源:https://blog.csdn.net/2301_76534754/article/details/142377357  浏览:    关键词:腾讯云网站搭建教程_短视频创作平台_柏乡seo快排优化_在线咨询 1 网站宣传
腾讯云网站搭建教程_短视频创作平台_柏乡seo快排优化_在线咨询 1 网站宣传

7.1 全局组件

App.vue

<template><div><h2>我是父组件,下面是全局组件的内容</h2><HelloWorld></HelloWorld></div>
</template>
​
<script setup>
​
</script>
<style scoped></style>

全局组件HelloWorld.vue

<template><div><h2>我是全局组件</h2></div>
</template>
​
<script setup>
​
</script>
<style scoped></style>

main.js

// createApp是一个工厂函数
import {createApp
} from 'vue'
import './style.css'
​
​
import App from './App.vue'
let app = createApp(App)
​
// 注册全局组件
import HelloWorld from './components/HelloWorld.vue'
app.component('HelloWorld', HelloWorld)
​
app.mount('#app')
​
// 另一种写法
// createApp(App).mount('#app')

7.2 全局自定义指令

App.vue

<template><div><button v-has="{ color: '#f60', text: '全局自定义指令' }">{{ btn }}</button></div>
</template>
​
<script setup>
import { ref } from "vue";
​
let btn = ref('按钮')
</script>
​
<style scoped></style>
​

main.js

// createApp是一个工厂函数
import {createApp
} from 'vue'
import './style.css'
​
​
import App from './App.vue'
let app = createApp(App)
​
// 注册全局组件
import HelloWorld from './components/HelloWorld.vue'
app.component('HelloWorld', HelloWorld)
// 全局自定义指令
// 写法1:
// app.directive('has', {
//  beforeMount(el, binding) {
​
//  },
//  mounted(el, binding) {
//      el.innerHTML = binding.value.text
//      el.style.color=binding.value.color
//  }
// })
// 写法2:
app.directive('has', function (el, binding) {el.innerHTML = binding.value.textel.style.color = binding.value.color
})
​
app.mount('#app')
​
// 另一种写法
// createApp(App).mount('#app')

7.3 路由

router->index.js

import { createRouter, createWebHashHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
// import AboutView from '../views/AboutView'  下面用了懒加载方法,所以这里注释掉
​
// 定义一些路由
// 每个路由都需要映射到一个组件
const routes = [{name: 'home',path: '/',component: HomeView
​},{name: 'about',path: '/about/:name/:age',  // '/about'这个前缀代表了不同的模块或功能区域,避免路由名称冲突component: () => import('../views/AboutView.vue')   // 路由懒加载
​},
]
​
// 3. 创建路由实例并传递 `routes` 配置
// 你可以在这里输入更多的配置,但我们在这里
// 暂时保持简单
const router = createRouter({// 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。history: createWebHashHistory(),routes, // `routes: routes` 的缩写
})
​
export default router

main.js

// 导入
import router from './router'
// router是插件,需要use才能用
app.use(router).mount('#app')

App.vue

<template><div><!-- 写法1: --><!-- <router-view></router-view> --><!-- 写法2: --><RouterView></RouterView><!-- 点击按钮后将本路由数据传给AboutView.vue路由,展示在页面上 --><button @click="goHome">home</button><button @click="goAbout">about</button></div>
</template>
​
<script setup>
import { reactive } from 'vue';
import { useRoute, useRouter } from 'vue-router';
​
let info = reactive({name: 'haha',work: {job: 'xi',age: 27}
})
const router = useRouter()  //解构出来
​
let goHome = () => {router.push('/')
}
let goAbout = () => {router.push(// query传参// {//  path: '/about',//  query: {//      age: info.work.age,//      name: info.name//  }// }// params传参{name: 'about',params: {name: info.name,age: info.work.age}})
}
​
​
</script>
​
<style scoped></style>
​

AboutView.vue

<template><div><h2>AboutView</h2><!-- <h2>{{ route }}</h2> --><!-- <h2>{{ $route }}</h2> --><!-- App.vue路由传过来的数据 --><!-- <h2>{{ $route.query.age }}</h2> --><!-- <h2>{{ $route.query.name }}</h2> --><h2>{{ $route.params.name }}</h2><h2>{{ $route.params.age }}</h2></div>
</template>
​
<script setup>
import { ref, reactive, toRefs, onMounted } from 'vue'
import { useRoute } from 'vue-router';
const route = useRoute()
console.log(route.params);
​
​
</script>
<style scoped lang="less"></style>

HomeView.vue

<template><div><h2>HomeView</h2></div>
</template>
​
<script setup>
import { ref, reactive, toRefs, onMounted} from 'vue'
​
</script>
<style scoped>
</style>

7.4 动画

<template><div><button @click="show = !show">电我吧</button><transition name="fade"><p v-show="show" :style="styleobj">看我变身</p></transition></div>
</template>
​
<script setup>
import { reactive, ref } from 'vue';
let show = ref(true)
let styleobj = reactive({fontSize: '30px',color: 'red'
})
​
</script>
​
<style scoped>
.fade-enter-active,
.fade-leave-active {transition: opacity 2s;
}
/* vue3这里的fade-enter后面加了一个from,比vue2的动画离开效果更生动了  */
.fade-enter-from,
.fade-leave-to {opacity: 0;
}
</style>
 

7.5 pinia

Pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。pinia和Vuex的作用是一样的,它也充当的是一个存储数据的作用,存储在pinia的数据允许我们在各个组件中使用

优点:

  • Vue2和Vue3都支持,这让我们同时使用Vue2和Vue3的小伙伴都能很快上手。

  • pinia中只有state、getter、action,抛弃了Vuex中的Mutation,Vuex中mutation一直都不太受小伙伴们的待见,pinia直接抛弃它了,这无疑减少了我们工作量。

  • pinia中action支持同步和异步,Vuex不支持

  • 良好的Typescript支持,毕竟我们Vue3都推荐使用TS来编写,这个时候使用pinia就非常合适了

  • 无需再创建各个模块嵌套了,Vuex中如果数据过多,我们通常分模块来进行管理,稍显麻烦,而pinia中每个store都是独立的,互相不影响。

  • 体积非常小,只有1KB左右。

  • pinia支持插件来扩展自身功能。

  • 支持服务端渲染。

pinia的使用

  1. 安装

    pnpm install pinia

    安装完成后我们需要将pinia挂载到Vue应用中,也就是我们需要创建一个根存储传递给应用程序,简单来说就是创建一个存储数据的数据桶,放到应用程序中去。

    修改main.js,引入pinia提供的createPinia方法,创建根存储。

    import { createPinia } from "pinia";
    const pinia = createPinia();
    app.use(pinia).mount('#app')

  2. 创建store

    可以理解为一个公共组件,只不过该公共组件只存放数据,这些数据我们其它所有的组件都能够访问且可以修改,使用pinia提供的defineStore()方法来创建一个store,该store用来存放我们需要全局使用的数据,首先在项目src目录下新建store文件夹,用来存放我们创建的各种store,然后在该目录下新建user.js文件,主要用来存放与user相关的store。

    defineStore函数,接收两个参数:

  • name:一个字符串,必传项,该store的唯一id。

  • options:一个对象,store的配置项,比如配置store内的数据,修改数据的方法等等。

我们可以定义任意数量的store,因为一个store就是一个函数,这也是pinia的好处之一,让我们的代码扁平化了,这和Vue3的实现思想是一样的。

user.js

  import { defineStore } from 'pinia'// 第一个参数是应用程序中 store 的唯一 idexport const useUsersStore = defineStore('users', {// 其它配置项})
  1. 使用store

    使用store很简单,直接引入我们声明的useUsersStore 方法即可

    App.vue

    <template></template>
    ​
    <script setup>
    import { useUsersStore } from "../src/store/user";
    const store = useUsersStore();
    console.log(store);
    ​
    </script>
    ​
    <style scoped>
    ​
    </style>
    ​

  2. 添加state

    前面我们利用defineStore函数创建了一个store,该函数第二个参数是一个options配置项,我们需要存放的数据就放在options对象中的state属性内。

    user.js

    export const useUsersStore = defineStore("users", {state: () => {return {name: "小猪课堂",age: 25,sex: "男",};},
    });

    上段代码中我们给配置项添加了state属性,该属性就是用来存储数据的,我们往state中添加了3条数据。需要注意的是,state接收的是一个箭头函数返回的值,它不能直接接收一个对象

  3. 操作state

    1. 读取state数据

      App.vue

      <template><p>姓名:{{ name }}</p><p>年龄:{{ age }}</p><p>性别:{{ sex }}</p>
      </template>
      ​
      <script setup>
      import {ref} from 'vue'
      import { useUsersStore } from "../src/store/user";
      const store = useUsersStore();
      console.log(store);
      ​
      const name = ref(store.name);
      const age = ref(store.age);
      const sex = ref(store.sex);
      ​
      </script>
      ​
      <style scoped>
      ​
      </style>

      简单方法:用解构的方法获取数据

      App.vue

      import { useUsersStore } from "../src/store/user";
      const store = useUsersStore();
      const { name, age, sex } = store;

    2. 多个组件使用state

      接下来我们新建一个child.vue组件,在该组件内部也使用state数据

      components->child.vue

      <template><h1>我是child组件</h1><p>姓名:{{ name }}</p><p>年龄:{{ age }}</p><p>性别:{{ sex }}</p>
      </template>
      ​
      <script setup>
      import { ref, reactive, toRefs, onMounted } from 'vue'
      import { useUsersStore } from "../store/user";
      const store = useUsersStore();
      const { name, age, sex } = store;
      </script>
      <style scoped></style>

      App.vue

      <child></child>
      import child from './components/child.vue'

      这样我们就实现了多个组件同时使用store中的数据

    3. 修改state数据

      如果我们想要修改store中的数据,可以直接重新赋值即可,我们在App.vue里面添加一个按钮,点击按钮修改store中的某一个数据

      App.vue

      <button @click="changeName">更改姓名</button>
      const changeName = () => {store.name = "张三";console.log(store);
      };

      我们可以看到store中的name确实被修改了,但是页面上似乎没有变化,这说明我们的使用的name不是响应式的。

      很多小伙伴可能会说那可以用监听函数啊,监听store变化,刷新页面...

      其实,pinia提供了方法给我们,让我们获得的name等属性变为响应式的,我们重新修改代码。

      利用pinia的storeToRefs函数,将sstate中的数据变为了响应式的

      App.vue

      import { storeToRefs } from 'pinia';
      // 响应式
      const { name, age, sex } = storeToRefs(store);
      child.vueimport { storeToRefs } from 'pinia';
      // 响应式
      const { name, age, sex } = storeToRefs(store);

    4. 重置state

      有时候我们修改了state数据,想要将它还原,此时,我们直接调用store的$reset()方法即可,继续使用我们的例子,添加一个重置按钮

      <button @click="reset">重置store</button>
      // 重置store
      const reset = () => {store.$reset();
      };

    5. 批量更改state数据

      一次性需要修改很多条数据的话,有更加简便的方法,使用store的$patch方法,修改app.vue代码,添加一个批量更改数据的方法

      <button @click="patchStore">批量修改数据</button>
      // 批量修改数据
      const patchStore = () => {store.$patch({name: "张三",age: 100,sex: "女",});
      };

      假如我们state中有些字段无需更改,但是按照上段代码的写法,我们必须要将state中的所有字段例举出了。

      为了解决该问题,pinia提供的$patch方法还可以接收一个回调函数,它的用法有点像我们的数组循环回调函数了

      App.vue

      // 修改单个数据
      const patchStore = () => {store.$patch((state) => {state.name='haha'state.hasChanged = true})
      };

  4. getters属性

    getters是defineStore参数配置项里面的另一个属性,前面我们讲了state属性。getter属性值是一个对象,该对象里面是各种各样的方法。大家可以把getter想象成Vue中的计算属性,它的作用就是返回一个新的结果,既然它和Vue中的计算属性类似,那么它肯定也是会被缓存的,就和computed一样

    1. 添加getter

      user.js

      // 第一个参数是应用程序中 store 的唯一 id
      export const useUsersStore = defineStore('users', {// 其它配置项state: () => {return {name: "小猪课堂",age: 25,sex: "男",};},getters: {getAddAge: (state) => {return state.age + 100;},},
      })

      我们在配置项参数中添加了getter属性,该属性对象中定义了一个getAddAge方法,该方法会默认接收一个state参数,也就是state对象,然后该方法返回的是一个新的数据

    2. 使用getter

      <template><p>新年龄:{{ store.getAddAge }}</p><button @click="patchStore">批量修改数据</button>
      </template>
      <script setup lang="ts">
      import { useUsersStore } from "../src/store/user";
      const store = useUsersStore();
      // 批量修改数据
      const patchStore = () => {store.$patch({name: "张三",age: 100,sex: "女",});
      };
      </script>

      上段代码中我们直接在标签上使用了store.gettAddAge方法,这样可以保证响应式,其实我们state中的name等属性也可以以此种方式直接在标签上使用,也可以保持响应式。

      当我们点击批量修改数据按钮时,页面上的新年龄字段也会跟着变化

    3. getter中调用其他getter

      有时候我们需要在这一个getter方法中调用其它getter方法,其实很简单,我们可以直接在getter方法中调用this,this指向的便是store实例,所以理所当然的能够调用到其它getter。

      getters: {getAddAge: (state) => {return state.age + 100;},getNameAndAge(): string {return this.name + this.getAddAge; // 调用其它getter},},

      上段代码中我们又定义了一个名为getNameAndAge的getter函数,在函数内部直接使用了this来获取state数据以及调用其它getter函数。

      细心的小伙伴可能会发现我们这里没有使用箭头函数的形式,这是因为我们在函数内部使用了this,箭头函数的this指向问题相信大家都知道吧!所以这里我们没有采用箭头函数的形式。

      组件中

      <p>调用其它getter:{{ store.getNameAndAge }}</p>

    4. getter传参

      getAddAge: (state) => {return (num) => state.age + num;},

      上段代码中我们getter函数getAddAge接收了一个参数num,这种写法其实有点闭包的概念在里面了,相当于我们整体返回了一个新的函数,并且将state传入了新的函数。

      组件中

       <p>新年龄:{{ store.getAddAge(1100) }}</p>

  5. actions属性

    前面我们提到的state和getters属性都主要是数据层面的,并没有具体的业务逻辑代码,它们两个就和我们组件代码中的data数据和computed计算属性一样。

    那么,如果我们有业务代码的话,最好就是卸载actions属性里面,该属性就和我们组件代码中的methods相似,用来放置一些处理业务逻辑的方法。

    actions属性值同样是一个对象,该对象里面也是存储的各种各样的方法,包括同步方法和异步方法。

    1. 添加actions

       actions: {saveName(name: string) {this.name = name;},},

      上段代码中我们定义了一个非常简单的actions方法,在实际场景中,该方法可以是任何逻辑,比如发送请求、存储token等等。大家把actions方法当作一个普通的方法即可,特殊之处在于该方法内部的this指向的是当前store。

    2. 使用actions

      <button @click="saveName">actions修改数据的方法</button>
      const saveName = () => {store.saveName("我是小猪");
      };

      pinia内容借鉴保姆级教程:https://zhuanlan.zhihu.com/p/533233367

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com