Project Dome Address

Gitee.com/Jaction/vit…

vite

cn.vitejs.dev/

First taste of Vue3.0 && Vue3.0 juejin.cn/post/684790…

The installation

Cn. Vitejs. Dev/guide / # scaf…

yarn create @vitejs/app
Copy the code

vite.config.js

import {
	defineConfig
} from 'vite'
import vue from '@vitejs/plugin-vue'
const path = require('path')

// https://vitejs.dev/config/
export default defineConfig({
	resolve: {
		alias: {
			// Keys must start and end with a slash
			"@": path.resolve(__dirname, "./src"),}},base: '/'.outDir: 'dist'.plugins: [vue()]
})

Copy the code

Environment configuration

The first:

yarn add cross-env -D


  "scripts": {
    "dev": "cross-env NODE_ENV=development vite"."build": "cross-env NODE_ENV=development vite build"."build": "cross-env NODE_ENV=production vite build"."serve": "vite preview"
  },
Copy the code

The second:


  "scripts": {
    "dev": "vite --mode development"."build:uat": "vite build --mode staging"."build:prd":"vite build --mode production"."serve": "vite preview"
  },
Copy the code
# .env.development
NODE_ENV=development
VITE_APP_TITLE=My App (staging)
Copy the code
# .env.staging
NODE_ENV=production
VITE_APP_TITLE=My App (staging)
Copy the code
# .env.production
NODE_ENV=production
VITE_APP_TITLE=My App (staging)
Copy the code

Write VITE_ are a must

use

let title = import.meta.env.VITE_APP_TITLE
Copy the code

The tutorial

The setup function

The Setup function is a new Vue component that is the Composition API entry point

