前端 – web百事通 https://www.askme-121.pw web互联网之家 Mon, 18 Mar 2024 06:59:14 +0000 zh-CN hourly 1 https://wordpress.org/?v=6.5.3 https://www.askme-121.pw/wp-content/uploads/2023/12/cropped-05ee702f-4b38-40f3-915f-c8fc68b10a91-32x32.png 前端 – web百事通 https://www.askme-121.pw 32 32 app开发框架有哪些 https://www.askme-121.pw/app/ https://www.askme-121.pw/app/#respond Mon, 18 Mar 2024 06:59:01 +0000 https://www.askme-121.pw/?p=514 APP开发框架是指在移动应用程序开发中,为了提高开发效率、降低开发成本和提高代码质量而使用的软件架构体系。下面将介绍一些常用的APP开发框架。

1. React Native

React Native是由Facebook开发的一种基于React的开源框架。它允许开发者使用JavaScript和React来构建原生移动应用程序。React Native可以让开发者快速构建高性能的移动应用程序,并且可以在不同平台上使用相同的代码。React Native通过使用原生组件来实现高性能,从而提高了应用程序的性能和响应能力。

2. Flutter

Flutter是Google开发的一种开源框架,它可以用于构建高性能的移动应用程序。Flutter使用Dart语言来编写代码,并且可以在iOS和Android平台上使用相同的代码。Flutter具有快速的开发周期、高质量的用户界面和出色的性能。Flutter使用自己的渲染引擎来实现高性能,从而提高了应用程序的性能和响应能力。

3. Ionic

Ionic是一个基于HTML5和CSS3的开源框架,可以用于构建跨平台的移动应用程序。Ionic使用AngularJS来构建应用程序,并且可以在不同平台上使用相同的代码。Ionic提供了大量的UI组件和工具来帮助开发者更快地构建应用程序。Ionic使用自己的渲染引擎来实现高性能,从而提高了应用程序的性能和响应能力。

4. Xamarin

Xamarin是由Microsoft开发的一种跨平台移动应用程序开发框架。它允许开发者使用C#和.NET框架来构建原生移动应用程序。Xamarin可以在iOS、Android和Windows Phone平台上使用相同的代码。Xamarin使用自己的渲染引擎来实现高性能,从而提高了应用程序的性能和响应能力。

5. PhoneGap

PhoneGap是一个基于HTML、CSS和JavaScript的开源框架,可以用于构建跨平台的移动应用程序。PhoneGap使用Web技术来构建应用程序,并且可以在不同平台上使用相同的代码。PhoneGap使用自己的渲染引擎来实现高性能,从而提高了应用程序的性能和响应能力。

以上是一些常用的APP开发框架,每个框架都有自己的特点和适用范围。选择一个适合自己的框架可以提高开发效率和代码质量,从而更快地构建高性能的移动应用程序。

]]>
https://www.askme-121.pw/app/feed/ 0
uniapp中easycom用法详解 https://www.askme-121.pw/uniapp-easycom/ https://www.askme-121.pw/uniapp-easycom/#respond Sun, 17 Mar 2024 06:45:19 +0000 https://www.askme-121.pw/?p=513 Uniapp中的easycom是一种组件自动注册机制,可以让开发者更加方便地使用和管理组件。下面详细介绍下关于easycom使用方法。

什么是easycom

easycom是Uniapp框架提供的一种组件自动注册机制,它可以自动扫描指定目录下的所有组件,并注册到全局组件中。这意味着我们无需手动在components中引入组件,也无需在每个页面中单独引入组件,只需要在组件的目录下创建一个index.vue文件,就可以自动注册组件并在全局中使用了。

如何使用easycom?

使用easycom非常简单,只需要在项目根目录下的pages.json中配置easycom属性即可。例如:

{
  "easycom": {
    "autoscan": true,
    "custom": {
      "^cu-": "@/components/cu/"
    }
  }
}

其中,autoscan表示是否启用自动扫描功能,如果设置为true,则会自动扫描项目中所有符合规则的组件并注册到全局中。如果设置为false,则需要手动在components中引入组件。

custom是自定义规则,可以根据规则自动注册组件。例如上面的例子中,以cu-开头的组件会被自动注册到@/components/cu/目录下。

除了在pages.json中配置easycom属性外,还可以在单个页面的json文件中配置usingComponents属性来引用组件。例如:

{
  "usingComponents": {
    "cu-btn": "@/components/cu-btn/index"
  }
}

上面的例子中,cu-btn组件会被自动引入到当前页面中,无需手动在components中引入。

easycom的规则

easycom支持多种规则,可以自定义组件的目录和组件名。以下是常见的规则:

  • 目录规则:将组件放在components目录下,文件名为index.vue,则组件会自动注册到全局中。例如:components/my-component/index.vue会被自动注册为my-component组件。
  • 前缀规则:将组件放在任意目录下,文件名为index.vue,文件名以指定前缀开头,例如my-,则组件会自动注册到全局中。例如:components/my-component/index.vue会被自动注册为my-component组件。
  • 全路径规则:将组件放在任意目录下,文件名为index.vue,则可以在页面中使用全路径来引用组件,例如:@/components/my-component/index

easycom的注意事项

虽然easycom提供了方便的组件自动注册机制,但在使用easycom时,也有一些需要注意的事项:

  1. 组件命名必须是小写字母,使用短横线连接单词。例如:my-component
  2. 不同平台的组件可能有不同的实现方式,因此需要在pages.json中配置easycom属性时,需要根据平台分别配置。例如:
    {
    "easycom": {
    “nvue”: {
    “autoscan” true
    } ,
    “h5”: {
    “autoscan”: true
    }
    }
    }
  3.  如果有一些组件不需要自动注册,可以在组件目录下创建一个.easycomignore文件来忽略该组件的自动注册。例如:
    # 忽略my-component组件
    my-component/

    如果需要忽略某个目录下的所有组件,可以在.easycomignore文件中输入目录名即可。
  4. 如果需要自定义规则,可以在pages.json中配置custom属性。例如:
    {
    "easycom": {
    “autoscan”: true,
    “custom”: {
    “^my-“: “@/components/my/”
    }
    }
    }

    上面的例子中,以my-开头的组件会被自动注册到@/components/my/目录下。
  5. 如果需要在某个页面中引用组件,可以在页面的json文件中配置usingComponents属性。例如:
    { "usingComponents": { "my-component": "@/components/my-component/index" } }
    上面的例子中,my-component组件会被自动引入到当前页面中。

总的来说,easycom是Uniapp框架中非常方便的组件自动注册机制,可以大大简化组件的使用和管理。但是在使用时需要注意一些规则和注意事项,以保证组件能够正常注册和使用。

]]>
https://www.askme-121.pw/uniapp-easycom/feed/ 0
vue选项式vs组合式 https://www.askme-121.pw/vue-options-vs-composables/ https://www.askme-121.pw/vue-options-vs-composables/#respond Sun, 17 Mar 2024 05:54:18 +0000 https://www.askme-121.pw/?p=510 Vue中的选项式API和组合式API是两种不同的编写组件逻辑的方式。

选项式API(Options API):

  • 基于对象(data、methods、computed、watch等)的API。
  • 每个组件的选项是集中在一个地方的。
  • 可能会导致组件变得庞大而复杂。
// 选项式API示例
Vue.component('my-component', {
  data() {
    return {
      message: 'Hello, Vue!'
    };
  },
  methods: {
    updateMessage() {
      this.message = 'Updated message';
    }
  },
  template: '<div>{{ message }}</div>'
});

组合式API(Composition API):

  • 基于函数的API,使用setup函数。
  • 使用函数组合而非类继承。
  • 可以更灵活地使用Vue的响应式系统和其他API。
  • 需要Vue 3.x。
// 组合式API示例
Vue.component('my-component', {
  setup() {
    const message = Vue.ref('Hello, Vue!');
 
    function updateMessage() {
      message.value = 'Updated message';
    }
 
    return { message, updateMessage };
  },
  template: '<div>{{ message }} <button @click="updateMessage">Update</button></div>'
});

选项式API更适合于旧版Vue 2.x,而组合式API则是Vue 3.x推出的一个新特性,旨在提供更简洁、更易于理解的方式来组织组件逻辑。

伴随着新到的vue3,我们编写组件的书写方式也发生了变化。
除了底层的更新,编写方式的改变或许才是我们最能直观感受到的。

其实就是vue3多了一种名为组合式api(composables api)的写法,相对应传统的选项式api(options api)
组合式api简单来说就是使用setup方式编写组件。

传统的选项式api

来看看这种传统的写法:65行

<template>
  <div class="home" v-if="userInfo">
    <my-header/>
    用户详情:{{fullUname}},{{userInfo.age}}岁
  </div>
</template>
<script>
import MyHeader from '../components/my-header.vue';

export default {
  // 组件:公共头部
  components: { MyHeader },

  // 属性: 接受属性用户id
  props: {
    userId: {
      type: String,
      default: '2022-01-01'
    }
  },

  // 状态:用户信息
  data() {
    return {
      userInfo: null
    }
  },

  // 计算属性:给用户名加一个牛逼的前缀
  computed: {
    fullUname() {
      if(this.userInfo && this.userInfo.name){
        return '牛逼的' + this.userInfo.name;
      }
      return ''
    }
  },

  // 监听:用户id改变
  watch: {
    userId: {
      handler(newVal, oldVal) {
        console.log('用户id变化啦:'+newVal);
      },
      immediate: true
    }
  },

  // 方法:同步用户信息
  methods: {
    syncUserInfo(userId) {
      this.userInfo = {
        id: userId,
        name: '小明',
        age: 20
      };
    }
  },

  // 钩子:初始化
  mounted() {
    this.syncUserInfo(this.userId)
  }
}
</script>

先进的组合式api

来看看这种先进的写法:48行

<template>
  <div class="home" v-if="userInfo">
    <my-header />
    用户详情:{{ fullUname }},{{ userInfo.age }}岁
  </div>
</template>
<script setup>// <script setup> 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。
import { ref, onMounted, watch, computed } from 'vue';
import MyHeader from '../components/my-header.vue';