<template>
</template>
<script>
import { setup } from 'vue'
export default {
   setup(props, context) {
       // Props is the function passed by the parent
       // What is context?
       We can't use this in setup()
       $emit, this.$psrent, this.$refs in vue2.0 do not apply to this.
       // Context is a set of these parameters
       //context.attrs
       //context.slots
       //context.parent = this.$psrent
       //context.root is equivalent to this in 2.0
       //context.emit corresponds to this.$emit in 2.0
       //context.refs corresponds to this.$refs in 2.0. }}</script>
<style>
</style>
Copy the code

Route Router/Route parameter Route

import { useRouter, useRoute } from 'vue-router'
import { setup } from 'vue'
export default {
	setup(props, context) {
    // Get parameters
    const route = useRoute()
    const { id } = route.query
    // Route the hook function
    const router = useRouter()
    router.beforeEach((to, from) = > {
      if (to.meta.index > from.meta.index) {
        state.transitionName = 'slide-left' // Swipe left
      } else if (to.meta.index < from.meta.index) {
        // From secondary to primary
        state.transitionName = 'slide-right'
      } else {
        state.transitionName = ' '   // Level has no transition effect}})const onAdd = () = > {
      router.push({ path: '/address-edit'.query: { type: 'add'.from: state.from }})
    }
    
    return {
      onAdd
    }
    
  }
}
Copy the code

Declare the variable ref reactive

Ref and Reactive are both ways of implementing responsive data

  • Reactive must pass an object
  • ref() Used when declaring a single underlying data typeBlog.csdn.net/weixin_4329…
import { setup, Reactive, torefs } from 'vue'
export default {
   setup(props, context) {
     		let count = ref(0) // ref(initial value) None The initial value is set to null
    		let name = ref('jeff')
        const obj = reacttive({
        data1: '123'.data2: {}})return{ count, name, ... torefs(obj)// change obj to a responsive ref, otherwise it will not be available in template}}}Copy the code

Dom

<div class="search-wrap" ref="searchWrap">
</div>
import { onMounted } from 'vue'
export default {
  setup() {
    const searchWrap = ref(null)
    onMounted(async() = > {let $screenHeight = document.documentElement.clientHeight
      console.log('searchWrap.value', searchWrap.value)
      searchWrap.value.style.height = $screenHeight - 100 + 'px'
    })
    
    return {
      searchWrap
    }
  }
}
Copy the code

nextTick

export default {
  setup() {
    nextTick(() = >{})}}Copy the code

Method function

There are no methods in VUe3.0

Methods should also be placed inside return

export default {
  setup() {
    / / method
    const goToDetail = (item) = > {
      router.push({ path: `/product/${item.goodsId}`})}/ / method 2
    const tips = () = > {
      Toast('Stay tuned');
    }
    
    return {
      goToDetail
      tips
    }
  }
}
Copy the code

components / props

Same as vue 2.0

import ziComp from './ziComp.vue'
import { setup } from 'vue'
export default {
  props: ['val'].// As with 2.0, props can also be used as objectsComponents: {ziComp},// Components is the same as 2.0
  setup(props, context) {
      const value = ref(props.val)
      
      const goBack = () = > {
        if(! props.val) {/ / processing}}return {
        value
        goBack
      }
  }
}
Copy the code

Emit events

// Parent component
<s-header :name="' Generate order '" @callback="deleteLocal"></s-header>

// Subcomponent
<div>{{name}}</div>

export detault {
  props: {
    name: {
      type: String.default: ' '
    },
    back: {
      type: String.detault: ' '}},emits: ['callback'].setup(props, ctx) {
    const goBack = () = > {
      if(! props.name) { router.go(-1)}else {
        router.push({ path: props.back })
      }
      ctx.emit('callback')}return {
      goBack
    }
    
 	}
}
Copy the code

WatchEffect listening props

<template>
 <div>{{obj.data1}}</div>
</template>
<script>
import { Reactive, watchEffect } from 'vue'
export default {
  props: ['val'].// As with 2.0, props can also be used as objects
  setup(props, context) {
     watchEffect(() = > {  // The first time and the props change will execute the code below
         console.log(props.val)
     })
  }
}
</script>
<style>
</style>
Copy the code

The watch () listener

import { Reactive } from 'vue'
export detault {
  setup(props, context) {
    	let count = ref(0)
      let state = reactive({
        count2: 1
      })
      
      // Listen for the ref type
      watch(count, (countNew, preCount)) => { //count new value, preCount old value (count)
        console.log(' ') // This is a function that executes after listening for data changes
      }
      
      // Listen to reactive
      watch(() = > state.count2, (count2New, preCount) = > {
        console.log(' ') // This is a function that executes after listening for data changes}, {lazy:false}) // // does not listen on the first creation
    
    	
  }
  return{ count countNew, count2New ... toRefs(state) } }Copy the code

Listening for multiple data

import { setup, Reactive } from 'vue'
export default {
  setup(props, context) {
   let count1 = ref(0)
    let name1 = ref(0)
   let state = reactive({
      count2: 0, name2:'yangy'
   )
    // Listen to multiple reactive types
   watch(
       [() = > state.count2, () = >State.name2] ([count, name], [preCount, preName]) => {//count new value, preCount old value
           console.log(' ') // This is a function that executes after listening for data changes}, {lazy:false
   })// Do not listen on the first creation
   
   // Listen for the ref typeWatch ([count2, name2] ([count, name], [preCount, preName]) => {//count new value, preCount old value
           console.log(' ') // This is a function that executes after listening for data changes}, {lazy:false}// do not listen on the first creation)
   
   return{count,... toRefs(state) } } }Copy the code

Computed () Computes attributes

Can be created read-only, and readable and writable

import { setup, Reactive } from 'vue'
export default {
  setup(props, context) {
   let count = ref(0)
   
  setup () {
    	const state = reactive({
        list: []})const count = ref(0)
      const addCount = computed(() = > count.value + 1) // Read only, count. Value changes to increment 1
      
      const addCount2 = computed({
          get:() = > count.value + 1.set: (value) = > count.value = value 
      })    
      Addcount2. value = 10 // Assignment method
      
      const total = computed(() = > {
        let sum = 0
        let _list = state.list.filter(item= > state.result.includes(item.cartItemId))
        _list.forEach(item= > {
          sum += item.goodsCount * item.sellingPrice
        })
        return sum
      })
      
     return {
       	 total
         count
         addCount
         addCount2
     }
  }
  }
}
Copy the code

script setup

<HelloWorld></HelloWorld>
<div @click='doClick'></div>

<script setup>
  import HelloWorld from './components/HelloWorld.vue'
	import msg from "./components/msg.vue"
	// props
	import { defineProps, defineEmit } from "vue";// props emit
	let props = defineProps({
    msg: String});let emit = defineEmit(['callback'])
  
  / / event
  function doClick() {}// Get the context
	import {useContext} from 'vue'

	// Lifecycle and declarations
	import { reactive, onMounted } from "vue";
	
	const msg = ' '
	const state = reactive({
    mag: "I love my country"
	});

	onMounted(() = > {
    initData()
  })
  const	initData = () = > {
    console.log(state.mag)
  }
  
  Vue provides getCurrentInstance Proxy in this, Script Setup similar to Vue2.0
  import { reactive, onMounted, getCurrentInstance } from "vue";
	const { proxy } = getCurrentInstance();
  const init = () = > {
      proxy.$alert('This is a piece of content.'.'Title name', {
            confirmButtonText: 'sure'.callback: action= > {
              proxy.$message({
                type: 'info'.message: `action: ${ action }`}); }}); };// Get the route and route parameters
	import { reactive, onMounted, getCurrentInstance } from "vue";
	const { proxy } = getCurrentInstance();

	const init = () = > {
    let { id } = proxy.$route.query
  }
  
  // Or use useRoute useRouter
  import { useRoute, useRouter } from 'vue-router'
	const route = useRoute()
  let { id } = route.query
	
  
</script>
Copy the code

Vue3 life cycle

import { onMounted, onUpdated, onUnmounted } from 'vue'
Copy the code

In addition to beforeCreate and Created, there are nine old lifecycle hooks that we can access in our setup method

  • onBeforeMount
  • onMounted
  • onBeforeUpdate
  • onUpdated
  • onBeforeUnmount
  • onUnmounted
  • onActivated
  • onDeactivated
  • onErrorCaptured

We import them and access them in our code

import { onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, onActivated, onDeactivated, onErrorCaptured } from 'vue'

export default {
  setup() {
    onBeforeMount(() = > {
      // ... 
    })
    onMounted(() = > { / / asynchronous
      // ... 
    })
    onBeforeUpdate(() = > {
      // ... 
    })
    onUpdated(() = > {
      // ... 
    })
    onBeforeUnmount(() = > {
      // ... 
    })
    onUnmounted(() = > {
      // ... 
    })
    onActivated(() = > {
      // ... 
    })
    onDeactivated(() = > {
      // ... 
    })
    onErrorCaptured(() = > {
      // ... })}Copy the code
  • beforeCreate -> use setup()
  • created -> use setup()
  • beforeMount -> onBeforeMount
  • mounted -> onMounted
  • beforeUpdate -> onBeforeUpdate
  • updated -> onUpdated
  • beforeDestroy -> onBeforeUnmount
  • destroyed -> onUnmounted
  • errorCaptured -> onErrorCaptured

Store Status Management

Yran add [email protected]

index.js

state.js

mutation.js

action.js

// index.js
import { createStore } from 'vuex'
import state from './state'
import actions from './actions'
import mutations from './mutations'

export default createStore({
  state,
  mutations,
  actions,
  modules: {}})// state.js
export default {
  cartCount: 0
}

// mutation.js
export default {
  addCart (state, payload) {
    state.cartCount = payload.count
  }
}

// action.js
import { getCart } from '.. /service/cart'

export default {
  async updateCart(ctx) {
    const { data } = await getCart()
    ctx.commit('addCart', {
      count: data.length || 0}}})Copy the code
// main.js
import App from './App.vue'
import store from './store'
const app = createApp(App) // Create an instance
app.use(store)

app.mount('#app')
Copy the code

In the page

import { useStore } from 'vuex'
export detault {
  setup() {
    const store = useStore()
    
    onMounted(() = > {
      store.dispatch('updateCart')})const handleAddCart = async () => {
      store.dispatch('updateCart')})return {
      handleAddCart
    }
    
  }
}
Copy the code

vue-jsx

yarn add @vitejs/plugin-vue-jsx

// vite.config.js
import {
	defineConfig
} from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJxs from '@vitejs/plugin-vue-jsx'

// https://vitejs.dev/config/
export default defineConfig({
	plugins: [vue(), vueJxs()]
})
Copy the code
/ / setup
<script lang='jsx'>
import { ref } from 'vue'
export default {
	setup() {
    let counter = ref(0)
    let onclick = () = > {
      	counter.value ++
    }
    return () = > {
      <>
        	<div>comp</div>
      		<p onClick={onclick}>{counter.value}</p>
      </>
    }
  }
}
</script>
Copy the code

The mock data

yarn add vite-plugin-mock -D

yarn add mockjs -S

// vite.config.js
// vite.config.js
import {
	defineConfig
} from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJxs from '@vitejs/plugin-vue-jsx'
import { viteMockServe } from 'vite-plugin-mock';

// https://vitejs.dev/config/
export default defineConfig({
	plugins: [vue(), vueJxs(), viteMockServe({ supportTs: false})]})Copy the code

Create a mock in the root directory

For example, create a new JS file, such as user.js

export default[{url: '/api/createUser'.method: 'post'.response: ({ body }) = > {
      console.log('body>>>>>>>>', body);
      return {
        code: 0.message: 'ok'.data: null}; }},];Copy the code

role.js

export default[{url: '/api/getRoleById'.method: 'get'.response: ({ query }) = > {
      console.log('id>>>>>>>>', query.id);
      return {
        code: 0.message: 'ok'.data: {
          roleName: 'admin'.roleValue: 'admin',}}; }},];Copy the code

vue-router

yarn add vue-router@next -S

router/index.js

import { createRouter, createWebHashHistory } from "vue-router";

const router = createRouter({
  history: createWebHashHistory(),
  routes: [{path: "/".component: () = > import(".. /views/index.vue"),},]});export default router
Copy the code
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router/index";

const app = createApp(App)
app.use(router)
app.mount("#app");
Copy the code

vuex

yarn add vuex@nest -S

// store/index.js
import { createStore } from 'vuex'
export detault createStore({
  state: {
    counter: 0
  },
  mutations: {
    add(state)=> {
    	state.counter ++
  	}
  }
})
Copy the code
import { createApp } from "vue";
import App from "./App.vue";
import store from './store'

const app = createApp(App)
app.use(store)
app.mount("#app");
Copy the code
<p @click="$store.commit('add')">
  {{$store.state.counter}}
</p>
Copy the code

Style of management

Install the sass

yarn add sass -D

  @import './element-ui.scss'
  @import './index.scss'
  @import './mixin.scss'
  @import './sidebar.scss'
Copy the code

The styles directory holds various styles

element-ui.scss

index.scss

mixin.scss

sidebar.scss

Pack to build

yarn build
Copy the code

Cors errors are reported when the build is packaged and opened directly in the browser

Directly on the server will not report errors, normal operation

Blog.csdn.net/sayyy/artic…

npm install http-server -g

http-server [path] [options]
Copy the code

Go directly to the packaged dist file and execute the http-server command (default 8080)

Directly open http://127.0.0.1:8080/index.html#/