// 属性: 接受属性用户id
const props = defineProps({
  userId: {
    type: String,
    default: '2022-01-01'
  }
})

// 状态:用户信息
const userInfo = ref(null);

// 计算属性:给用户名加一个牛逼的前缀
const fullUname = computed(() => {
  if (userInfo.value && userInfo.value.name) {
    return '牛逼的' + userInfo.value.name;
  }
  return ''
})

// 监听:用户id改变
watch((newVal, oldVal) => {
  console.log('用户id变化啦:' + newVal);
}, { immediate: true })

// 方法:同步用户信息
const syncUserInfo = (userId) => {
  userInfo.value = {
    id: userId,
    name: '小明',
    age: 20
  };
}

// 钩子:初始化
onMounted(() => {
  syncUserInfo(props.userId)
})
</script>
]]>
https://www.askme-121.pw/vue-options-vs-composables/feed/ 0
Vue中配置使用process.env详解 https://www.askme-121.pw/vue-process-env/ https://www.askme-121.pw/vue-process-env/#respond Thu, 07 Mar 2024 12:13:05 +0000 https://www.askme-121.pw/?p=507 process是 nodejs 下的一个全局变量,它存储着 nodejs 中进程有关的信息。process.env 是 Node.js 中的一个环境对象,其中保存着系统的环境的变量信息,可使用 Node.js 命令行工具直接进行查看。

而 NODE_ENV 就是其中的一个环境变量。这个变量主要用于标识当前的环境(生产环境,开发环境)。默认是没有这个环境变量的,需要自己手动配置。不同系统有不同的环境变量配置方式,在这里就不多加赘述。

NODE_ENV 变量只能在系统中配置吗?其实不然。在 Vue 项目中, Vue 提供了自己的配置方式。这就要涉及到 Vue CLI 中模式的概念了。 Vue CLI 文档说明了这个问题。

也就是说,在 Vue 中, NODE_ENV 可以通过 .env 文件或者 .env.[mode] 文件配置。配置过后,运行 Vue CLI 指令( npm run dev(serve) ,npm run build )时,就会将该模式下的NODE_ENV载入其中了。而这些命令,都有自己的默认模式:

  • npm run dev(serve) ,其实是运行了 vue-cli service serve ,默认模式为 development 。可以在 .env.development 文件下修改该模式的 NODE_ENV 。
  • npm run build ,其实运行了 vue-cli service build ,默认模式为 production 。可以在 .env.production 文件下修改该模式的 NODE_ENV 。

除了以上的修改方式外,也可以在命令后直接使用 –mode 参数手动指定模式。当然,每个模式配置的变量也不只有 NODE_ENV , 也可以通过配置其他的变量简化工作流程。

模式的应用

有了模式的概念,就可以根据不同的环境配置模式,就不用每次打包时都去更改 vue.config.js 文件了。比如在测试环境和生产环境, publicPath参数 (部署应用包时的基本 URL) 可能不同。遇到这种情况就可以在 vue.config.js 文件中,将 publicPath 参数设置为:publicPath: process.env.BASE_URL
设置之后,再在各个 .env.[mode] 文件下对 BASE_URL 进行配置就行了,这样就避免了每次修改配置文件的尴尬。其他的配置也是同理。
Tips: 即使不是生产环境,也可以将模式设置为 production ,这样可以获得 webpack 默认的打包优化。

process.env使用

1、在nodejs中使用

1、安装

npm install dotenv

2、根目录下创建 .env 文件

HOST = localhost
PORT = 8080

3、入口文件中引入 dotenv 并使用

require("dotenv").config({path: '.env'})
console.log(process.env.HOST); // localhost
console.log(process.env.PORT); // 8080

2、在vue中使用

在使用脚手架创建项目的时候,会自动安装dotenv,可以从package-lock.json中找到配置。在main.js入口文件中打印console.log(process.env);可以看出,默认的模式是development即开发模式。

也就是说,在Vue中, NODE_ENV 可以通过 .env 文件或者.env.[mode]文件配置。配置过后,运行 Vue CLI 指令( npm run dev(serve) ,npm run build )时,就会将该模式下的NODE_ENV载入其中了。而这些命令,都有自己的默认模式:

  • npm run dev(serve) ,其实是运行了 vue-cli service serve ,默认模式为 development 。可以在 .env.development 文件下修改该模式的 NODE_ENV 。
  • npm run build ,其实运行了 vue-cli service build ,默认模式为 production 。可以在 .env.production 文件下修改该模式的 NODE_ENV 。

注意:只有 NODE_ENVBASE_URL 和以 VUE_APP_ 开头的变量将通过 webpack.DefinePlugin 静态地嵌入到客户端侧的代码中。这是为了避免意外公开机器上可能具有相同名称的私钥。

NODE_ENV = development
VUE_APP_BASE_API = 'http://localhost:8099/'

注意:.env 环境文件是通过运行 vue-cli-service 命令载入的,因此环境文件发生变化,你需要重启服务。除了以上的修改方式外,也可以在命令后直接使用--mode参数手动指定模式。

当运行 vue-cli-service 命令时,所有的环境变量都从对应的环境文件中载入。如果文件内部不包含 NODE_ENV 变量,它的值将取决于模式,例如,在 production 模式下被设置为 “production”,在 test 模式下被设置为 “test”,默认则是 “development”。

NODE_ENV 将决定您的应用运行的模式,是开发,生产还是测试,因此也决定了创建哪种 webpack 配置。

例如通过将 NODE_ENV 设置为 “test”,Vue CLI 会创建一个优化过后的,并且旨在用于单元测试的 webpack 配置,它并不会处理图片以及一些对单元测试非必需的其他资源。

同理,NODE_ENV=development 创建一个 webpack 配置,该配置启用热更新,不会对资源进行 hash 也不会打出 vendor bundles,目的是为了在开发的时候能够快速重新构建。

当你运行 vue-cli-service build 命令时,无论你要部署到哪个环境,应该始终把 NODE_ENV 设置为 “production” 来获取可用于部署的应用程序。

示例配置

我们现在有三个配置文件,分别如下:

#.env.development
NODE_ENV=development
VUE_APP_AXIOS_BASEURL=http://xxxx
#.env.preview 测试环境的配置
NODE_ENV=production
VUE_APP_AXIOS_BASEURL=http://xxxx
#.env.production
NODE_ENV=production
VUE_APP_AXIOS_BASEURL=http://xxxx

在 axios 中使用

import axios from "axios";
const conf = {
  baseURL: process.env.VUE_APP_AXIOS_BASEURL,
};
return axios.create(conf);

package.json 配置

{
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build --mode preview",
    "build:release": "vue-cli-service build"
  }
}

启动方式

npm run serve # 默认 dev
npm run build # 测试环境
npm run build:release # 正式环境
]]>
https://www.askme-121.pw/vue-process-env/feed/ 0
uniapp-x uts 介绍 https://www.askme-121.pw/uniapp-x-uts/ https://www.askme-121.pw/uniapp-x-uts/#respond Wed, 06 Mar 2024 12:55:38 +0000 https://www.askme-121.pw/?p=506 uts 是什么

uts,全称 uni type script,是一门跨平台的、高性能的、强类型的现代编程语言。

它可以被编译为不同平台的编程语言,如:

  • web平台,编译为JavaScript
  • Android平台,编译为Kotlin
  • iOS平台,编译Swift

uts 采用了与 ts 基本一致的语法规范,支持绝大部分 ES6 API。但为了跨端,uts进行了一些约束和特定平台的增补。

过去在js引擎下运行支持的语法,大部分在uts的处理下也可以平滑的在kotlin和swift中使用。但有一些无法抹平,需要使用条件编译。和uni-app的条件编译类似,uts也支持条件编译。写在条件编译里的,可以调用平台特有的扩展语法。

用途和关系

uts是一门语言。也仅是一门语言,不包含ui框架。uvue是DCloud提供的跨平台的、基于vue语法的ui框架。uts相当于js,uvue相当于html和css。它们类似于v8和webkit的关系、类似于dart和flutter的关系。

uts这门语言,有2个用途:

  • 开发uni-app 和 uni-app x 的原生扩展插件:因为uts可以调用所有原生能力。
  • uts和uvue一起组合,开发原生级的项目,也就是 uni-app x 项目

uni-app x 开发App时,输出的是纯原生的App(Android上就是kotlin的app),里面没有js引擎和webview。也就是说,uts可以在uni-app中使用,也可以在uni-app x中使用。

在uni-app中,主编程语言是js。uts可以开发原生插件,包括API插件和组件插件。
在uni-app x中,主编程语言是uts。不管是应用逻辑还是扩展插件,均使用uts编程,没有js。

]]>
https://www.askme-121.pw/uniapp-x-uts/feed/ 0
vue组件的is特性 https://www.askme-121.pw/vue-is/ https://www.askme-121.pw/vue-is/#respond Sun, 14 Jan 2024 07:38:45 +0000 https://www.askme-121.pw/?p=494 组件(Component)是Vue.js最强大的功能之一。组件可以扩展HTML元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js的编译器为它添加特殊功能。在有些情况下,组件也可以是原生HTML元素的形式,以is特性扩展。

限制元素

当使用 DOM 作为模板时,你会受到 HTML 本身的一些限制,因为 Vue 只有在浏览器解析、规范化模板之后才能获取其内容。Vue的模板是DOM模板,使用浏览器原生的解析器而不是自己实现一个。相比字符串模板,DOM模板有一些好处,但是也有问题,它必须是有效的HTML片段。一些HTML元素对什么元素可以放在它里面有限制。对内部元素有限制的标签内,放在这些元素内部的自定义标签将被提到元素的外面,因而渲染不正确。

对应自定义元素,应当使用is特性:

<table>
<tr is="my-component"></tr>
</table>

意思就是有些元素,比如 ul 里面只能直接包含 li元素,像这样:

<ul>
    <li></li>
</ul>
//而不能:
<ul>
    <your-component>
</ul>

这样就不能复用your-component这个组件了,如果要达到我们的目的,我们就要使用is特性像这样:

<ul>
    <li is="your-component"></li>
</ul>

动态组件

在我们平时使用vue中的模板的时候,许多时候都是直接定义成一个固定的模板,但是,vue中提供了一个动态模板,可以在任意模板中切换,就是用vue中<component>用:is来挂载不同的组件。

<div id="app" v-cloak>
        <component :is="currentView"></component>
        <button @click="handleChangeView('A')">A</button>
        <button @click="handleChangeView('B')">B</button>
        <button @click="handleChangeView('C')">C</button>
</div>
<script>
var app = new Vue({
            el: '#app',
            components:{
                comA:{
                    template:`
                        <div>组件A</div>
                    `
                },
                comB:{
                    template:`
                        <div>组件B</div>
                    `
                },
                comC:{
                    template:`
                        <div>组件C</div>
                    `
                }
            },
            data:{
                currentView:'comA'
            },
            methods:{
                handleChangeView:function(component){
                    this.currentView='com'+component;
                }
            }
        });
</script>

我们在components中注册了三个模板,当我们点击当前按钮的时候,就会将模板切换模板,可以说是非常方便了。

]]>
https://www.askme-121.pw/vue-is/feed/ 0
vue中的v-for循环 https://www.askme-121.pw/v-for/ https://www.askme-121.pw/v-for/#respond Sun, 14 Jan 2024 05:45:03 +0000 https://www.askme-121.pw/?p=493 1.v-for遍历普通数组

in前面如果是一个变量,那么该变量保存的是数组中的数据in前面如果是两个变量,那么第一个变量保存的是数组中的数据,第二个变量保存的是下标。

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
 
<body>
    <div id="app">
        <!-- 绑定事件 v-on: 简写为@ -->
        <button @click="add">点击在数组最后添加元素</button>
        <ul style="list-style-type: none;">
            <!-- item是数组里面的元素  index是数组的下标 -->
            <li v-for="(item,index) in list">{{index}}-{{item}}</li>
        </ul>
 
    </div>
    <script src="/vue.js"></script>
    <script>
 
        new Vue({
            el: '#app',
            data: {
                list: ['猪方', '战神', '小金子', '楠神']
            },
            methods: {
                add() {
                    this.list.push('黑牛')
                }
            },
        })
    </script>
</body>
 
</html>

2.v-for遍历对象

如果是一个变量,那么保存的是对象中的属性值
如果是两个变量,那么第一个变量保存的是属性值,第二个变量保存的是属性名
如果是三个变量,那么第一个变量保存的是属性值,第二个变量保存的是属性名,第三个变量保存的是下标

v-for=”o1 in obj” o1:属性值
v-for=”(o1,o2) in obj” o1:属性值 o2:属性名
v-for=”(o1,o2,o3) in obj” o1:属性值 o2:属性名 o3:下标

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
 
<body>
    <div id="app">
        <ul>
            <li v-for="item in obj">{{item}}</li>
            <hr>
            <li v-for="(val,key) in obj">{{ key }}-{{ val }}</li>
 
        </ul>
    </div>
 
    <script src="./vue.js"></script>
 
    <script>
        new Vue({
            el: '#app',
            data: {
                obj: {
                    name: '卡拉米',
                    age: 16,
                    sex: '男',
 
                }
            }
        })
    </script>
</body>
 
</html>

3.v-for循环数字

in后面不仅可以放数组、对象数组、对象,还可以放数字
在in前面用一个变量存储当前次数,注意:此变量是从1开始,而不是从0开始

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
 
<body>
    <div id="app">
        <ul style="list-style-type: none;">
            <!-- v-for='遍历的数 in 遍历的范围' -->
            <li v-for="num in 9">{{num}}</li>
        </ul>
    </div>
    <script src="/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
 
        })
 
    </script>
</body>
 
</html>

4. Key是什么?

Key 特殊属性主要用做 Vue 的虚拟 DOM 算法在将新节点列表与旧列表进行比较时识别 VNode 的提示。在没有键的情况下,Vue 使用一种算法来最小化元素移动,并尝试尽可能多地就地修补/重用相同类型的元素。使用键,它将根据键的顺序更改对元素进行重新排序,并且不再存在键的元素将始终被删除/销毁。

有 Key

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!-- @click="list.splice(下标,删除的数量,添加的元素)" -->
        <button @click="list.splice(1,0,{name:'狗屎',age:11,sex:'男',id:4})">点击添加对象</button>
        <ul>
            <li v-for="item in list" :key="item.id">
                <!-- 单选框 -->
                <input type="checkbox">
                <!-- 行内元素 -->
                <span>{{item.name}}</span>
            </li>
        </ul>
    </div>
    <script src="/vue.js"></script>
    <script>
        new Vue({
            el:'#app',
            data:{
                list:[
                    {name:'战神',age:18,sex:'男',id:1},
                    {name:'金子',age:18,sex:'男',id:2},
                    {name:'铜牌',age:18,sex:'男',id:3}
                ]
            }
        })
    </script>
</body>
</html>

没有 Key

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!-- @click="list.splice(下标,删除的数量,添加的元素)" -->
        <button @click="list.splice(1,0,{name:'狗屎',age:11,sex:'男',id:4})">点击添加对象</button>
        <ul>
            <li v-for="item in list">
                <!-- 单选框 -->
                <input type="checkbox">
                <!-- 行内元素 -->
                <span>{{item.name}}</span>
            </li>
        </ul>
    </div>
    <script src="/vue.js"></script>
    <script>
        new Vue({
            el:'#app',
            data:{
                list:[
                    {name:'战神',age:18,sex:'男',id:1},
                    {name:'金子',age:18,sex:'男',id:2},
                    {name:'铜牌',age:18,sex:'男',id:3}
                ]
            }
        })
    </script>
</body>
</html>
]]>
https://www.askme-121.pw/v-for/feed/ 0
Vue插件(Plugin)、动态组件(component)和混入(mixin)介绍 https://www.askme-121.pw/vue-plugin-component-mixin/ https://www.askme-121.pw/vue-plugin-component-mixin/#respond Tue, 09 Jan 2024 13:56:12 +0000 https://www.askme-121.pw/?p=492 一、插件

插件通常用来为 Vue 添加全局功能。Vue.js 的插件应该暴露一个 install 方法。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象。

通过全局方法 Vue.use() 使用插件。

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<script src="https://cdn.jsdelivr.net/npm/vue@2.7.10"></script>
	<script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.29.4/moment.min.js"></script>
</head>
<body>
	<div id="app">
    <!-- 使用插件中的过滤器 -->
    {{new Date().getTime() | fmtDate}}
    <!-- 使用插件中定义的自定义指令 -->
    <input type="text" v-focus>
  </div>
	<script>
    // 1.定义一个插件
    let myPlugin = {
      // 插件暴露一个install方法 参数:Vue构造函数 option可选项
      install(Vue,options){
        // 1.1 定义全局资源 Vue.xxx
        //定义一个 自定义指令
        Vue.directive('focus',{
          inserted(el){
            el.focus()
          }
        });
        //定义一个过滤器
        Vue.filter('fmtDate', function(val){
          return moment(val).format('YYYY-MM-DD')
        });
        //1.2 定义一个实例方法,定义在Vue的原型上 Vue.prototype.xxx
        Vue.prototype.message = function(val){
          console.log(val);
        }
      }
    }
 
    //2.使用插件
    Vue.use(myPlugin)
    
	new Vue({
		el:"#app",
		created(){
            // 插件中在Vue原型上定义了一个方法message,因此这里可以使用message方法
            this.message('请求成功!')
        }
	})
    </script>
</body>
</html>

二、动态组件

动态组件使用component标签,标签内使用v-bind绑定is属性动态切换组件:

<component :is="current"></component>

点击相应按钮切换相应组件:

<body>
	<div id="app">
    <button @click="current=myA">切换A组件</button>
    <button @click="current=myB">切换B组件</button>
    <component :is="current"></component>
  </div>
	<script>
    // 定义组件myA
    let myA = {
      template:`
        <div>我是A组件</div>
      `
    }
    // 定义组件myB
    let myB = {
      template:`
        <div>我是B组件</div>
      `
    }
	new Vue({
		el:"#app",
		// 注册组件
        components:{
            'my-a': myA,
            'my-b': myB
        },
        data:{
            current: myA
        }
	})
	</script>
</body>

keep-alive

默认情况下,当组件在切换的时候都会重新创建组件,但是有些时候我们希望组件实例能够被在它们第一次被创建的时候缓存下来。为了解决这个问题,我们可以用一个 <keep-alive> 元素将其动态组件包裹起来。

<keep-alive>
   <component :is="current"></component> 
</keep-alive>

动态组件的生命周期

动态组件中新增了三个生命周期:

activated:进入激活组件

deactivated:离开停用

errorCaptured:子组件/后代组件发生错误捕获错误

触发顺序:

created–>errorCaptured–>mounted–>activated–>deactivated

<body>
	<div id="app">
    <button @click="current=myA">切换A组件</button>
    <button @click="current=myB">切换B组件</button>
    <keep-alive>
      <component :is="current"></component> 
    </keep-alive>
  </div>
	<script>
    // 定义一个A的子组件,用来说明errorCaptured声明周期
    let aChild={
			template:`
				<div>
					A组件的子组件
					{{subMsg}}
				</div>
			`
		};
    // 定义组件myA
    let myA = {
      template:`
        <div>我是A组件
          <a-child></a-child>
        </div>
      `,
      components:{
				'a-child': aChild
			},
      created(){
        alert('实例A初始化完成');
      },
      mounted(){
        alert('实例A挂载到页面完成')
      },
      // 激活组件 进入组件就会触发的生命周期
      activated() {
        alert('进入A组件了')
      },
      // 捕获子组件/后代组件发生错误的生命周期
	  errorCaptured(){
		alert('子组件发生错误了');
	  },
	  // 离开当前组件触发 停用组件
	  deactivated(){
		alert('离开A组件了');
	  },
    }
    // 定义组件myB
    let myB = {
      template:`
        <div>我是B组件</div>
      `
    }
	new Vue({
		el:"#app",
		// 注册组件
        components:{
            'my-a': myA,
            'my-b': myB
        },
        data:{
            current: myA
        }
	})
	</script>
</body>

三、混入

混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。

全局混入

Vue.mixin()

不建议使用全局注册混入对象,一旦使用全局混入,它将会影响以后创建的每一个vue实例。

局部混入

在组件实例中使用mixin配置项  mixins:[]

混入规则

当组件和混入对象有同名选项时,这些选项会以恰当的方式合并:

1、数据 data:

数据对象在混入时,会进行合并,发生冲突时,保留组件的数据

2、值为对象 methods、computed等:

在混入时,methods会合并成为一个对象,如果对象的键名发生冲突,则保留组件对象的键值对

3、生命周期钩子函数:

同名的钩子函数会被合并为一个数组,依次都会被调用,但是混入对象的钩子函数先被调用

<body>
	<div id="app">
    {{mixinMsg}}
	{{foo()}}
	{{bar()}}
  </div>
	<script>
    // 定义一个混入对象
    let myMixin = {
      data(){
        return{
          mixinMsg: '我是混入对象的数据',
          age: 18
        }
      },
      created(){
        console.log('我是混入的生命周期');
      },
      methods:{
        foo(){
          return this.age
        },
        bar(){
          console.log('我是混入方法');
        }
      },
    }
    // 全局混入——>混入到所有组件实例
    // Vue.mixin(myMixin);
	new Vue({
      // 局部混入
      mixins: [myMixin],
	  el:"#app",
      // 数据对象在混入时,会进行合并,发生冲突时,保留组件的数据
	  data:{
		msg: '我是vue实例的数据模型',
        age: 20
	  },
      // 生命周期会合并并依次调用执行 混入的生命周期优先执行
      created(){
		console.log('我是组件的生命周期');
		console.log(this.$data);
      },
      // 在混入时,methods会合并成为一个对象,如果对象的键名发生冲突,则保留组件对象的键值对
	  methods:{
        bar(){
          console.log('我是组件的方法');
        }
      }
	})
	</script>
</body>
]]>
https://www.askme-121.pw/vue-plugin-component-mixin/feed/ 0
Vue export and inport https://www.askme-121.pw/vue-export-inport/ https://www.askme-121.pw/vue-export-inport/#respond Mon, 08 Jan 2024 07:27:29 +0000 https://www.askme-121.pw/?p=491 一.export

一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量。

用法:

//输出变量用法1
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;

//输出变量用法2
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
export {firstName, lastName, year};

//输出函数用法1
export function multiply(x, y) {
  return x * y;
};
//输出函数用法2
function v1() { ... }
function v2() { ... }

export {
  v1 as streamV1,
  v2 as streamV2,
  v2 as streamLatestVersion
};

//输出类
export default class { ... }

错误用法

// 报错
export 1;
var m = 1;
export m;
//上面两种写法都会报错,因为没有提供对外的接口,两种错误其实都是因为直接输出值了
// 报错
function f() {}
export f;
//以上错误跟上面的相同,必须提供的是接口
//报错
function foo() {
  export default 'bar' // SyntaxError
}
foo()
//这种错误是因为export命令必须处于模块顶层才可以,也就是不能出现在代码块里面,这里涉及到import的编译时加载原理,这个稍后会讲

二、import

使用export命令定义了模块的对外接口以后,其他 JS 文件就可以通过import命令加载这个模块。

// main.js
import {firstName, lastName, year} from './profile';

function setName(element) {
  element.textContent = firstName + ' ' + lastName;
}

上面代码的import命令,用于加载profile.js文件,并从中输入变量。import命令接受一对大括号,里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块(profile.js)对外接口的名称相同。如果想为输入的变量重新取一个名字,import命令要使用as关键字,将输入的变量重命名。

import { lastName as surname } from './profile';

(1)提升效果

import命令具有提升效果,会提升到整个模块的头部,首先执行。

foo();
import { foo } from 'my_module';

上面的代码不会报错,因为import的执行早于foo的调用。这种行为的本质是,import命令是编译阶段执行的,在代码运行之前。

(2)不能使用表达式和变量

由于import是静态执行,所以不能使用表达式和变量,这些只有在运行时才能得到结果的语法结构。

// 报错
import { 'f' + 'oo' } from 'my_module';

// 报错
let module = 'my_module';
import { foo } from module;

// 报错
if (x === 1) {
  import { foo } from 'module1';
} else {
  import { foo } from 'module2';
}

上面三种写法都会报错,因为它们用到了表达式、变量和if结构。在静态分析阶段,这些语法都是没法得到值的。

(3)不重复加载

import { foo } from 'my_module';
import { bar } from 'my_module';
// 等同于
import { foo, bar } from 'my_module';

上面代码中,虽然foo和bar在两个语句中加载,但是它们对应的是同一个my_module实例。也就是说,import语句是 Singleton 模式。

(4)同export一样的import不能出现在代码块

由于import是编译时加载

三、export default

从前面的例子可以看出,使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。但是,用户肯定希望快速上手,未必愿意阅读文档,去了解模块有哪些属性和方法。

为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出。

// export-default.js
export default function () {
  console.log('foo');
}

上面代码是一个模块文件export-default.js,它的默认输出是一个函数。
其他模块加载该模块时,import命令可以为该匿名函数指定任意名字。

// import-default.js
import customName from './export-default';
customName(); // 'foo'

上面代码的import命令,可以用任意名称指向export-default.js输出的方法,这时就不需要知道原模块输出的函数名。需要注意的是,这时import命令后面,不使用大括号。

export default命令用在非匿名函数前,也是可以的。

// export-default.js
export default function foo() {
  console.log('foo');
}
// 或者写成
function foo() {
  console.log('foo');
}
export default foo;

上面代码中,foo函数的函数名foo,在模块外部是无效的。加载的时候,视同匿名函数加载。
下面比较一下默认输出和正常输出。

// 第一组
export default function crc32() { // 输出
  // ...
}

import crc32 from 'crc32'; // 输入

// 第二组
export function crc32() { // 输出
  // ...
};
import {crc32} from ‘crc32’; // 输入

上面代码的两组写法,第一组是使用export default时,对应的import语句不需要使用大括号;第二组是不使用export default时,对应的import语句需要使用大括号。

export default命令用于指定模块的默认输出。显然,一个模块只能有一个默认输出,因此export default命令只能使用一次。所以,import命令后面才不用加大括号,因为只可能对应一个方法。

本质上,export default就是输出一个叫做default的变量或方法,然后系统允许你为它取任意名字。所以,下面的写法是有效的。

// modules.js
function add(x, y) {
  return x * y;
}
export {add as default};
// 等同于
// export default add;

// app.js
import { default as xxx } from 'modules';
// 等同于
// import xxx from 'modules';
正是因为export default命令其实只是输出一个叫做default的变量,所以它后面不能跟变量声明语句。

// 正确
export var a = 1;

// 正确
var a = 1;
export default a;

// 错误
export default var a = 1;

上面代码中,export default a的含义是将变量a的值赋给变量default。所以,最后一种写法会报错。
同样地,因为export default本质是将该命令后面的值,赋给default变量以后再默认,所以直接将一个值写在export default之后。

// 正确
export default 42;

// 报错
export 42;

上面代码中,后一句报错是因为没有指定对外的接口,而前一句指定外对接口为default。

有了export default命令,输入模块时就非常直观了,以输入 lodash 模块为例。

import _ from ‘lodash’;

如果想在一条import语句中,同时输入默认方法和其他变量,可以写成下面这样。

import _, { each } from ‘lodash’;
对应上面代码的export语句如下。

export default function (obj) {
  // ···
}

export function each(obj, iterator, context) {
  // ···
}
export { each as forEach };

上面代码的最后一行的意思是,暴露出forEach接口,默认指向each接口,即forEach和each指向同一个方法。export default也可以用来输出类。

// MyClass.js
export default class { ... }

// main.js
import MyClass from 'MyClass';
let o = new MyClass();

总结:
ES6是未来,虽然现在很多浏览器都还不支持(现在可以通过babel将es6转成es5),但是有些很好的框架已经运用es6语法了,比如Vue,所以了解es6语法还是很有必要的。比如Vue组件化开发就采用export default去构建一个组件。

]]>
https://www.askme-121.pw/vue-export-inport/feed/ 0
vue中export的使用 https://www.askme-121.pw/vue-export/ https://www.askme-121.pw/vue-export/#respond Mon, 08 Jan 2024 07:11:54 +0000 https://www.askme-121.pw/?p=490 在vue开发的过程中,常用到暴露和引入,常见的暴露与引入方式是通过export暴露通过import引入,下面分别讲解一下:分别暴露、统一暴露、默认暴露的应用场景和使用方法。

一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量。

用法:

//输出变量用法1
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;

//输出变量用法2
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
export {firstName, lastName, year};

//输出函数用法1
export function multiply(x, y) {
  return x * y;
};
//输出函数用法2
function v1() { ... }
function v2() { ... }

export {
  v1 as streamV1,
  v2 as streamV2,
  v2 as streamLatestVersion
};

//输出类
export default class { ... }

一、分别暴露

应用场景:用于一个文件内暴露多个属性的场景,分别暴露,每一个属性都进行暴露

//暴露
export  const a =()=>{
    console.log(999);
} 
export  const b = 2
export  const c = 1 
//引入
import {a,b,c} from '@/api/api'
//使用:可直接通过a,b,c获取
created(){
    a()
    console.log(b,c);
  }

二、统一暴露

应用场景:用于一个文件内暴露多个属性的场景,统一进行暴露

//暴露
const a =()=>{
    console.log(999);
} 
const b = 2
const c = 1 
export{a,b,c}
//引入
import {a,b,c} from '@/api/api'
//使用
created(){
    a()
    console.log(b,c);
  }

三、默认暴露

应用场景:对于只需要暴露一个属性的时候使用

//暴露
const a =(data)=>{
    return data+1
} 
 
export default a
//引入
import a from '@/api/api'
 
//使用
created(){
    console.log(a(5));
  }
]]>
https://www.askme-121.pw/vue-export/feed/ 0